aifinpay-agent 0.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: aifinpay-agent
3
+ Version: 0.1.0a1
4
+ Summary: Non-custodial x402 payment client for autonomous AI agents on AiFinPay (Solana + Polygon)
5
+ Author-email: "CoinSecurities (SECCO)" <contact@aifinpay.company>
6
+ License: MIT
7
+ Project-URL: Homepage, https://aifinpay.company
8
+ Project-URL: Documentation, https://aifinpay.company/docs
9
+ Project-URL: Repository, https://github.com/enot3615/oracle-financial-hub-59
10
+ Project-URL: Issues, https://github.com/enot3615/oracle-financial-hub-59/issues
11
+ Keywords: x402,ai-agent,solana,polygon,payments,non-custodial,ed25519
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: PyNaCl>=1.5
24
+ Requires-Dist: base58>=2.1
25
+ Requires-Dist: requests>=2.28
26
+
27
+ # aifinpay-agent (Python)
28
+
29
+ Non-custodial x402 payment client for autonomous AI agents on
30
+ [AiFinPay](https://aifinpay.company).
31
+
32
+ The Ed25519 keypair is generated locally and never leaves your process. The
33
+ SDK only sends a one-time SHA-256 + Ed25519 signature in the `x-signature`
34
+ header to authenticate against AiFinPay-protected endpoints.
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ pip install aifinpay-agent
40
+ ```
41
+
42
+ ## Quick start
43
+
44
+ ```python
45
+ from aifinpay import Agent
46
+
47
+ # Generate a fresh keypair locally — never transmitted
48
+ agent = Agent.new()
49
+ print("Fund this address:", agent.address)
50
+ print("Save this secret:", agent.secret_b58) # store securely!
51
+
52
+ # Wait until the wallet has at least $0.01 worth on-chain
53
+ agent.wait_for_funding(min_usd_cents=1)
54
+
55
+ # Request an invoice for a Seat (USDC on Solana)
56
+ invoice = agent.reserve_seat_invoice(amount_usd=1.00, asset="USDC")
57
+ print("Invoice:", invoice.raw)
58
+ # Build + sign + submit the Solana transaction with @solana/web3.js, anchorpy,
59
+ # or solana-py — the invoice contains program_id, treasury_vault, mints, etc.
60
+
61
+ # Once the Seat is on-chain, any AiFinPay-gated endpoint just works:
62
+ resp = agent.get("https://aifinpay.company/api/stats")
63
+ print(resp.json())
64
+ ```
65
+
66
+ ## Loading an existing keypair
67
+
68
+ ```python
69
+ # from solana-keygen JSON file
70
+ agent = Agent.from_keypair_file("~/agent-wallet.json")
71
+
72
+ # from base58 secret string
73
+ agent = Agent.from_secret_b58("3RvZm7Gw...")
74
+ ```
75
+
76
+ ## How x402 auth works under the hood
77
+
78
+ For every gated request the SDK:
79
+
80
+ 1. `GET /nonce` → receives a one-time UUID with 60s TTL
81
+ 2. computes `SHA-256("AiFinPay-x402:{nonce}:{pubkey}")`
82
+ 3. signs with Ed25519, base58-encodes the signature
83
+ 4. retries the original request with headers:
84
+ - `x-agent-pubkey: <base58 pubkey>`
85
+ - `x-nonce: <uuid>`
86
+ - `x-signature: <base58 sig>`
87
+
88
+ The server verifies the signature, checks the agent has a live Seat PDA
89
+ on-chain, and serves the resource.
90
+
91
+ ## Privacy
92
+
93
+ - **The server never sees your private key.** Period.
94
+ - Nonces are consumed on use; replay-resistant.
95
+ - All transactions are public and on-chain — Solana + Polygon mainnet.
96
+
97
+ ## License
98
+
99
+ MIT.
@@ -0,0 +1,73 @@
1
+ # aifinpay-agent (Python)
2
+
3
+ Non-custodial x402 payment client for autonomous AI agents on
4
+ [AiFinPay](https://aifinpay.company).
5
+
6
+ The Ed25519 keypair is generated locally and never leaves your process. The
7
+ SDK only sends a one-time SHA-256 + Ed25519 signature in the `x-signature`
8
+ header to authenticate against AiFinPay-protected endpoints.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pip install aifinpay-agent
14
+ ```
15
+
16
+ ## Quick start
17
+
18
+ ```python
19
+ from aifinpay import Agent
20
+
21
+ # Generate a fresh keypair locally — never transmitted
22
+ agent = Agent.new()
23
+ print("Fund this address:", agent.address)
24
+ print("Save this secret:", agent.secret_b58) # store securely!
25
+
26
+ # Wait until the wallet has at least $0.01 worth on-chain
27
+ agent.wait_for_funding(min_usd_cents=1)
28
+
29
+ # Request an invoice for a Seat (USDC on Solana)
30
+ invoice = agent.reserve_seat_invoice(amount_usd=1.00, asset="USDC")
31
+ print("Invoice:", invoice.raw)
32
+ # Build + sign + submit the Solana transaction with @solana/web3.js, anchorpy,
33
+ # or solana-py — the invoice contains program_id, treasury_vault, mints, etc.
34
+
35
+ # Once the Seat is on-chain, any AiFinPay-gated endpoint just works:
36
+ resp = agent.get("https://aifinpay.company/api/stats")
37
+ print(resp.json())
38
+ ```
39
+
40
+ ## Loading an existing keypair
41
+
42
+ ```python
43
+ # from solana-keygen JSON file
44
+ agent = Agent.from_keypair_file("~/agent-wallet.json")
45
+
46
+ # from base58 secret string
47
+ agent = Agent.from_secret_b58("3RvZm7Gw...")
48
+ ```
49
+
50
+ ## How x402 auth works under the hood
51
+
52
+ For every gated request the SDK:
53
+
54
+ 1. `GET /nonce` → receives a one-time UUID with 60s TTL
55
+ 2. computes `SHA-256("AiFinPay-x402:{nonce}:{pubkey}")`
56
+ 3. signs with Ed25519, base58-encodes the signature
57
+ 4. retries the original request with headers:
58
+ - `x-agent-pubkey: <base58 pubkey>`
59
+ - `x-nonce: <uuid>`
60
+ - `x-signature: <base58 sig>`
61
+
62
+ The server verifies the signature, checks the agent has a live Seat PDA
63
+ on-chain, and serves the resource.
64
+
65
+ ## Privacy
66
+
67
+ - **The server never sees your private key.** Period.
68
+ - Nonces are consumed on use; replay-resistant.
69
+ - All transactions are public and on-chain — Solana + Polygon mainnet.
70
+
71
+ ## License
72
+
73
+ MIT.
@@ -0,0 +1,23 @@
1
+ """
2
+ AiFinPay agent SDK — non-custodial x402 payment client.
3
+
4
+ Quick start:
5
+
6
+ from aifinpay import Agent
7
+
8
+ agent = Agent.new() # generate fresh Ed25519 keypair locally
9
+ print("Fund:", agent.address)
10
+
11
+ agent.wait_for_funding(min_usd_cents=100)
12
+ invoice = agent.reserve_seat(amount_usd=1.00, asset="USDC")
13
+ receipt = agent.send_signed(invoice)
14
+
15
+ # any HTTP call to AiFinPay-protected endpoints auto-handles x402:
16
+ resp = agent.request("GET", "https://aifinpay.company/api/stats")
17
+ """
18
+
19
+ from .client import Agent
20
+ from .errors import AiFinPayError, FundingTimeoutError, X402Error
21
+
22
+ __version__ = "0.1.0a1"
23
+ __all__ = ["Agent", "AiFinPayError", "FundingTimeoutError", "X402Error"]
@@ -0,0 +1,232 @@
1
+ """Low-level Agent client. Non-custodial: keypair never leaves this process."""
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import json
6
+ import os
7
+ import time
8
+ from dataclasses import dataclass
9
+ from typing import Any, Dict, Optional
10
+
11
+ import nacl.signing # PyNaCl
12
+ import base58
13
+ import requests
14
+
15
+ from .errors import (
16
+ AiFinPayError,
17
+ FundingTimeoutError,
18
+ SeatNotFoundError,
19
+ X402Error,
20
+ )
21
+
22
+ DEFAULT_BASE_URL = "https://aifinpay.company"
23
+ DEFAULT_TIMEOUT = 30 # seconds
24
+
25
+
26
+ @dataclass
27
+ class Invoice:
28
+ """An on-chain payment invoice returned by the AiFinPay backend."""
29
+
30
+ amount_usd: float
31
+ treasury_vault: str
32
+ program_id: str
33
+ nonce: str
34
+ raw: Dict[str, Any]
35
+
36
+
37
+ class Agent:
38
+ """A non-custodial AiFinPay agent.
39
+
40
+ The Ed25519 keypair lives only in this Python process. The SDK never
41
+ transmits the secret key; only ``signature(SHA256("AiFinPay-x402:{nonce}:{pubkey}"))``
42
+ is sent in the ``x-signature`` header.
43
+ """
44
+
45
+ def __init__(
46
+ self,
47
+ signing_key: nacl.signing.SigningKey,
48
+ base_url: str = DEFAULT_BASE_URL,
49
+ timeout: int = DEFAULT_TIMEOUT,
50
+ ):
51
+ self._sk = signing_key
52
+ self._vk = signing_key.verify_key
53
+ self.base_url = base_url.rstrip("/")
54
+ self.timeout = timeout
55
+ self._session = requests.Session()
56
+ self._session.headers["User-Agent"] = "aifinpay-agent-py/0.1.0"
57
+
58
+ # ── Constructors ────────────────────────────────────────────────────────
59
+
60
+ @classmethod
61
+ def new(cls, **kwargs) -> "Agent":
62
+ """Generate a fresh Ed25519 keypair locally."""
63
+ return cls(nacl.signing.SigningKey.generate(), **kwargs)
64
+
65
+ @classmethod
66
+ def from_secret_b58(cls, secret_b58: str, **kwargs) -> "Agent":
67
+ """Load from a 64-byte base58 secret (Solana style: secret + pub)."""
68
+ raw = base58.b58decode(secret_b58)
69
+ if len(raw) == 64:
70
+ raw = raw[:32]
71
+ if len(raw) != 32:
72
+ raise AiFinPayError(
73
+ f"secret must decode to 32 or 64 bytes, got {len(raw)}"
74
+ )
75
+ return cls(nacl.signing.SigningKey(raw), **kwargs)
76
+
77
+ @classmethod
78
+ def from_keypair_file(cls, path: str, **kwargs) -> "Agent":
79
+ """Load a Solana CLI ``solana-keygen`` JSON file (array of 64 ints)."""
80
+ with open(path) as f:
81
+ arr = json.load(f)
82
+ if not isinstance(arr, list) or len(arr) != 64:
83
+ raise AiFinPayError(f"{path}: expected 64-byte array")
84
+ return cls(nacl.signing.SigningKey(bytes(arr[:32])), **kwargs)
85
+
86
+ # ── Public properties ──────────────────────────────────────────────────
87
+
88
+ @property
89
+ def address(self) -> str:
90
+ """Solana base58 public key."""
91
+ return base58.b58encode(bytes(self._vk)).decode()
92
+
93
+ @property
94
+ def secret_b58(self) -> str:
95
+ """Base58-encoded secret. Save this somewhere safe."""
96
+ return base58.b58encode(bytes(self._sk) + bytes(self._vk)).decode()
97
+
98
+ # ── Manifesto / discovery ──────────────────────────────────────────────
99
+
100
+ def manifesto(self) -> Dict[str, Any]:
101
+ r = self._session.get(
102
+ f"{self.base_url}/manifesto.json", timeout=self.timeout
103
+ )
104
+ r.raise_for_status()
105
+ return r.json()
106
+
107
+ def well_known(self) -> Dict[str, Any]:
108
+ r = self._session.get(
109
+ f"{self.base_url}/.well-known/x402.json", timeout=self.timeout
110
+ )
111
+ r.raise_for_status()
112
+ return r.json()
113
+
114
+ # ── x402 auth ──────────────────────────────────────────────────────────
115
+
116
+ def _fetch_nonce(self) -> Dict[str, Any]:
117
+ r = self._session.get(f"{self.base_url}/nonce", timeout=self.timeout)
118
+ r.raise_for_status()
119
+ return r.json()
120
+
121
+ def _sign_nonce(self, nonce: str) -> str:
122
+ msg = f"AiFinPay-x402:{nonce}:{self.address}".encode()
123
+ digest = hashlib.sha256(msg).digest()
124
+ sig = self._sk.sign(digest).signature
125
+ return base58.b58encode(sig).decode()
126
+
127
+ def auth_headers(self) -> Dict[str, str]:
128
+ """Build a fresh x402 header set (nonces are one-time, 60s TTL)."""
129
+ nonce_info = self._fetch_nonce()
130
+ nonce = nonce_info["nonce"]
131
+ return {
132
+ "x-agent-pubkey": self.address,
133
+ "x-nonce": nonce,
134
+ "x-signature": self._sign_nonce(nonce),
135
+ }
136
+
137
+ # ── Funding / Seat ────────────────────────────────────────────────────
138
+
139
+ def has_seat(self) -> bool:
140
+ r = self._session.get(
141
+ f"{self.base_url}/api/seat/{self.address}", timeout=self.timeout
142
+ )
143
+ r.raise_for_status()
144
+ return bool(r.json().get("has_seat"))
145
+
146
+ def wait_for_funding(
147
+ self, min_usd_cents: int = 100, poll_seconds: int = 5, timeout: int = 600
148
+ ) -> None:
149
+ """Poll the leaderboard until this address shows up with at least
150
+ ``min_usd_cents`` reserved on its Seat. Raises FundingTimeoutError."""
151
+ deadline = time.time() + timeout
152
+ while time.time() < deadline:
153
+ r = self._session.get(
154
+ f"{self.base_url}/api/leaderboard?merge=true",
155
+ timeout=self.timeout,
156
+ )
157
+ r.raise_for_status()
158
+ for entry in r.json().get("leaderboard", []):
159
+ if entry.get("pubkey") == self.address:
160
+ cents = int(float(entry.get("usd", 0)) * 100)
161
+ if cents >= min_usd_cents:
162
+ return
163
+ time.sleep(poll_seconds)
164
+ raise FundingTimeoutError(
165
+ f"address {self.address} never reached {min_usd_cents} cents on-chain"
166
+ )
167
+
168
+ # ── Invoices (server returns instructions, agent executes on-chain) ────
169
+
170
+ def reserve_seat_invoice(
171
+ self, amount_usd: float, asset: str = "USDC"
172
+ ) -> Invoice:
173
+ """Request an invoice for reserving a Seat. The returned ``raw`` dict
174
+ contains everything you need to build and submit the on-chain
175
+ transaction with the Solana / Polygon SDK of your choice."""
176
+ endpoint = "/api/invoice" if asset.upper() == "SOL" else "/api/invoice-spl"
177
+ payload: Dict[str, Any] = {
178
+ "amount_usd": amount_usd,
179
+ "agent_pubkey": self.address,
180
+ }
181
+ if asset.upper() != "SOL":
182
+ payload["asset"] = asset.upper()
183
+ r = self._session.post(
184
+ f"{self.base_url}{endpoint}", json=payload, timeout=self.timeout
185
+ )
186
+ r.raise_for_status()
187
+ data = r.json()
188
+ return Invoice(
189
+ amount_usd=amount_usd,
190
+ treasury_vault=data.get("treasury_vault", ""),
191
+ program_id=data.get("program_id", ""),
192
+ nonce=data.get("nonce", ""),
193
+ raw=data,
194
+ )
195
+
196
+ # ── Convenience: x402-aware HTTP request ──────────────────────────────
197
+
198
+ def request(
199
+ self,
200
+ method: str,
201
+ url: str,
202
+ *,
203
+ max_retries: int = 1,
204
+ **kwargs,
205
+ ) -> requests.Response:
206
+ """HTTP request that auto-injects x-agent-pubkey/x-nonce/x-signature
207
+ headers on first try, and retries with fresh auth on 402."""
208
+ headers = kwargs.pop("headers", {}) or {}
209
+ attempt = 0
210
+ while True:
211
+ attempt += 1
212
+ merged = {**self.auth_headers(), **headers}
213
+ resp = self._session.request(
214
+ method, url, headers=merged, timeout=self.timeout, **kwargs
215
+ )
216
+ if resp.status_code != 402 or attempt > max_retries:
217
+ return resp
218
+ # 402 → caller hasn't reserved a Seat yet. Surface the challenge.
219
+ try:
220
+ challenge = resp.json()
221
+ except Exception:
222
+ challenge = {"raw": resp.text}
223
+ raise X402Error(
224
+ f"402 Payment Required after {attempt} attempt(s). "
225
+ f"Reserve a Seat first via reserve_seat_invoice(). "
226
+ f"Challenge: {challenge}"
227
+ )
228
+
229
+ # ── Aliases for ergonomics ────────────────────────────────────────────
230
+
231
+ get = lambda self, url, **kw: self.request("GET", url, **kw)
232
+ post = lambda self, url, **kw: self.request("POST", url, **kw)
@@ -0,0 +1,14 @@
1
+ class AiFinPayError(Exception):
2
+ """Base class for all SDK errors."""
3
+
4
+
5
+ class X402Error(AiFinPayError):
6
+ """Raised when the x402 challenge/response flow fails."""
7
+
8
+
9
+ class FundingTimeoutError(AiFinPayError):
10
+ """Raised when polling for funding exceeds the timeout."""
11
+
12
+
13
+ class SeatNotFoundError(AiFinPayError):
14
+ """Raised when the agent has no Seat PDA on-chain."""
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: aifinpay-agent
3
+ Version: 0.1.0a1
4
+ Summary: Non-custodial x402 payment client for autonomous AI agents on AiFinPay (Solana + Polygon)
5
+ Author-email: "CoinSecurities (SECCO)" <contact@aifinpay.company>
6
+ License: MIT
7
+ Project-URL: Homepage, https://aifinpay.company
8
+ Project-URL: Documentation, https://aifinpay.company/docs
9
+ Project-URL: Repository, https://github.com/enot3615/oracle-financial-hub-59
10
+ Project-URL: Issues, https://github.com/enot3615/oracle-financial-hub-59/issues
11
+ Keywords: x402,ai-agent,solana,polygon,payments,non-custodial,ed25519
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: PyNaCl>=1.5
24
+ Requires-Dist: base58>=2.1
25
+ Requires-Dist: requests>=2.28
26
+
27
+ # aifinpay-agent (Python)
28
+
29
+ Non-custodial x402 payment client for autonomous AI agents on
30
+ [AiFinPay](https://aifinpay.company).
31
+
32
+ The Ed25519 keypair is generated locally and never leaves your process. The
33
+ SDK only sends a one-time SHA-256 + Ed25519 signature in the `x-signature`
34
+ header to authenticate against AiFinPay-protected endpoints.
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ pip install aifinpay-agent
40
+ ```
41
+
42
+ ## Quick start
43
+
44
+ ```python
45
+ from aifinpay import Agent
46
+
47
+ # Generate a fresh keypair locally — never transmitted
48
+ agent = Agent.new()
49
+ print("Fund this address:", agent.address)
50
+ print("Save this secret:", agent.secret_b58) # store securely!
51
+
52
+ # Wait until the wallet has at least $0.01 worth on-chain
53
+ agent.wait_for_funding(min_usd_cents=1)
54
+
55
+ # Request an invoice for a Seat (USDC on Solana)
56
+ invoice = agent.reserve_seat_invoice(amount_usd=1.00, asset="USDC")
57
+ print("Invoice:", invoice.raw)
58
+ # Build + sign + submit the Solana transaction with @solana/web3.js, anchorpy,
59
+ # or solana-py — the invoice contains program_id, treasury_vault, mints, etc.
60
+
61
+ # Once the Seat is on-chain, any AiFinPay-gated endpoint just works:
62
+ resp = agent.get("https://aifinpay.company/api/stats")
63
+ print(resp.json())
64
+ ```
65
+
66
+ ## Loading an existing keypair
67
+
68
+ ```python
69
+ # from solana-keygen JSON file
70
+ agent = Agent.from_keypair_file("~/agent-wallet.json")
71
+
72
+ # from base58 secret string
73
+ agent = Agent.from_secret_b58("3RvZm7Gw...")
74
+ ```
75
+
76
+ ## How x402 auth works under the hood
77
+
78
+ For every gated request the SDK:
79
+
80
+ 1. `GET /nonce` → receives a one-time UUID with 60s TTL
81
+ 2. computes `SHA-256("AiFinPay-x402:{nonce}:{pubkey}")`
82
+ 3. signs with Ed25519, base58-encodes the signature
83
+ 4. retries the original request with headers:
84
+ - `x-agent-pubkey: <base58 pubkey>`
85
+ - `x-nonce: <uuid>`
86
+ - `x-signature: <base58 sig>`
87
+
88
+ The server verifies the signature, checks the agent has a live Seat PDA
89
+ on-chain, and serves the resource.
90
+
91
+ ## Privacy
92
+
93
+ - **The server never sees your private key.** Period.
94
+ - Nonces are consumed on use; replay-resistant.
95
+ - All transactions are public and on-chain — Solana + Polygon mainnet.
96
+
97
+ ## License
98
+
99
+ MIT.
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ aifinpay/__init__.py
4
+ aifinpay/client.py
5
+ aifinpay/errors.py
6
+ aifinpay_agent.egg-info/PKG-INFO
7
+ aifinpay_agent.egg-info/SOURCES.txt
8
+ aifinpay_agent.egg-info/dependency_links.txt
9
+ aifinpay_agent.egg-info/requires.txt
10
+ aifinpay_agent.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ PyNaCl>=1.5
2
+ base58>=2.1
3
+ requests>=2.28
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "aifinpay-agent"
7
+ version = "0.1.0a1"
8
+ description = "Non-custodial x402 payment client for autonomous AI agents on AiFinPay (Solana + Polygon)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "CoinSecurities (SECCO)", email = "contact@aifinpay.company" },
14
+ ]
15
+ keywords = ["x402", "ai-agent", "solana", "polygon", "payments", "non-custodial", "ed25519"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ ]
27
+ dependencies = [
28
+ "PyNaCl>=1.5",
29
+ "base58>=2.1",
30
+ "requests>=2.28",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://aifinpay.company"
35
+ Documentation = "https://aifinpay.company/docs"
36
+ Repository = "https://github.com/enot3615/oracle-financial-hub-59"
37
+ Issues = "https://github.com/enot3615/oracle-financial-hub-59/issues"
38
+
39
+ [tool.setuptools.packages.find]
40
+ where = ["."]
41
+ include = ["aifinpay*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+