From 072e1d662f83a5b5f7f9728891a1fd960a84a2d5 Mon Sep 17 00:00:00 2001 From: 123xiaode456-boop <123xiaode456@gmail.com> Date: Mon, 22 Jun 2026 10:09:29 +0800 Subject: [PATCH] feat: add environment constants --- README.md | 19 ++++++++++++++++ src/shade/__init__.py | 3 ++- src/shade/config.py | 50 +++++++++++++++++++++++++++++++++++++++++++ src/shade/gateway.py | 33 ++++++++++++++++++++++++---- tests/test_config.py | 20 +++++++++++++++++ tests/test_gateway.py | 25 ++++++++++++++++++++-- 6 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 src/shade/config.py create mode 100644 tests/test_config.py diff --git a/README.md b/README.md index 569248b..78d5148 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,22 @@ A Python-based payment gateway system for Shade Protocol. +## Environments + +Shade defaults to the sandbox environment so local development uses Stellar +testnet and the staging Shade backend. + +```python +from shade import Gateway + +shade = Gateway() +shade.environment = "production" + +print(shade.horizon_url) +print(shade.network_passphrase) +print(shade.api_base_url) +``` + +Supported values are `"sandbox"` and `"production"`. Invalid values raise a +`ValueError` that lists the accepted options. + diff --git a/src/shade/__init__.py b/src/shade/__init__.py index fe0645a..0b2eee9 100644 --- a/src/shade/__init__.py +++ b/src/shade/__init__.py @@ -1,5 +1,6 @@ +from .config import Environment, EnvironmentConfig, parse_environment from .gateway import Gateway __version__ = "0.1.0" -__all__ = ["Gateway"] +__all__ = ["Environment", "EnvironmentConfig", "Gateway", "parse_environment"] diff --git a/src/shade/config.py b/src/shade/config.py new file mode 100644 index 0000000..89baa99 --- /dev/null +++ b/src/shade/config.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from dataclasses import dataclass +from enum import Enum + + +class Environment(str, Enum): + SANDBOX = "sandbox" + PRODUCTION = "production" + + +@dataclass(frozen=True) +class EnvironmentConfig: + horizon_url: str + network_passphrase: str + api_base_url: str + + +_ENVIRONMENT_CONFIGS = { + Environment.SANDBOX: EnvironmentConfig( + horizon_url="https://horizon-testnet.stellar.org", + network_passphrase="Test SDF Network ; September 2015", + api_base_url="https://api.sandbox.shadeprotocol.io", + ), + Environment.PRODUCTION: EnvironmentConfig( + horizon_url="https://horizon.stellar.org", + network_passphrase="Public Global Stellar Network ; September 2015", + api_base_url="https://api.shadeprotocol.io", + ), +} + + +def parse_environment(value: Environment | str) -> Environment: + if isinstance(value, Environment): + return value + + if isinstance(value, str): + normalized = value.strip().lower() + for environment in Environment: + if environment.value == normalized: + return environment + + valid_options = ", ".join(environment.value for environment in Environment) + raise ValueError( + f"Invalid Shade environment {value!r}. Valid options: {valid_options}" + ) + + +def get_environment_config(value: Environment | str) -> EnvironmentConfig: + return _ENVIRONMENT_CONFIGS[parse_environment(value)] diff --git a/src/shade/gateway.py b/src/shade/gateway.py index efb6bca..67d4868 100644 --- a/src/shade/gateway.py +++ b/src/shade/gateway.py @@ -1,13 +1,38 @@ +from .config import Environment, get_environment_config, parse_environment + + class Gateway: """ Main entry point for the Shade Payment Gateway. """ - def __init__(self): - pass + + def __init__(self, environment: Environment | str = Environment.SANDBOX): + self.environment = environment + + @property + def environment(self) -> Environment: + return self._environment + + @environment.setter + def environment(self, value: Environment | str) -> None: + self._environment = parse_environment(value) + self._environment_config = get_environment_config(self._environment) + + @property + def horizon_url(self) -> str: + return self._environment_config.horizon_url + + @property + def network_passphrase(self) -> str: + return self._environment_config.network_passphrase + + @property + def api_base_url(self) -> str: + return self._environment_config.api_base_url def process_payment(self, amount: float, currency: str): """ Process a payment (placeholder). """ - print(f"Processing payment of {amount} {currency}...") - return True + print(f"Processing payment of {amount} {currency}...") + return True diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..11678a9 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,20 @@ +import pytest + +from shade import Environment +from shade.config import parse_environment + + +def test_parse_environment_accepts_string_shorthands(): + assert parse_environment("sandbox") is Environment.SANDBOX + assert parse_environment("production") is Environment.PRODUCTION + + +def test_parse_environment_rejects_invalid_strings_with_valid_options(): + with pytest.raises(ValueError) as exc: + parse_environment("staging") + + message = str(exc.value) + assert "staging" in message + assert "sandbox" in message + assert "production" in message + diff --git a/tests/test_gateway.py b/tests/test_gateway.py index 95dc234..bfb1db1 100644 --- a/tests/test_gateway.py +++ b/tests/test_gateway.py @@ -1,11 +1,32 @@ -import pytest -from shade import Gateway +from shade import Environment, Gateway + def test_gateway_initialization(): gateway = Gateway() assert gateway is not None + def test_process_payment(): gateway = Gateway() result = gateway.process_payment(100.0, "USD") assert result is True + + +def test_gateway_defaults_to_sandbox_environment(): + gateway = Gateway() + + assert gateway.environment is Environment.SANDBOX + assert gateway.horizon_url == "https://horizon-testnet.stellar.org" + assert gateway.network_passphrase == "Test SDF Network ; September 2015" + assert gateway.api_base_url == "https://api.sandbox.shadeprotocol.io" + + +def test_gateway_environment_string_updates_stellar_and_api_config(): + gateway = Gateway() + + gateway.environment = "production" + + assert gateway.environment is Environment.PRODUCTION + assert gateway.horizon_url == "https://horizon.stellar.org" + assert gateway.network_passphrase == "Public Global Stellar Network ; September 2015" + assert gateway.api_base_url == "https://api.shadeprotocol.io"