voidly-pay 2.0.0__tar.gz → 2.0.2__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.
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/PKG-INFO +3 -3
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/README.md +2 -2
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/pyproject.toml +1 -1
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/voidly_pay/__init__.py +170 -0
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/voidly_pay.egg-info/PKG-INFO +3 -3
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/setup.cfg +0 -0
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/tests/test_sdk.py +0 -0
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/voidly_pay.egg-info/SOURCES.txt +0 -0
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/voidly_pay.egg-info/dependency_links.txt +0 -0
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/voidly_pay.egg-info/requires.txt +0 -0
- {voidly_pay-2.0.0 → voidly_pay-2.0.2}/voidly_pay.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voidly-pay
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Voidly Pay SDK — open marketplace for AI-agent payments. claim() + request_with_pay() handle x402 end-to-end. USDC-backed Sourcify-verified vault on Base mainnet.
|
|
5
5
|
Author-email: Voidly <team@voidly.ai>
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Requires-Dist: responses>=0.23; extra == "dev"
|
|
|
20
20
|
|
|
21
21
|
[](https://pypi.org/project/voidly-pay/)
|
|
22
22
|
[](https://www.x402.org)
|
|
23
|
-
[](https://repo.sourcify.dev/contracts/full_match/8453/
|
|
23
|
+
[](https://repo.sourcify.dev/contracts/full_match/8453/0xd25d3c6f32886b65356cc5c700382a8a02d84df5/)
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
pip install voidly-pay
|
|
@@ -188,7 +188,7 @@ ok = verify_webhook_signature(
|
|
|
188
188
|
|
|
189
189
|
## Honest disclosure
|
|
190
190
|
|
|
191
|
-
The Voidly Pay vault on Base mainnet (`
|
|
191
|
+
The Voidly Pay vault on Base mainnet (`0xd25d3c6f32886b65356cc5c700382a8a02d84df5`, [Sourcify-verified](https://repo.sourcify.dev/contracts/full_match/8453/0xd25d3c6f32886b65356cc5c700382a8a02d84df5/)) currently holds **$4 USDC**. We have approximately zero sustained external paying users yet. Live reserves at [voidly.ai/pay/proof](https://voidly.ai/pay/proof).
|
|
192
192
|
|
|
193
193
|
We opened the marketplace before the demand exists because we believe agent adoption is gated on discoverability, not on payment-rail UX.
|
|
194
194
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://pypi.org/project/voidly-pay/)
|
|
6
6
|
[](https://www.x402.org)
|
|
7
|
-
[](https://repo.sourcify.dev/contracts/full_match/8453/
|
|
7
|
+
[](https://repo.sourcify.dev/contracts/full_match/8453/0xd25d3c6f32886b65356cc5c700382a8a02d84df5/)
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
pip install voidly-pay
|
|
@@ -172,7 +172,7 @@ ok = verify_webhook_signature(
|
|
|
172
172
|
|
|
173
173
|
## Honest disclosure
|
|
174
174
|
|
|
175
|
-
The Voidly Pay vault on Base mainnet (`
|
|
175
|
+
The Voidly Pay vault on Base mainnet (`0xd25d3c6f32886b65356cc5c700382a8a02d84df5`, [Sourcify-verified](https://repo.sourcify.dev/contracts/full_match/8453/0xd25d3c6f32886b65356cc5c700382a8a02d84df5/)) currently holds **$4 USDC**. We have approximately zero sustained external paying users yet. Live reserves at [voidly.ai/pay/proof](https://voidly.ai/pay/proof).
|
|
176
176
|
|
|
177
177
|
We opened the marketplace before the demand exists because we believe agent adoption is gated on discoverability, not on payment-rail UX.
|
|
178
178
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "voidly-pay"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.2"
|
|
4
4
|
description = "Voidly Pay SDK — open marketplace for AI-agent payments. claim() + request_with_pay() handle x402 end-to-end. USDC-backed Sourcify-verified vault on Base mainnet."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -500,6 +500,176 @@ class VoidlyPay:
|
|
|
500
500
|
def trust(self, did: str | None = None) -> dict:
|
|
501
501
|
return self._req("GET", f"/v1/pay/trust/{did or self.did}")
|
|
502
502
|
|
|
503
|
+
# ─── Capability marketplace + hire (1.0.x compat surface) ──────────────
|
|
504
|
+
# These methods are kept for framework-adapter packages
|
|
505
|
+
# (voidly-pay-langchain, -crewai, -pydantic-ai, -autogen, -llamaindex)
|
|
506
|
+
# which were built against the 1.0.x API. New code should prefer
|
|
507
|
+
# /v1/pay/listings + the marketplace endpoint instead.
|
|
508
|
+
|
|
509
|
+
def capability_list(
|
|
510
|
+
self,
|
|
511
|
+
capability: str,
|
|
512
|
+
name: str,
|
|
513
|
+
description: str = "",
|
|
514
|
+
price_credits: float = 0.001,
|
|
515
|
+
unit: str = "call",
|
|
516
|
+
sla_deadline_hours: int = 24,
|
|
517
|
+
tags: list | None = None,
|
|
518
|
+
) -> dict:
|
|
519
|
+
"""Provider-signed capability listing. UPSERT on (provider DID, capability slug)."""
|
|
520
|
+
env = {
|
|
521
|
+
"schema": "voidly-capability-list/v1",
|
|
522
|
+
"did": self.did,
|
|
523
|
+
"capability": capability,
|
|
524
|
+
"name": name,
|
|
525
|
+
"description": description,
|
|
526
|
+
"price_micro": round(price_credits * MICRO_PER_CREDIT),
|
|
527
|
+
"unit": unit,
|
|
528
|
+
"sla_deadline_hours": sla_deadline_hours,
|
|
529
|
+
"tags": tags,
|
|
530
|
+
"nonce": uuid.uuid4().hex,
|
|
531
|
+
"issued_at": self._now_iso(),
|
|
532
|
+
"expires_at": self._expires(),
|
|
533
|
+
}
|
|
534
|
+
return self._req("POST", "/v1/pay/capability/list", {"envelope": env, "signature": self._sign(env)})
|
|
535
|
+
|
|
536
|
+
def capability_search(
|
|
537
|
+
self,
|
|
538
|
+
q: str | None = None,
|
|
539
|
+
capability: str | None = None,
|
|
540
|
+
max_price_credits: float | None = None,
|
|
541
|
+
provider_did: str | None = None,
|
|
542
|
+
limit: int = 50,
|
|
543
|
+
) -> dict:
|
|
544
|
+
params = []
|
|
545
|
+
if q: params.append(f"q={requests.utils.quote(q)}")
|
|
546
|
+
if capability: params.append(f"capability={requests.utils.quote(capability)}")
|
|
547
|
+
if max_price_credits is not None: params.append(f"max_price_micro={round(max_price_credits * MICRO_PER_CREDIT)}")
|
|
548
|
+
if provider_did: params.append(f"provider_did={provider_did}")
|
|
549
|
+
params.append(f"limit={limit}")
|
|
550
|
+
qs = "?" + "&".join(params) if params else ""
|
|
551
|
+
return self._req("GET", f"/v1/pay/capability/search{qs}")
|
|
552
|
+
|
|
553
|
+
# alias used by some framework adapters
|
|
554
|
+
def capability(self, *args, **kwargs):
|
|
555
|
+
return self.capability_list(*args, **kwargs)
|
|
556
|
+
|
|
557
|
+
def hire(
|
|
558
|
+
self,
|
|
559
|
+
capability_id: str,
|
|
560
|
+
input: Any = None,
|
|
561
|
+
task_id: str | None = None,
|
|
562
|
+
delivery_deadline_hours: int = 24,
|
|
563
|
+
) -> dict:
|
|
564
|
+
"""Atomic hire — opens escrow + records hire in one call. Server-pinned price."""
|
|
565
|
+
env = {
|
|
566
|
+
"schema": "voidly-hire-request/v1",
|
|
567
|
+
"did": self.did,
|
|
568
|
+
"capability_id": capability_id,
|
|
569
|
+
"input": input,
|
|
570
|
+
"task_id": task_id or uuid.uuid4().hex,
|
|
571
|
+
"delivery_deadline_hours": delivery_deadline_hours,
|
|
572
|
+
"nonce": uuid.uuid4().hex,
|
|
573
|
+
"issued_at": self._now_iso(),
|
|
574
|
+
"expires_at": self._expires(),
|
|
575
|
+
}
|
|
576
|
+
return self._req("POST", "/v1/pay/hire", {"envelope": env, "signature": self._sign(env)})
|
|
577
|
+
|
|
578
|
+
def hire_get(self, hire_id: str) -> dict:
|
|
579
|
+
return self._req("GET", f"/v1/pay/hire/{hire_id}")
|
|
580
|
+
|
|
581
|
+
def hires_incoming(self, did: str | None = None, state: str | None = None, limit: int = 50) -> dict:
|
|
582
|
+
target = did or self.did
|
|
583
|
+
qs = f"?limit={limit}" + (f"&state={requests.utils.quote(state)}" if state else "")
|
|
584
|
+
return self._req("GET", f"/v1/pay/hire/incoming/{target}{qs}")
|
|
585
|
+
|
|
586
|
+
def hires_outgoing(self, did: str | None = None, state: str | None = None, limit: int = 50) -> dict:
|
|
587
|
+
target = did or self.did
|
|
588
|
+
qs = f"?limit={limit}" + (f"&state={requests.utils.quote(state)}" if state else "")
|
|
589
|
+
return self._req("GET", f"/v1/pay/hire/outgoing/{target}{qs}")
|
|
590
|
+
|
|
591
|
+
def hire_and_wait(
|
|
592
|
+
self,
|
|
593
|
+
capability_id: str,
|
|
594
|
+
input: Any = None,
|
|
595
|
+
task_id: str | None = None,
|
|
596
|
+
delivery_deadline_hours: int = 24,
|
|
597
|
+
poll_interval_s: float = 1.0,
|
|
598
|
+
timeout_s: float = 30.0,
|
|
599
|
+
) -> dict:
|
|
600
|
+
"""Hire + poll until completion. Returns the final hire state."""
|
|
601
|
+
import time
|
|
602
|
+
h = self.hire(capability_id, input=input, task_id=task_id, delivery_deadline_hours=delivery_deadline_hours)
|
|
603
|
+
hire_id = h.get("hire_id") or h.get("id")
|
|
604
|
+
if not hire_id:
|
|
605
|
+
return h
|
|
606
|
+
deadline = time.time() + timeout_s
|
|
607
|
+
while time.time() < deadline:
|
|
608
|
+
state = self.hire_get(hire_id)
|
|
609
|
+
if state.get("hire", {}).get("state") in ("completed", "disputed", "expired"):
|
|
610
|
+
return state
|
|
611
|
+
time.sleep(poll_interval_s)
|
|
612
|
+
return state # whatever the last poll showed
|
|
613
|
+
|
|
614
|
+
# alias for adapters that use `escrow` as a single namespace
|
|
615
|
+
def escrow(self, op: str, **kwargs):
|
|
616
|
+
if op == "open": return self.open_escrow(**kwargs)
|
|
617
|
+
if op == "release": return self.release_escrow(**kwargs)
|
|
618
|
+
if op == "refund": return self.refund_escrow(**kwargs)
|
|
619
|
+
raise VoidlyPayError(code="bad_escrow_op", message=f"unknown escrow op: {op}", status=400)
|
|
620
|
+
|
|
621
|
+
# Marketplace listings (Round 31 surface — also kept for 1.0 compat)
|
|
622
|
+
def list_endpoint(
|
|
623
|
+
self,
|
|
624
|
+
name: str,
|
|
625
|
+
tagline: str,
|
|
626
|
+
url: str,
|
|
627
|
+
amount_usdc: float,
|
|
628
|
+
description: str | None = None,
|
|
629
|
+
category: str | None = None,
|
|
630
|
+
method: str = "GET",
|
|
631
|
+
receiver_did: str | None = None,
|
|
632
|
+
free_tier_url: str | None = None,
|
|
633
|
+
free_tier_description: str | None = None,
|
|
634
|
+
try_url: str | None = None,
|
|
635
|
+
info_url: str | None = None,
|
|
636
|
+
tags: list | None = None,
|
|
637
|
+
why_unique: str | None = None,
|
|
638
|
+
examples: list | None = None,
|
|
639
|
+
) -> dict:
|
|
640
|
+
env = {
|
|
641
|
+
"schema": "voidly-pay-listing-create/v1",
|
|
642
|
+
"did": self.did,
|
|
643
|
+
"name": name,
|
|
644
|
+
"tagline": tagline,
|
|
645
|
+
"url": url,
|
|
646
|
+
"method": method,
|
|
647
|
+
"pricing": {"amount_micro": round(amount_usdc * MICRO_PER_CREDIT), "currency": "voidly-credit", "model": "per-call"},
|
|
648
|
+
"nonce": uuid.uuid4().hex,
|
|
649
|
+
"issued_at": self._now_iso(),
|
|
650
|
+
"expires_at": self._expires(),
|
|
651
|
+
}
|
|
652
|
+
if description: env["description"] = description
|
|
653
|
+
if category: env["category"] = category
|
|
654
|
+
if receiver_did: env["receiver_did"] = receiver_did
|
|
655
|
+
if free_tier_url: env["free_tier_url"] = free_tier_url
|
|
656
|
+
if free_tier_description: env["free_tier_description"] = free_tier_description
|
|
657
|
+
if try_url: env["try_url"] = try_url
|
|
658
|
+
if info_url: env["info_url"] = info_url
|
|
659
|
+
if tags: env["tags"] = tags
|
|
660
|
+
if why_unique: env["why_unique"] = why_unique
|
|
661
|
+
if examples: env["examples"] = examples
|
|
662
|
+
return self._req("POST", "/v1/pay/listings", {"envelope": env, "signature": self._sign(env)})
|
|
663
|
+
|
|
664
|
+
def marketplace(self) -> dict:
|
|
665
|
+
return self._req("GET", "/v1/pay/marketplace")
|
|
666
|
+
|
|
667
|
+
def listings(self, limit: int = 50, offset: int = 0, tag: str | None = None, category: str | None = None) -> dict:
|
|
668
|
+
params = [f"limit={limit}", f"offset={offset}"]
|
|
669
|
+
if tag: params.append(f"tag={requests.utils.quote(tag)}")
|
|
670
|
+
if category: params.append(f"category={requests.utils.quote(category)}")
|
|
671
|
+
return self._req("GET", f"/v1/pay/listings?" + "&".join(params))
|
|
672
|
+
|
|
503
673
|
|
|
504
674
|
# ─── Webhook signature verification ──────────────────────────────────────
|
|
505
675
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voidly-pay
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Voidly Pay SDK — open marketplace for AI-agent payments. claim() + request_with_pay() handle x402 end-to-end. USDC-backed Sourcify-verified vault on Base mainnet.
|
|
5
5
|
Author-email: Voidly <team@voidly.ai>
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Requires-Dist: responses>=0.23; extra == "dev"
|
|
|
20
20
|
|
|
21
21
|
[](https://pypi.org/project/voidly-pay/)
|
|
22
22
|
[](https://www.x402.org)
|
|
23
|
-
[](https://repo.sourcify.dev/contracts/full_match/8453/
|
|
23
|
+
[](https://repo.sourcify.dev/contracts/full_match/8453/0xd25d3c6f32886b65356cc5c700382a8a02d84df5/)
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
pip install voidly-pay
|
|
@@ -188,7 +188,7 @@ ok = verify_webhook_signature(
|
|
|
188
188
|
|
|
189
189
|
## Honest disclosure
|
|
190
190
|
|
|
191
|
-
The Voidly Pay vault on Base mainnet (`
|
|
191
|
+
The Voidly Pay vault on Base mainnet (`0xd25d3c6f32886b65356cc5c700382a8a02d84df5`, [Sourcify-verified](https://repo.sourcify.dev/contracts/full_match/8453/0xd25d3c6f32886b65356cc5c700382a8a02d84df5/)) currently holds **$4 USDC**. We have approximately zero sustained external paying users yet. Live reserves at [voidly.ai/pay/proof](https://voidly.ai/pay/proof).
|
|
192
192
|
|
|
193
193
|
We opened the marketplace before the demand exists because we believe agent adoption is gated on discoverability, not on payment-rail UX.
|
|
194
194
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|