diff --git a/README.md b/README.md
index fca3b5e..8be2251 100644
--- a/README.md
+++ b/README.md
@@ -8,4 +8,4 @@ Currently implemented endpoints:
## Options
- [fly.io](./fly/README.md) - deploy fly.io app
-- [aws lambda](./lambda/README.md) - lambda functions (wip)
\ No newline at end of file
+- [self hosted](./fly/DEV.md) - deploy anywhere you want
\ No newline at end of file
diff --git a/lambda/README.md b/lambda/README.md
deleted file mode 100644
index 4972b99..0000000
--- a/lambda/README.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# Nodeless payments
-This is a proof of concept implementation for deploying the Breez SDK (Nodeless implementation) as a lambda function to AWS. It provides a REST api with close to zero cost of hosting.
-
-
-Currently implemented endpoints:
-- /send_payment (bolt11)
-- /receive_payment (bolt11)
-- /list_payments
-
-
-### API Key Security
-- X-API-KEY header serves as authorization method for accessing the API. Anyone that knows the API url and API_SECRET can access your funds, so make sure to protect this secret and to generate a unique and long string. You can use generators like [this](https://1password.com/password-generator) or [this](https://www.uuidgenerator.net/).
-- Encrypted secrets are stored in [AWS Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) and are accessed each time any endpoint is called (in the background docker container is started for each REST API call).
-
-## Requirements for deployment
-- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
-- [Access to AWS account](https://signin.aws.amazon.com/signup?request_type=register)
-- [Breez SDK - Nodeless implementation API key](https://breez.technology/request-api-key/#contact-us-form-sdk)
-- 12 words BIP 39 seed (TBA: use Misty Breez to generate it)
-
-## Deployment
-Deployment to AWS with [cloudformation](./cloudformation.yaml).
-
-### Install CLI
-Follow [AWS guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) to install it on your computer.
-
-### Create credentials
-There are several ways of creating credentials to deploy in AWS. Ideally, you want to generate temporary credentials that are gonna be revoked after this deployment. You can create create credentials that have the same permissions as your root account. This will enable you to run all the CLI commands. Follow these steps to create an access key:
-
-* Select *Security Credentials* from your account's menu:
-
-
-
-* Follow the steps to create an access key:
-
-
-
-
-### Configure CLI
-Now that you have AWS CLI installed and credentials ready, it's time for the last step of the requirements: configuring the AWS CLI to work with your account credentials.
-
-You will also have to choose a default region where you want to deploy your API. You can see the list of all regions [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). You should pick the region that is closest to your business. For quick reference:
-* **US**: *us-east-1*, *us-west-1*
-* **Europe**: *eu-central-1*, *eu-west-1*
-* **LATAM**: *sa-east-1*
-* **Asia**: *ap-southeast-1*
-
-Once you have an API key, an API secret and region string, you're ready to configure the CLI.
-
-Open a command line interface in your OS and type `aws configure` and press enter. Now, copy/paste the API key, press enter, then copy/paste the API secret and press enter. Do the same for the region string. You can leave the default output format blank.
-
-Here's an example:
-
-```
-# aws configure
-AWS Access Key ID [None]: AKIA44HIGHQYZHRTZ7WP
-AWS Secret Access Key [None]: qKVd5nMA7y8DbEuvF6kFbKTcYrAow8rH9KDxWGkT
-Default region name [None]: us-east-1
-Default output format [None]:
-```
-
-### Create SSM parameters for Breez credentials
-From the command line, run the following commands:
-```
-aws ssm put-parameter --name "/breez-nodeless/api_key" --value "" --type SecureString
-```
-
-```
-aws ssm put-parameter --name "/breez-nodeless/seed_phrase" --value "" --type SecureString
-```
-
-```
-aws ssm put-parameter --name "/breez-nodeless/api_secret" --value "" --type SecureString
-```
-### Deploy Cloudformation stack
-* Download this configuration file: [cloudformation.yaml](https://raw.githubusercontent.com/breez/nodeless-payments/refs/heads/main/cloudformation.yaml).
-* Deploy the stack:
-```
-aws cloudformation create-stack --stack-name breez-integration --template-body file://cloudformation.yaml --capabilities CAPABILITY_IAM
-```
-* Monitor the stack creation (wait until it changes to *CREATE_COMPLETE*):
-```
-aws cloudformation describe-stacks --stack-name breez-integration --query Stacks[0].StackStatus
-```
-* Retrieve the API endpoints:
-```
-aws cloudformation describe-stacks --stack-name breez-integration --query 'Stacks[0].Outputs'
-```
-Output should look like this:
-```
-root@2edec8635e65:/# aws cloudformation describe-stacks --stack-name breez-integration --query 'Stacks[0].Outputs'
-[
- {
- "OutputKey": "ApiGatewayBaseURL",
- "OutputValue": "https://yxzjorems5.execute-api.us-east-1.amazonaws.com/prod",
- "Description": "Base URL for API Gateway"
- },
- {
- "OutputKey": "SendEndpoint",
- "OutputValue": "https://yxzjorems5.execute-api.us-east-1.amazonaws.com/prod/send_payment",
- "Description": "Send endpoint URL"
- },
- {
- "OutputKey": "PaymentsEndpoint",
- "OutputValue": "https://yxzjorems5.execute-api.us-east-1.amazonaws.com/prod/list_payments",
- "Description": "Payments endpoint URL"
- },
- {
- "OutputKey": "ReceiveEndpoint",
- "OutputValue": "https://yxzjorems5.execute-api.us-east-1.amazonaws.com/prod/receive_payment",
- "Description": "Receive endpoint URL"
- }
-]
-```
-* If the deployment was successful, you should deactivate your API key now.
-### Example usage
-#### Python
-You can use `example-client.py`file from this to test the functionality. Take Base URL from the output of last command (see *ApiGatewayBaseURL* example above) and API_SECRET and edit the `example-client.py` with correct values
-
-```
-API_URL = "YOUR-URL-HERE"
-API_KEY = "YOUR-SECRET-HERE"
-```
-For example-client to work, you need to have python installed together with requests library:
-```
-pip install requests
-```
-Then run:
-```
-python example-client.py
-```
-#### curl
-If you don't have python installed, you can also just run a curl command.
-
-For example, for the *list_payments* endpoint, run:
-```
-curl -X POST "/list_payments" -H "Content-Type: application/json" -H "x-api-key: " -d '{}'
-```
-
-### Cleanup
-To remove the stack you deployed you need to run the command delete-stack. This command starts the process to delete the stack, but it takes a while.
-```
-aws cloudformation delete-stack --stack-name breez-integration
-```
-You can use the same status command to see if its been successfully deleted:
-```
-aws cloudformation describe-stacks --stack-name breez-integration --query Stacks[0].StackStatus
-```
-
-You should also cleanup the parameters:
-```
-aws ssm delete-parameter --name "/breez-nodeless/api_key"
-aws ssm delete-parameter --name "/breez-nodeless/seed_phrase"
-aws ssm delete-parameter --name "/breez-nodeless/api_secret"
-
-```
\ No newline at end of file
diff --git a/lambda/cloudformation.yaml b/lambda/cloudformation.yaml
deleted file mode 100644
index 2ed03d0..0000000
--- a/lambda/cloudformation.yaml
+++ /dev/null
@@ -1,168 +0,0 @@
-AWSTemplateFormatVersion: "2010-09-09"
-Description: "Deploys an API Gateway, Lambda function, and IAM roles for Breez integration."
-
-Resources:
- # IAM Role for Lambda Function
- LambdaExecutionRole:
- Type: AWS::IAM::Role
- Properties:
- AssumeRolePolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Effect: Allow
- Principal:
- Service:
- - lambda.amazonaws.com
- Action:
- - sts:AssumeRole
- Policies:
- - PolicyName: LambdaAccessPolicy
- PolicyDocument:
- Version: "2012-10-17"
- Statement:
- - Effect: Allow
- Action:
- - logs:CreateLogGroup
- - logs:CreateLogStream
- - logs:PutLogEvents
- Resource: "arn:aws:logs:*:*:*"
- - Effect: Allow
- Action:
- - s3:GetObject
- Resource:
- - "arn:aws:s3:::lambda-nodeless-payment/*"
- - Effect: Allow
- Action:
- - ssm:GetParameter
- Resource:
- - !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/breez-nodeless/api_key"
- - !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/breez-nodeless/seed_phrase"
- - !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/breez-nodeless/api_secret"
-
- # API Gateway
- ApiGateway:
- Type: AWS::ApiGateway::RestApi
- Properties:
- Name: BreezAPIGateway
- Description: "API Gateway for Breez Lightning Network integration"
-
- # API Resources for each endpoint
- ApiListPaymentsResource:
- Type: AWS::ApiGateway::Resource
- Properties:
- RestApiId: !Ref ApiGateway
- ParentId: !GetAtt ApiGateway.RootResourceId
- PathPart: "list_payments"
-
- ApiReceiveResource:
- Type: AWS::ApiGateway::Resource
- Properties:
- RestApiId: !Ref ApiGateway
- ParentId: !GetAtt ApiGateway.RootResourceId
- PathPart: "receive_payment"
-
- ApiSendResource:
- Type: AWS::ApiGateway::Resource
- Properties:
- RestApiId: !Ref ApiGateway
- ParentId: !GetAtt ApiGateway.RootResourceId
- PathPart: "send_payment"
-
- # Lambda Function
- BreezLambdaFunction:
- Type: AWS::Lambda::Function
- Properties:
- FunctionName: BreezLambda
- Runtime: python3.12
- Handler: lambda_function.lambda_handler
- Role: !GetAtt LambdaExecutionRole.Arn
- Code:
- S3Bucket: "breez-nodeless-payment"
- S3Key: "lambda.zip"
- Timeout: 30
- Environment:
- Variables:
- PARAMETER_PREFIX: "/breez/"
-
- # Allow API Gateway to invoke Lambda
- LambdaInvokePermission:
- Type: AWS::Lambda::Permission
- DependsOn: BreezLambdaFunction
- Properties:
- Action: "lambda:InvokeFunction"
- FunctionName: !Ref BreezLambdaFunction
- Principal: "apigateway.amazonaws.com"
- SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/*/*"
-
-
- # API Methods
- GetPaymentsMethod:
- Type: AWS::ApiGateway::Method
- DependsOn: BreezLambdaFunction
- Properties:
- RestApiId: !Ref ApiGateway
- ResourceId: !Ref ApiListPaymentsResource
- HttpMethod: GET
- AuthorizationType: NONE
- Integration:
- Type: AWS_PROXY
- IntegrationHttpMethod: POST
- Uri: !Sub
- - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaArn}/invocations"
- - LambdaArn: !GetAtt BreezLambdaFunction.Arn
-
- PostReceiveMethod:
- Type: AWS::ApiGateway::Method
- DependsOn: BreezLambdaFunction
- Properties:
- RestApiId: !Ref ApiGateway
- ResourceId: !Ref ApiReceiveResource
- HttpMethod: POST
- AuthorizationType: NONE
- Integration:
- Type: AWS_PROXY
- IntegrationHttpMethod: POST
- Uri: !Sub
- - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaArn}/invocations"
- - LambdaArn: !GetAtt BreezLambdaFunction.Arn
-
- PostSendMethod:
- Type: AWS::ApiGateway::Method
- DependsOn: BreezLambdaFunction
- Properties:
- RestApiId: !Ref ApiGateway
- ResourceId: !Ref ApiSendResource
- HttpMethod: POST
- AuthorizationType: NONE
- Integration:
- Type: AWS_PROXY
- IntegrationHttpMethod: POST
- Uri: !Sub
- - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaArn}/invocations"
- - LambdaArn: !GetAtt BreezLambdaFunction.Arn
-
- # API Deployment
- ApiDeployment:
- Type: AWS::ApiGateway::Deployment
- DependsOn:
- - GetPaymentsMethod
- - PostReceiveMethod
- - PostSendMethod
- - LambdaInvokePermission
- Properties:
- RestApiId: !Ref ApiGateway
- StageName: "prod"
-
-Outputs:
- ApiGatewayBaseURL:
- Description: "Base URL for API Gateway"
- Value: !Sub "https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod"
- PaymentsEndpoint:
- Description: "Payments endpoint URL"
- Value: !Sub "https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod/list_payments"
- ReceiveEndpoint:
- Description: "Receive endpoint URL"
- Value: !Sub "https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod/receive_payment"
- SendEndpoint:
- Description: "Send endpoint URL"
- Value: !Sub "https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod/send_payment"
\ No newline at end of file
diff --git a/lambda/dev/DEV.md b/lambda/dev/DEV.md
deleted file mode 100644
index 9da17c4..0000000
--- a/lambda/dev/DEV.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## Deploy lambda function
-If you want to deploy your own changes directly to lambda you can use [deploy.sh](./deploy.sh) to package and deploy it for you. Tested on linux.
-
-Requirements:
-- aws cli installed and configured (instructions in [README.md](./README.md))
-- python3.12 and pip installed
diff --git a/lambda/dev/INFRASTRUCTURE.md b/lambda/dev/INFRASTRUCTURE.md
deleted file mode 100644
index 10715c4..0000000
--- a/lambda/dev/INFRASTRUCTURE.md
+++ /dev/null
@@ -1,28 +0,0 @@
-### Code deployment
-New code is automatically packaged and deployed to Breez's S3 bucket for public consumption.
-
-
-### Create S3 bucket
-```
-aws s3api create-bucket --bucket breez-nodeless-payment --acl public-read
-aws s3api delete-public-access-block --bucket breez-nodeless-payment
-aws s3api put-bucket-policy --bucket breez-nodeless-payment --policy '{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "PublicReadGetObject",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::breez-nodeless-payment/*"
- }
- ]
-}'
-```
-
-### Create user for github actions upload
-```
-aws iam create-user --user-name github-actions-user
-aws iam put-user-policy --user-name github-actions-user --policy-name S3UploadPolicy --policy-document file://github-actions-policy.json
-aws iam create-access-key --user-name github-actions-user
-```
\ No newline at end of file
diff --git a/lambda/dev/deploy.sh b/lambda/dev/deploy.sh
deleted file mode 100644
index cfb5d3f..0000000
--- a/lambda/dev/deploy.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# Variables
-FUNCTION_NAME="BreezLambda" # Match the FunctionName in CloudFormation
-ZIP_FILE="lambda.zip"
-
-# Install dependencies
-echo "Installing dependencies..."
-mkdir -p package
-pip install -r requirements.txt -t package/
-
-# Package the function
-echo "Packaging the function..."
-cp lambda_function.py package/
-cd package
-zip -r ../$ZIP_FILE .
-cd ..
-
-# Update Lambda function code directly
-echo "Updating Lambda function code..."
-aws lambda update-function-code \
- --function-name $FUNCTION_NAME \
- --zip-file fileb://$ZIP_FILE
-
-# Clean up
-rm -rf package
-rm $ZIP_FILE
-
-echo "Deployment complete!"
-
diff --git a/lambda/dev/github-actions-policy.json b/lambda/dev/github-actions-policy.json
deleted file mode 100644
index 8a26907..0000000
--- a/lambda/dev/github-actions-policy.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "AllowS3Upload",
- "Effect": "Allow",
- "Action": [
- "s3:PutObject",
- "s3:PutObjectAcl"
- ],
- "Resource": "arn:aws:s3:::breez-nodeless-payment/*"
- },
- {
- "Sid": "AllowListBucket",
- "Effect": "Allow",
- "Action": "s3:ListBucket",
- "Resource": "arn:aws:s3:::breez-nodeless-payment"
- }
- ]
-}
diff --git a/lambda/docs/aws_credentials.md b/lambda/docs/aws_credentials.md
deleted file mode 100644
index d04f390..0000000
--- a/lambda/docs/aws_credentials.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/lambda/docs/screenshot0.jpg b/lambda/docs/screenshot0.jpg
deleted file mode 100644
index f0ac430..0000000
Binary files a/lambda/docs/screenshot0.jpg and /dev/null differ
diff --git a/lambda/docs/screenshot1.jpg b/lambda/docs/screenshot1.jpg
deleted file mode 100644
index 10b823f..0000000
Binary files a/lambda/docs/screenshot1.jpg and /dev/null differ
diff --git a/lambda/docs/screenshot2.jpg b/lambda/docs/screenshot2.jpg
deleted file mode 100644
index 59042c3..0000000
Binary files a/lambda/docs/screenshot2.jpg and /dev/null differ
diff --git a/lambda/docs/screenshot3.jpg b/lambda/docs/screenshot3.jpg
deleted file mode 100644
index a791bc7..0000000
Binary files a/lambda/docs/screenshot3.jpg and /dev/null differ
diff --git a/lambda/docs/screenshot4.jpg b/lambda/docs/screenshot4.jpg
deleted file mode 100644
index 1bcf71a..0000000
Binary files a/lambda/docs/screenshot4.jpg and /dev/null differ
diff --git a/lambda/example-client.py b/lambda/example-client.py
deleted file mode 100644
index 8231571..0000000
--- a/lambda/example-client.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import requests
-import json
-
-API_URL = "https://yxzjorems5.execute-api.us-east-1.amazonaws.com/prod"
-
-API_KEY = "1234567890"
-
-class BreezClient:
- def __init__(self):
- # Load API key from file
- self.api_url = API_URL
- self.headers = {
- 'Content-Type': 'application/json',
- 'x-api-key': API_KEY
- }
-
- def list_payments(self, from_timestamp=None, to_timestamp=None, offset=None, limit=None):
- """List all payments with optional filters."""
- params = {
- "from_timestamp": from_timestamp,
- "to_timestamp": to_timestamp,
- "offset": offset,
- "limit": limit
- }
- response = requests.get(f"{self.api_url}/list_payments", params=params, headers=self.headers)
- print(response.json())
- print(self.headers)
- return self._handle_response(response)
-
- def receive_payment(self, amount, method="LIGHTNING"):
- """Generate a Lightning/Bitcoin/Liquid invoice to receive payment."""
- payload = {
- "amount": amount,
- "method": method
- }
- response = requests.post(f"{self.api_url}/receive_payment", json=payload, headers=self.headers)
- return self._handle_response(response)
-
- def send_payment(self, destination, amount=None, drain=False):
- """Send a payment via Lightning or Liquid."""
- payload = {
- "destination": destination,
- "amount": amount,
- "drain": drain
- }
- response = requests.post(f"{self.api_url}/send_payment", json=payload, headers=self.headers)
- return self._handle_response(response)
-
- def _handle_response(self, response):
- """Helper method to handle API responses."""
- if response.status_code == 200:
- return response.json()
- else:
- return {"error": f"Request failed with status {response.status_code}", "details": response.text}
-
-# Initialize client
-breez = BreezClient()
-
-# Example Usage
-if __name__ == "__main__":
- print("š Listing Payments...")
- print(breez.list_payments())
-
- #print("\nš° Receiving Payment...")
- #print(breez.receive_payment(amount=1000, method="LIGHTNING"))
-
- #print("\nš Sending Payment...")
- #print(breez.send_payment(destination="lnbc...", amount=1000))
diff --git a/lambda/lambda_function.py b/lambda/lambda_function.py
deleted file mode 100644
index 5c65ab5..0000000
--- a/lambda/lambda_function.py
+++ /dev/null
@@ -1,288 +0,0 @@
-import json
-import boto3
-from typing import Optional
-from breez_sdk_liquid import (
- LiquidNetwork,
- PayAmount,
- ConnectRequest,
- PrepareSendRequest,
- SendPaymentRequest,
- PrepareReceiveRequest,
- ReceivePaymentRequest,
- EventListener,
- SdkEvent,
- connect,
- default_config,
- PaymentMethod,
- ListPaymentsRequest
-)
-import time
-import logging
-from aws_lambda_powertools import Logger, Tracer
-from aws_lambda_powertools.event_handler import APIGatewayRestResolver
-from aws_lambda_powertools.utilities.typing import LambdaContext
-
-logger = Logger()
-tracer = Tracer()
-app = APIGatewayRestResolver()
-
-class SdkListener(EventListener):
- def __init__(self):
- self.synced = False
- self.paid = []
-
- def on_event(self, event):
- if isinstance(event, SdkEvent.SYNCED):
- self.synced = True
- if isinstance(event, SdkEvent.PAYMENT_SUCCEEDED):
- if event.details.destination:
- self.paid.append(event.details.destination)
-
- def is_paid(self, destination: str):
- return destination in self.paid
-
-class PaymentHandler:
- def __init__(self):
- self.breez_api_key = self._get_ssm_parameter('/breez-nodeless/api_key')
- self.seed_phrase = self._get_ssm_parameter('/breez-nodeless/seed_phrase')
-
- if not self.breez_api_key:
- raise Exception("Missing Breez API key in Parameter Store")
- if not self.seed_phrase:
- raise Exception("Missing seed phrase in Parameter Store")
-
- logger.info("Retrieved encrypted parameters successfully")
-
- config = default_config(LiquidNetwork.MAINNET, self.breez_api_key)
- config.working_dir = '/tmp'
- connect_request = ConnectRequest(config=config, mnemonic=self.seed_phrase)
- self.instance = connect(connect_request)
- self.listener = SdkListener()
- self.instance.add_event_listener(self.listener)
-
- def _get_ssm_parameter(self, param_name: str) -> str:
- """Get an encrypted parameter from AWS Systems Manager Parameter Store"""
- logger.info(f"Retrieving encrypted parameter: {param_name}")
- ssm = boto3.client('ssm')
- try:
- response = ssm.get_parameter(
- Name=param_name,
- WithDecryption=True
- )
- return response['Parameter']['Value']
- except ssm.exceptions.ParameterNotFound:
- logger.error(f"Parameter {param_name} not found in Parameter Store")
- raise Exception(f"Parameter {param_name} not found in Parameter Store")
- except Exception as e:
- logger.error(f"Failed to get parameter {param_name}: {str(e)}", exc_info=True)
- raise Exception(f"Failed to get parameter {param_name}: {str(e)}")
-
- def wait_for_sync(self, timeout_seconds: int = 30):
- """Wait for the SDK to sync before proceeding."""
- start_time = time.time()
- while time.time() - start_time < timeout_seconds:
- if self.listener.synced:
- return True
- time.sleep(1)
- raise Exception("Sync timeout: SDK did not sync within the allocated time.")
-
- def wait_for_payment(self, destination: str, timeout_seconds: int = 60) -> bool:
- """Wait for payment to complete or timeout"""
- start_time = time.time()
- while time.time() - start_time < timeout_seconds:
- if self.listener.is_paid(destination):
- return True
- time.sleep(1)
- return False
-
- def list_payments(self, params: dict = None) -> dict:
- try:
- self.wait_for_sync() # Ensure sync before executing
- from_ts = int(params.get('from_timestamp')) if params and params.get('from_timestamp') is not None else None
- to_ts = int(params.get('to_timestamp')) if params and params.get('to_timestamp') is not None else None
- offset = int(params.get('offset')) if params and params.get('offset') is not None else None
- limit = int(params.get('limit')) if params and params.get('limit') is not None else None
-
- req = ListPaymentsRequest(
- from_timestamp=from_ts,
- to_timestamp=to_ts,
- offset=offset,
- limit=limit
- )
- payments = self.instance.list_payments(req)
- payment_list = []
- for payment in payments:
- payment_dict = {
- 'timestamp': payment.timestamp,
- 'amount_sat': payment.amount_sat,
- 'fees_sat': payment.fees_sat,
- 'payment_type': str(payment.payment_type),
- 'status': str(payment.status),
- 'details': str(payment.details),
- 'destination': payment.destination,
- 'tx_id': payment.tx_id
- }
- payment_list.append(payment_dict)
-
- # apply offset, limit and timestamp filters
- print(f"payment_list: {payment_list}")
- filtered_payments = []
- for payment in payment_list:
- if from_ts and payment['timestamp'] < from_ts:
- continue
- if to_ts and payment['timestamp'] > to_ts:
- continue
- if offset and offset > 0:
- offset -= 1
- continue
- filtered_payments.append(payment)
-
- # apply limit
- if limit and limit < len(filtered_payments):
- filtered_payments = filtered_payments[:limit]
-
- # apply offset
- if offset and offset > 0:
- filtered_payments = payment_list[offset:]
-
- if not (offset or limit or from_ts or to_ts):
- return {
- 'statusCode': 200,
- 'body': json.dumps({
- 'payments': payment_list
- })
- }
- # apply limit
- return {
- 'statusCode': 200,
- 'body': json.dumps({
- 'payments': filtered_payments
- })
- }
- except Exception as e:
- return {
- 'statusCode': 500,
- 'body': json.dumps({'error': str(e)})
- }
-
- def receive_payment(self, amount: int, payment_method: str = 'LIGHTNING') -> dict:
- try:
- self.wait_for_sync() # Ensure sync before executing
- prepare_req = PrepareReceiveRequest(getattr(PaymentMethod, payment_method), amount)
- prepare_res = self.instance.prepare_receive_payment(prepare_req)
- req = ReceivePaymentRequest(prepare_res)
- res = self.instance.receive_payment(req)
-
- # Return the invoice details immediately
- return {
- 'statusCode': 200,
- 'body': json.dumps({
- 'destination': res.destination,
- 'fees_sat': prepare_res.fees_sat
- })
- }
- except Exception as e:
- return {'statusCode': 500, 'body': json.dumps({'error': str(e)})}
-
- def send_payment(self, destination: str, amount: Optional[int] = None, drain: bool = False) -> dict:
- try:
- self.wait_for_sync() # Ensure sync before executing
- pay_amount = PayAmount.DRAIN if drain else PayAmount.RECEIVER(amount) if amount else None
- prepare_req = PrepareSendRequest(destination, pay_amount)
- prepare_res = self.instance.prepare_send_payment(prepare_req)
- req = SendPaymentRequest(prepare_res)
- res = self.instance.send_payment(req)
- return {'statusCode': 200, 'body': json.dumps({'payment_status': 'success', 'destination': res.payment.destination, 'fees_sat': prepare_res.fees_sat})}
- except Exception as e:
- return {'statusCode': 500, 'body': json.dumps({'error': str(e)})}
-
-def validate_api_key(event):
- """Validate the API key from the request headers"""
- try:
- logger.info("Headers received: %s", json.dumps(event.get('headers', {})))
- api_key = event.get('headers', {}).get('x-api-key')
- if not api_key:
- logger.warning("No API key provided in request headers")
- return False
-
- logger.info("API key found in headers")
-
- # Get the stored API key from SSM
- ssm = boto3.client('ssm')
- try:
- stored_key = ssm.get_parameter(
- Name='/breez-nodeless/api_secret',
- WithDecryption=True
- )['Parameter']['Value']
- logger.info("Successfully retrieved stored API key from SSM")
-
- # Compare keys (safely log length but not the actual keys)
- keys_match = api_key == stored_key
- logger.info("API key validation result: %s (lengths: request=%d, stored=%d)",
- keys_match, len(api_key), len(stored_key))
- return keys_match
-
- except ssm.exceptions.ParameterNotFound:
- logger.error("SSM parameter /breez-nodeless/api_secret not found")
- return False
- except Exception as e:
- logger.error(f"Error validating API key: {str(e)}", exc_info=True)
- return False
-
-@app.get("/list_payments")
-@tracer.capture_method
-def list_payments():
- try:
- if not validate_api_key(app.current_event):
- return {"statusCode": 401, "body": json.dumps({"error": "Unauthorized"})}
-
- logger.info("Processing list_payments request")
- handler = PaymentHandler()
- return handler.list_payments(app.current_event.query_string_parameters or {})
- except Exception as e:
- logger.error(f"Error listing payments: {str(e)}", exc_info=True)
- return {"statusCode": 500, "body": json.dumps({"error": str(e)})}
-
-@app.post("/receive_payment")
-@tracer.capture_method
-def receive_payment():
- try:
- if not validate_api_key(app.current_event):
- return {"statusCode": 401, "body": json.dumps({"error": "Unauthorized"})}
-
- body = app.current_event.json_body
- logger.info(f"Processing receive_payment request with body: {body}")
-
- handler = PaymentHandler()
- return handler.receive_payment(
- amount=body['amount'],
- payment_method=body.get('method', 'LIGHTNING')
- )
- except Exception as e:
- logger.error(f"Error receiving payment: {str(e)}", exc_info=True)
- return {"statusCode": 500, "body": json.dumps({"error": str(e)})}
-
-@app.post("/send_payment")
-@tracer.capture_method
-def send_payment():
- try:
- if not validate_api_key(app.current_event):
- return {"statusCode": 401, "body": json.dumps({"error": "Unauthorized"})}
-
- body = app.current_event.json_body
- logger.info(f"Processing send_payment request with body: {body}")
-
- handler = PaymentHandler()
- return handler.send_payment(
- destination=body['destination'],
- amount=body.get('amount'),
- drain=body.get('drain', False)
- )
- except Exception as e:
- logger.error(f"Error sending payment: {str(e)}", exc_info=True)
- return {"statusCode": 500, "body": json.dumps({"error": str(e)})}
-
-@logger.inject_lambda_context
-@tracer.capture_lambda_handler
-def lambda_handler(event: dict, context: LambdaContext) -> dict:
- return app.resolve(event, context)
diff --git a/lambda/requirements.txt b/lambda/requirements.txt
deleted file mode 100644
index 6874e14..0000000
--- a/lambda/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-aws-lambda-powertools
-breez-sdk-liquid==0.6.3
-boto3
-python-dotenv
-requests
-aws-xray-sdk