@asgcard/pay 0.1.1
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.
- package/CHANGELOG.md +90 -0
- package/LICENSE +21 -0
- package/README.md +393 -0
- package/dist/cjs/adapters/base.js +174 -0
- package/dist/cjs/adapters/base.js.map +1 -0
- package/dist/cjs/adapters/evm.js +263 -0
- package/dist/cjs/adapters/evm.js.map +1 -0
- package/dist/cjs/adapters/index.js +13 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/stellar.js +173 -0
- package/dist/cjs/adapters/stellar.js.map +1 -0
- package/dist/cjs/adapters/stripe.js +338 -0
- package/dist/cjs/adapters/stripe.js.map +1 -0
- package/dist/cjs/adapters/types.js +3 -0
- package/dist/cjs/adapters/types.js.map +1 -0
- package/dist/cjs/client.js +309 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/index.js +36 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/logger.js +7 -0
- package/dist/cjs/logger.js.map +1 -0
- package/dist/cjs/mpp.js +187 -0
- package/dist/cjs/mpp.js.map +1 -0
- package/dist/cjs/policy.js +71 -0
- package/dist/cjs/policy.js.map +1 -0
- package/dist/cjs/stellar.js +87 -0
- package/dist/cjs/stellar.js.map +1 -0
- package/dist/esm/adapters/base.js +170 -0
- package/dist/esm/adapters/base.js.map +1 -0
- package/dist/esm/adapters/evm.js +258 -0
- package/dist/esm/adapters/evm.js.map +1 -0
- package/dist/esm/adapters/index.js +5 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/stellar.js +136 -0
- package/dist/esm/adapters/stellar.js.map +1 -0
- package/dist/esm/adapters/stripe.js +334 -0
- package/dist/esm/adapters/stripe.js.map +1 -0
- package/dist/esm/adapters/types.js +2 -0
- package/dist/esm/adapters/types.js.map +1 -0
- package/dist/esm/client.js +302 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logger.js +3 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/mpp.js +175 -0
- package/dist/esm/mpp.js.map +1 -0
- package/dist/esm/policy.js +67 -0
- package/dist/esm/policy.js.map +1 -0
- package/dist/esm/stellar.js +50 -0
- package/dist/esm/stellar.js.map +1 -0
- package/dist/types/adapters/base.d.ts +53 -0
- package/dist/types/adapters/base.d.ts.map +1 -0
- package/dist/types/adapters/evm.d.ts +81 -0
- package/dist/types/adapters/evm.d.ts.map +1 -0
- package/dist/types/adapters/index.d.ts +6 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/stellar.d.ts +67 -0
- package/dist/types/adapters/stellar.d.ts.map +1 -0
- package/dist/types/adapters/stripe.d.ts +206 -0
- package/dist/types/adapters/stripe.d.ts.map +1 -0
- package/dist/types/adapters/types.d.ts +35 -0
- package/dist/types/adapters/types.d.ts.map +1 -0
- package/dist/types/client.d.ts +89 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logger.d.ts +10 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/mpp.d.ts +153 -0
- package/dist/types/mpp.d.ts.map +1 -0
- package/dist/types/policy.d.ts +40 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/stellar.d.ts +27 -0
- package/dist/types/stellar.d.ts.map +1 -0
- package/package.json +86 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@asgcard/pay` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.1] โ 2026-04-03
|
|
6
|
+
|
|
7
|
+
### ๐ Major Rewrite โ Real MPP Protocol Support
|
|
8
|
+
|
|
9
|
+
The `StripePaymentAdapter` has been completely rewritten to implement the real Machine Payments Protocol (MPP) as specified at [mpp.dev](https://mpp.dev/payment-methods/stripe).
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **`src/mpp.ts`** โ Full MPP protocol utilities module
|
|
13
|
+
- `parseMppChallenge()` โ Parse `WWW-Authenticate: Payment` headers (RFC 7235)
|
|
14
|
+
- `buildMppCredential()` โ Build base64url-encoded credentials
|
|
15
|
+
- `buildAuthorizationHeader()` โ Build `Authorization: Payment` headers
|
|
16
|
+
- `parseMppReceipt()` โ Parse `Payment-Receipt` headers
|
|
17
|
+
- `detectProtocol()` โ Auto-detect MPP vs x402 from 402 responses
|
|
18
|
+
- `extractMppChallenges()` โ Extract multiple payment challenges
|
|
19
|
+
- `base64urlEncode/Decode()` โ RFC 4648 ยง5 helpers
|
|
20
|
+
- **Dual-protocol `OwsClient`** โ Automatically detects and handles BOTH protocols:
|
|
21
|
+
- **MPP**: `WWW-Authenticate: Payment` โ `Authorization: Payment` flow
|
|
22
|
+
- **x402**: JSON body โ `X-PAYMENT` header flow
|
|
23
|
+
- **StripePaymentAdapter** โ Full MPP lifecycle:
|
|
24
|
+
- SPT creation via `POST /v1/test_helpers/shared_payment/granted_tokens` (test)
|
|
25
|
+
- SPT creation via `POST /v1/shared_payment/issued_tokens` (production)
|
|
26
|
+
- Challenge-bound credential generation
|
|
27
|
+
- PaymentIntent creation with SPT for fallback mode
|
|
28
|
+
- `buildServerChallenge()` for gating your own APIs
|
|
29
|
+
- Autonomous mode (paymentMethodId) + Delegated mode (external SPT)
|
|
30
|
+
- **29 new tests** โ MPP protocol (26) + Stripe adapter rewrite (3 new)
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- `StripePaymentAdapter.pay()` now returns base64url MPP credential (not PaymentIntent ID) when challenge is present
|
|
34
|
+
- `OwsClient` interceptor now checks `WWW-Authenticate` header before JSON body
|
|
35
|
+
- Challenge selection logic prefers adapter-matching payment method
|
|
36
|
+
|
|
37
|
+
### Test Results
|
|
38
|
+
- **125/125 tests passed** (was 96)
|
|
39
|
+
- TypeScript strict mode โ PASS
|
|
40
|
+
- Dual CJS/ESM build โ PASS
|
|
41
|
+
|
|
42
|
+
## [0.1.0] โ 2026-04-03
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- **OwsClient** โ Axios-based HTTP client with autonomous 402 interceptor
|
|
46
|
+
- **PolicyEngine** โ Fail-closed budget controller (per-tx limits, monthly cap, address whitelist)
|
|
47
|
+
- **EvmPaymentAdapter** โ Universal EVM on-chain settlement via viem
|
|
48
|
+
- **10 networks**: Base, Arbitrum, Optimism, Ethereum, Polygon (mainnet + testnet each)
|
|
49
|
+
- Native token (ETH/MATIC) and USDC ERC-20 transfers
|
|
50
|
+
- Circle official USDC contracts for 9/10 networks
|
|
51
|
+
- `listEvmChains()` helper for runtime chain discovery
|
|
52
|
+
- One adapter class for ALL EVM chains โ no per-chain files
|
|
53
|
+
- **StripePaymentAdapter** โ Machine Payments Protocol (MPP) settlement
|
|
54
|
+
- Shared Payment Token (SPT) based fiat + stablecoin payments
|
|
55
|
+
- PaymentIntent creation and confirmation
|
|
56
|
+
- Live/test mode auto-detection from API key
|
|
57
|
+
- `stripe` is an optional peer dependency (lazy-loaded)
|
|
58
|
+
- `setSptToken()` for dynamic SPT updates
|
|
59
|
+
- **StellarPaymentAdapter** โ On-chain settlement on Stellar
|
|
60
|
+
- Native XLM payments
|
|
61
|
+
- Circle USDC payments (native Stellar USDC)
|
|
62
|
+
- Automatic trustline management
|
|
63
|
+
- Mainnet + Testnet support
|
|
64
|
+
- **BasePaymentAdapter** โ Legacy Base-only adapter (use `EvmPaymentAdapter` instead)
|
|
65
|
+
- **Silent-by-default logging** โ opt-in via `logger: console.log`
|
|
66
|
+
- **Dual CJS/ESM build** โ works with both `require()` and `import`
|
|
67
|
+
- **Full test suite** โ 96 tests via Vitest (PolicyEngine, OwsClient, EvmPaymentAdapter, StripePaymentAdapter)
|
|
68
|
+
- **X-PAYMENT proof generation** โ Base64-encoded JSON with CAIP-2 chain ID and tx hash
|
|
69
|
+
|
|
70
|
+
### Supported Protocols
|
|
71
|
+
- **x402** โ HTTP 402 + on-chain settlement (Coinbase/Cloudflare)
|
|
72
|
+
- **MPP** โ Machine Payments Protocol + Stripe SPTs (Stripe/Tempo)
|
|
73
|
+
|
|
74
|
+
### Supported Networks (13 total)
|
|
75
|
+
|
|
76
|
+
| Network | CAIP-2 | Asset | Protocol |
|
|
77
|
+
|---------|--------|-------|----------|
|
|
78
|
+
| Base | eip155:8453 | ETH/USDC | x402 |
|
|
79
|
+
| Base Sepolia | eip155:84532 | ETH/USDC | x402 |
|
|
80
|
+
| Arbitrum One | eip155:42161 | ETH/USDC | x402 |
|
|
81
|
+
| Arbitrum Sepolia | eip155:421614 | ETH/USDC | x402 |
|
|
82
|
+
| Optimism | eip155:10 | ETH/USDC | x402 |
|
|
83
|
+
| Optimism Sepolia | eip155:11155420 | ETH/USDC | x402 |
|
|
84
|
+
| Ethereum | eip155:1 | ETH/USDC | x402 |
|
|
85
|
+
| Ethereum Sepolia | eip155:11155111 | ETH/USDC | x402 |
|
|
86
|
+
| Polygon | eip155:137 | MATIC/USDC | x402 |
|
|
87
|
+
| Polygon Amoy | eip155:80002 | MATIC | x402 |
|
|
88
|
+
| Stellar Mainnet | stellar:pubnet | XLM/USDC | x402 |
|
|
89
|
+
| Stellar Testnet | stellar:testnet | XLM/USDC | x402 |
|
|
90
|
+
| Stripe (fiat) | stripe:live/test | USD/EUR/etc | MPP |
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ASG Compute
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ๐ OWS Agent Pay
|
|
4
|
+
|
|
5
|
+
### Autonomous Payment SDK for AI Agents
|
|
6
|
+
|
|
7
|
+
**OWS-compliant** โข **x402 Protocol** โข **Multi-chain** โข **Policy-gated**
|
|
8
|
+
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://openwallet.sh)
|
|
11
|
+
[](https://x402.org)
|
|
12
|
+
[](https://www.npmjs.com/package/@asgcard/pay)
|
|
13
|
+
[](https://base.org)
|
|
14
|
+
[](https://stellar.org)
|
|
15
|
+
[](https://pay.asgcard.dev)
|
|
16
|
+
|
|
17
|
+
*The AI agent simply calls `performTask()` โ the SDK handles payment, policy validation, on-chain settlement, and proof generation transparently.*
|
|
18
|
+
|
|
19
|
+
[Documentation](https://pay.asgcard.dev) โข [**โถ Live Demo**](https://asgcompute.github.io/ASGCompute-ows-agent-pay/) โข [Architecture](#%EF%B8%8F-architecture) โข [Live Products](#-live-production-products) โข [OWS Compliance](#-ows-spec-compliance)
|
|
20
|
+
|
|
21
|
+
> **๐ฎ [Try the interactive demo โ](https://asgcompute.github.io/ASGCompute-ows-agent-pay/)** โ no install, no wallet, no ETH needed. Watch the full x402 flow in your browser.
|
|
22
|
+
|
|
23
|
+
> **๐ [View the full ecosystem demo โ](https://asgcompute.github.io/ASGCompute-ows-agent-pay/ecosystem.html)** โ Fund โ Card โ Pay: the complete autonomous agent financial stack.
|
|
24
|
+
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ๐ก What This Solves
|
|
30
|
+
|
|
31
|
+
AI agents are rapidly becoming autonomous economic actors, but they have no native way to **pay for services programmatically**. OWS Agent Pay bridges this gap:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
AI Agent calls API โ Server returns HTTP 402 โ SDK auto-pays โ Agent gets result
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Zero payment code required from the agent developer.** The SDK intercepts, validates, settles, and retries โ all transparently.
|
|
38
|
+
|
|
39
|
+
> โ ๏ธ **This is not a hackathon prototype.** We extracted the core x402 payment logic from our **live production stack** (10K+ monthly NPM downloads) into a clean, OWS-compliant SDK.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## โก Quick Start
|
|
44
|
+
|
|
45
|
+
### Option 1: Browser Demo (Zero Install)
|
|
46
|
+
|
|
47
|
+
> **[โถ Open the live demo โ](https://asgcompute.github.io/ASGCompute-ows-agent-pay/)** โ click "Run Live Demo" and watch the full x402 cycle in 30 seconds.
|
|
48
|
+
|
|
49
|
+
### Option 2: CLI Demo
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Clone and install
|
|
53
|
+
git clone https://github.com/ASGCompute/ASGCompute-ows-agent-pay.git
|
|
54
|
+
cd ASGCompute-ows-agent-pay
|
|
55
|
+
npm install
|
|
56
|
+
|
|
57
|
+
# Run the demo (simulated mode โ no ETH needed)
|
|
58
|
+
npx ts-node demo.ts --simulate
|
|
59
|
+
|
|
60
|
+
# Or run with real Base Sepolia testnet (auto-funds via Coinbase faucet)
|
|
61
|
+
npx ts-node demo.ts
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Option 3: Use in Your Agent
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { OwsClient, BasePaymentAdapter } from 'ows-agent-pay';
|
|
68
|
+
|
|
69
|
+
const adapter = new BasePaymentAdapter({
|
|
70
|
+
privateKey: process.env.AGENT_PRIVATE_KEY as `0x${string}`,
|
|
71
|
+
network: 'mainnet',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const agent = new OwsClient({
|
|
75
|
+
baseURL: 'https://inference-api.example.com',
|
|
76
|
+
policy: {
|
|
77
|
+
monthlyBudget: 100,
|
|
78
|
+
maxAmountPerTransaction: 5,
|
|
79
|
+
allowedDestinations: ['0x...'],
|
|
80
|
+
},
|
|
81
|
+
adapter, // Swap to StellarPaymentAdapter for Stellar
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Agent code โ no payment logic needed!
|
|
85
|
+
const result = await agent.performTask('/v1/chat', {
|
|
86
|
+
model: 'gpt-4',
|
|
87
|
+
messages: [{ role: 'user', content: 'Summarize this document' }],
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Expected CLI Output
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
95
|
+
โ OWS Agent Pay โ Base/EVM Autonomous Demo โ
|
|
96
|
+
โ Built by ASG Pay โข https://asgcard.dev โ
|
|
97
|
+
โ x402 Protocol โข Base (Coinbase L2) โ
|
|
98
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
99
|
+
|
|
100
|
+
[Server] Mock API listening on http://localhost:4020
|
|
101
|
+
[Agent] Wallet: 0xAb5801a7D398991B8a7cF7706226...
|
|
102
|
+
[Agent] Chain: Base Sepolia (eip155:84532)
|
|
103
|
+
[Agent] ๐ง Requesting ETH from Base Sepolia faucetโฆ
|
|
104
|
+
[Agent] โ
Wallet funded from Coinbase faucet
|
|
105
|
+
[Agent] ๐ฐ Balance: 0.1 ETH
|
|
106
|
+
[Agent] ๐ง Sending inference requestโฆ
|
|
107
|
+
|
|
108
|
+
[OWS Client] โก Received 402 Payment Required challenge
|
|
109
|
+
[OWS Client] ๐ฐ Requested payment: $0.50
|
|
110
|
+
[OWS Client] โ๏ธ Settlement chain: Base (eip155:84532)
|
|
111
|
+
[OWS Client] โ
Policy check PASSED โ settling on-chainโฆ
|
|
112
|
+
[Base] ๐ Building payment โ 0xDead71โฆ8B3c4F (0.0005 ETH, Base Sepolia)
|
|
113
|
+
[Base] ๐ก Submitting transactionโฆ
|
|
114
|
+
[Base] โ
Confirmed โ hash: 0x9e8f7a6b5c4d3e2fโฆ
|
|
115
|
+
[OWS Client] ๐ Constructing X-PAYMENT token and retryingโฆ
|
|
116
|
+
|
|
117
|
+
[AI Agent] โ
Task completed: The AI model computed the answer...
|
|
118
|
+
|
|
119
|
+
โโ ๐ Demo complete โโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## ๐๏ธ Architecture
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
โโโโโโโโโโโโโโโโโโโโ
|
|
128
|
+
โ AI Agent โ
|
|
129
|
+
โ performTask() โ
|
|
130
|
+
โโโโโโโโโโฌโโโโโโโโโโ
|
|
131
|
+
โ HTTP POST
|
|
132
|
+
โโโโโโโโโโผโโโโโโโโโโ
|
|
133
|
+
โ OwsClient โ
|
|
134
|
+
โ (Axios + 402 โ
|
|
135
|
+
โ interceptor) โ
|
|
136
|
+
โโโฌโโโโโโโโโโโโโโโฌโโโ
|
|
137
|
+
โ โ
|
|
138
|
+
โโโโโโโโโโโโโโโโผโโโ โโโโโโโโโผโโโโโโโโโโโโ
|
|
139
|
+
โ PolicyEngine โ โ PaymentAdapter โ
|
|
140
|
+
โ โโโโโโโโโโโโโโ โ โ (interface) โ
|
|
141
|
+
โ โ Budget โ โ โ โ
|
|
142
|
+
โ โ Per-tx max โ โ โ โโโโโโโโโโโโโโโโ โ
|
|
143
|
+
โ โ Allowlist โ โ โ โ Base (viem) โ โ
|
|
144
|
+
โ โโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโค โ
|
|
145
|
+
โโโโโโโโโโโโโโโโโโโ โ โ Stellar โ โ
|
|
146
|
+
โ โโโโโโโโโโโโโโโโค โ
|
|
147
|
+
โ โ (Arbitrumโฆ) โ โ
|
|
148
|
+
โ โโโโโโโโโโโโโโโโ โ
|
|
149
|
+
โโโโโโโโโโโโโโโโโโโโโ
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
| Component | File | Purpose |
|
|
153
|
+
|-----------|------|---------|
|
|
154
|
+
| **OwsClient** | [`client.ts`](src/client.ts) | Chain-agnostic Axios wrapper with 402 interceptor |
|
|
155
|
+
| **PolicyEngine** | [`policy.ts`](src/policy.ts) | Fail-closed budget, per-tx limits, destination allowlist |
|
|
156
|
+
| **BasePaymentAdapter** | [`adapters/base.ts`](src/adapters/base.ts) | On-chain settlement via Base (Coinbase L2) using viem |
|
|
157
|
+
| **StellarPaymentAdapter** | [`adapters/stellar.ts`](src/adapters/stellar.ts) | On-chain settlement via Stellar network |
|
|
158
|
+
| **PaymentAdapter** | [`adapters/types.ts`](src/adapters/types.ts) | Generic interface โ plug in any chain (~40 lines) |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## ๐ OWS Spec Compliance
|
|
163
|
+
|
|
164
|
+
| OWS Section | Requirement | Implementation |
|
|
165
|
+
|-------------|-------------|----------------|
|
|
166
|
+
| **ยง03 Intercept** | Detect `402 Payment Required` | Axios response interceptor ([`client.ts:44`](src/client.ts#L44)) |
|
|
167
|
+
| **ยง04 Evaluate** | Validate `x402Version` + `accepts[]` | Envelope parser + PolicyEngine ([`policy.ts`](src/policy.ts)) |
|
|
168
|
+
| **ยง05 Settle** | Execute on-chain payment | BasePaymentAdapter / StellarPaymentAdapter |
|
|
169
|
+
| **ยง06 Prove** | Attach `X-PAYMENT` header | Base64-encoded proof with tx hash + CAIP-2 chain ID |
|
|
170
|
+
| **ยง07 Retry** | Resubmit original request | Axios re-request with proof header |
|
|
171
|
+
| **ยง08 Chains** | CAIP-2 chain identifiers | `eip155:8453` (Base), `eip155:84532` (Sepolia), `stellar:testnet` |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## ๐ Policy Engine (Fail-Closed)
|
|
176
|
+
|
|
177
|
+
Every payment **must** pass **all three** checks before execution:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const policy: BudgetPolicy = {
|
|
181
|
+
monthlyBudget: 50.0, // USD cap per calendar month
|
|
182
|
+
maxAmountPerTransaction: 5.0, // USD cap per single payment
|
|
183
|
+
allowedDestinations: [ // Whitelist of recipient addresses
|
|
184
|
+
'0xDead7101a13B2B6e2A4497706226bc3c4F',
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
โ Over budget โ **REJECTED**
|
|
190
|
+
โ Over per-tx limit โ **REJECTED**
|
|
191
|
+
โ Unknown destination โ **REJECTED**
|
|
192
|
+
โ
All checks pass โ **SETTLED**
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## โ๏ธ Supported Chains
|
|
197
|
+
|
|
198
|
+
| Chain | Adapter | CAIP-2 | Status |
|
|
199
|
+
|-------|---------|--------|--------|
|
|
200
|
+
| **Base** (Coinbase L2) | `BasePaymentAdapter` | `eip155:8453` | โ
Live |
|
|
201
|
+
| **Base Sepolia** | `BasePaymentAdapter` | `eip155:84532` | โ
Testnet |
|
|
202
|
+
| **Stellar** | `StellarPaymentAdapter` | `stellar:pubnet` | โ
Live |
|
|
203
|
+
| **Arbitrum** | `EvmPaymentAdapter` | `eip155:42161` | ๐ Next |
|
|
204
|
+
| **Solana** | `SolanaPaymentAdapter` | `solana:mainnet` | ๐ Planned |
|
|
205
|
+
| **Sui** | `SuiPaymentAdapter` | `sui:mainnet` | ๐ Planned |
|
|
206
|
+
|
|
207
|
+
> ๐ก **Any chain** can be added by implementing the `PaymentAdapter` interface (~40 lines).
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## ๐ Live Production Products
|
|
212
|
+
|
|
213
|
+
> **This is not a hackathon prototype.** Every product below is deployed and serving real traffic right now.
|
|
214
|
+
|
|
215
|
+
### ๐ Try them yourself
|
|
216
|
+
|
|
217
|
+
<table>
|
|
218
|
+
<tr>
|
|
219
|
+
<td width="33%" align="center">
|
|
220
|
+
|
|
221
|
+
### ๐ณ ASG Pay
|
|
222
|
+
**Universal Payment Gateway**
|
|
223
|
+
|
|
224
|
+
The AI agent payment infrastructure.
|
|
225
|
+
Accept fiat and crypto across 60+ chains.
|
|
226
|
+
|
|
227
|
+
**[โถ pay.asgcard.dev](https://pay.asgcard.dev)**
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npm install @asgcard/pay
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
</td>
|
|
234
|
+
<td width="33%" align="center">
|
|
235
|
+
|
|
236
|
+
### ๐ฐ ASG Fund
|
|
237
|
+
**Agent Wallet Funding**
|
|
238
|
+
|
|
239
|
+
Top up any AI agent's wallet with
|
|
240
|
+
USDC on Stellar โ via card, bank, or stablecoin.
|
|
241
|
+
|
|
242
|
+
**[โถ fund.asgcard.dev](https://fund.asgcard.dev)**
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
npm install @asgcard/fund
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
</td>
|
|
249
|
+
<td width="33%" align="center">
|
|
250
|
+
|
|
251
|
+
### ๐ ASG Card
|
|
252
|
+
**Virtual Cards for AI Agents**
|
|
253
|
+
|
|
254
|
+
Issue virtual debit cards on demand.
|
|
255
|
+
Pay via x402 or Stripe Machine Payments.
|
|
256
|
+
|
|
257
|
+
**[โถ asgcard.dev](https://asgcard.dev)**
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
npx @asgcard/cli
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
</td>
|
|
264
|
+
</tr>
|
|
265
|
+
</table>
|
|
266
|
+
|
|
267
|
+
### ๐ฆ NPM Packages
|
|
268
|
+
|
|
269
|
+
| Package | Install | Downloads | Description |
|
|
270
|
+
|---------|---------|-----------|-------------|
|
|
271
|
+
| **@asgcard/pay** | `npm i @asgcard/pay` | [](https://www.npmjs.com/package/@asgcard/pay) | Core payment SDK |
|
|
272
|
+
| **@asgcard/fund** | `npm i @asgcard/fund` | [](https://www.npmjs.com/package/@asgcard/fund) | Payment link generator CLI |
|
|
273
|
+
| **@asgcard/cli** | `npx @asgcard/cli` | [](https://www.npmjs.com/package/@asgcard/cli) | Virtual card issuing CLI |
|
|
274
|
+
|
|
275
|
+
### ๐ฎ Interactive Demos
|
|
276
|
+
|
|
277
|
+
| Demo | URL | What You'll See |
|
|
278
|
+
|------|-----|-----------------|
|
|
279
|
+
| **Browser Demo** | [โถ index.html](https://asgcompute.github.io/ASGCompute-ows-agent-pay/) | Full x402 cycle: 402 โ Policy โ Settlement โ Proof โ Result. Zero install. |
|
|
280
|
+
| **Ecosystem Demo** | [โถ ecosystem.html](https://asgcompute.github.io/ASGCompute-ows-agent-pay/ecosystem.html) | 3 interactive tabs: Fund Agent โ Issue Card โ x402 Pay โ each with live terminal. |
|
|
281
|
+
| **Fund Agent** | [โถ fund.asgcard.dev](https://fund.asgcard.dev) | Real agent wallet ($14.37 USDC + XLM on Stellar mainnet). |
|
|
282
|
+
| **Issue Card** | [โถ asgcard.dev](https://asgcard.dev) | Virtual debit card issuance for AI agents via x402 + Stripe. |
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## ๐ Hackathon Track Alignment
|
|
287
|
+
|
|
288
|
+
| Track | Alignment |
|
|
289
|
+
|-------|-----------|
|
|
290
|
+
| **๐ฐ Payments** | โญ Core โ x402 autonomous settlement on Base |
|
|
291
|
+
| **๐ค AI Agents** | โญ Core โ transparent payment layer for agents |
|
|
292
|
+
| **๐ Agent Spend Governance** | โญ Core โ PolicyEngine (fail-closed budget control) |
|
|
293
|
+
| **๐ Interoperability** | Multi-chain adapters via CAIP-2 |
|
|
294
|
+
| **๐๏ธ Infrastructure** | Production SDK + ASG Pay ecosystem |
|
|
295
|
+
|
|
296
|
+
### ๐ค Sponsor & Partner Alignment
|
|
297
|
+
|
|
298
|
+
<table>
|
|
299
|
+
<tr>
|
|
300
|
+
<td align="center" width="14%">
|
|
301
|
+
<a href="https://base.org">
|
|
302
|
+
<img src="https://img.shields.io/badge/Base-0052FF?style=for-the-badge&logo=coinbase&logoColor=white" alt="Base" />
|
|
303
|
+
</a>
|
|
304
|
+
<br><sub>Primary settlement<br/>Native x402 chain</sub>
|
|
305
|
+
</td>
|
|
306
|
+
<td align="center" width="14%">
|
|
307
|
+
<a href="https://circle.com">
|
|
308
|
+
<img src="https://img.shields.io/badge/Circle-00D632?style=for-the-badge&logoColor=white" alt="Circle" />
|
|
309
|
+
</a>
|
|
310
|
+
<br><sub>USDC settlement<br/>EVM + Stellar</sub>
|
|
311
|
+
</td>
|
|
312
|
+
<td align="center" width="14%">
|
|
313
|
+
<a href="https://stellar.org">
|
|
314
|
+
<img src="https://img.shields.io/badge/Stellar-7C3AED?style=for-the-badge" alt="Stellar" />
|
|
315
|
+
</a>
|
|
316
|
+
<br><sub>Production adapter<br/>Mainnet USDC</sub>
|
|
317
|
+
</td>
|
|
318
|
+
<td align="center" width="14%">
|
|
319
|
+
<a href="https://arbitrum.io">
|
|
320
|
+
<img src="https://img.shields.io/badge/Arbitrum-28A0F0?style=for-the-badge" alt="Arbitrum" />
|
|
321
|
+
</a>
|
|
322
|
+
<br><sub>EVM adapter<br/>Roadmap</sub>
|
|
323
|
+
</td>
|
|
324
|
+
<td align="center" width="14%">
|
|
325
|
+
<a href="https://stripe.com">
|
|
326
|
+
<img src="https://img.shields.io/badge/Stripe-635BFF?style=for-the-badge&logo=stripe&logoColor=white" alt="Stripe" />
|
|
327
|
+
</a>
|
|
328
|
+
<br><sub>Fiat settlement<br/>fund.asgcard.dev</sub>
|
|
329
|
+
</td>
|
|
330
|
+
<td align="center" width="14%">
|
|
331
|
+
<a href="https://li.fi">
|
|
332
|
+
<img src="https://img.shields.io/badge/LI.FI-EB46FF?style=for-the-badge" alt="Li.Fi" />
|
|
333
|
+
</a>
|
|
334
|
+
<br><sub>Cross-chain<br/>Aggregator</sub>
|
|
335
|
+
</td>
|
|
336
|
+
<td align="center" width="14%">
|
|
337
|
+
<a href="https://rozo.com">
|
|
338
|
+
<img src="https://img.shields.io/badge/ROZO-00BFFF?style=for-the-badge" alt="ROZO" />
|
|
339
|
+
</a>
|
|
340
|
+
<br><sub>Bridging<br/>Partner</sub>
|
|
341
|
+
</td>
|
|
342
|
+
</tr>
|
|
343
|
+
</table>
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## ๐ฃ๏ธ Roadmap
|
|
348
|
+
|
|
349
|
+
- [x] **OWS-compliant 402 interceptor** with policy engine
|
|
350
|
+
- [x] **Base adapter** (viem, Coinbase L2 โ native x402 chain)
|
|
351
|
+
- [x] **Stellar adapter** (production-proven via ASG Pay)
|
|
352
|
+
- [x] **Multi-chain adapter interface** (CAIP-2)
|
|
353
|
+
- [x] **Interactive browser demo** (GitHub Pages)
|
|
354
|
+
- [x] **Full ecosystem demo** (Fund โ Card โ Pay lifecycle)
|
|
355
|
+
- [ ] **Arbitrum / OP Stack** adapters
|
|
356
|
+
- [ ] **Solana adapter** (via @solana/web3.js)
|
|
357
|
+
- [ ] **Li.Fi integration** (cross-chain settlement aggregator)
|
|
358
|
+
- [ ] **MCP tool server** (A2A protocol bridge)
|
|
359
|
+
- [ ] **USDC (ERC-20)** transfer support on Base
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## ๐ Key Metrics
|
|
364
|
+
|
|
365
|
+
| Metric | Value |
|
|
366
|
+
|--------|-------|
|
|
367
|
+
| **NPM Downloads** | 10K+ monthly ([@asgcard](https://www.npmjs.com/org/asgcard)) |
|
|
368
|
+
| **SDK Size** | ~529 lines TypeScript |
|
|
369
|
+
| **Dependencies** | 3 (viem, axios, @stellar/stellar-sdk) |
|
|
370
|
+
| **Chains Live** | 2 (Base + Stellar) |
|
|
371
|
+
| **Products Live** | 3 (pay, fund, card) โ all in production |
|
|
372
|
+
| **OWS Compliance** | 6/6 specification sections |
|
|
373
|
+
| **License** | MIT |
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## ๐ License
|
|
378
|
+
|
|
379
|
+
MIT โ see [LICENSE](LICENSE) for details.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
<div align="center">
|
|
384
|
+
|
|
385
|
+
### Built with โค๏ธ by [ASG Compute](https://github.com/ASGCompute)
|
|
386
|
+
|
|
387
|
+
[pay.asgcard.dev](https://pay.asgcard.dev) โข [fund.asgcard.dev](https://fund.asgcard.dev) โข [asgcard.dev](https://asgcard.dev)
|
|
388
|
+
|
|
389
|
+
*Autonomous payments for autonomous agents.*
|
|
390
|
+
|
|
391
|
+
**[โถ Try the Live Demo](https://asgcompute.github.io/ASGCompute-ows-agent-pay/) โข [๐ฆ NPM](https://www.npmjs.com/org/asgcard) โข [๐ฆ Twitter](https://x.com/asgcard)**
|
|
392
|
+
|
|
393
|
+
</div>
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BasePaymentAdapter = void 0;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const accounts_1 = require("viem/accounts");
|
|
6
|
+
const chains_1 = require("viem/chains");
|
|
7
|
+
const logger_1 = require("../logger");
|
|
8
|
+
/** ERC-20 transfer ABI โ minimal, only what we need. */
|
|
9
|
+
const ERC20_TRANSFER_ABI = [
|
|
10
|
+
{
|
|
11
|
+
name: 'transfer',
|
|
12
|
+
type: 'function',
|
|
13
|
+
stateMutability: 'nonpayable',
|
|
14
|
+
inputs: [
|
|
15
|
+
{ name: 'to', type: 'address' },
|
|
16
|
+
{ name: 'amount', type: 'uint256' },
|
|
17
|
+
],
|
|
18
|
+
outputs: [{ name: '', type: 'bool' }],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'balanceOf',
|
|
22
|
+
type: 'function',
|
|
23
|
+
stateMutability: 'view',
|
|
24
|
+
inputs: [{ name: 'account', type: 'address' }],
|
|
25
|
+
outputs: [{ name: '', type: 'uint256' }],
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
/** Known USDC contract addresses on Base networks. */
|
|
29
|
+
const USDC_ADDRESSES = {
|
|
30
|
+
// Base Mainnet
|
|
31
|
+
8453: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
32
|
+
// Base Sepolia (Circle testnet USDC)
|
|
33
|
+
84532: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* BasePaymentAdapter โ On-chain settlement on Base (Coinbase L2).
|
|
37
|
+
*
|
|
38
|
+
* Supports both native ETH transfers and USDC (ERC-20) transfers.
|
|
39
|
+
* Uses viem for lightweight, type-safe EVM interactions.
|
|
40
|
+
*
|
|
41
|
+
* Networks:
|
|
42
|
+
* - Base Mainnet (eip155:8453) โ production
|
|
43
|
+
* - Base Sepolia (eip155:84532) โ testnet
|
|
44
|
+
*
|
|
45
|
+
* @see https://base.org
|
|
46
|
+
* @see https://x402.org
|
|
47
|
+
*/
|
|
48
|
+
class BasePaymentAdapter {
|
|
49
|
+
chainName = 'Base';
|
|
50
|
+
caip2Id;
|
|
51
|
+
wallet;
|
|
52
|
+
publicClient;
|
|
53
|
+
account;
|
|
54
|
+
chain;
|
|
55
|
+
asset;
|
|
56
|
+
log;
|
|
57
|
+
constructor(options = {}) {
|
|
58
|
+
const key = options.privateKey ?? (0, accounts_1.generatePrivateKey)();
|
|
59
|
+
this.account = (0, accounts_1.privateKeyToAccount)(key);
|
|
60
|
+
this.chain = options.network === 'mainnet' ? chains_1.base : chains_1.baseSepolia;
|
|
61
|
+
this.caip2Id = `eip155:${this.chain.id}`;
|
|
62
|
+
this.asset = options.asset ?? 'ETH';
|
|
63
|
+
this.log = options.logger ?? logger_1.noopLogger;
|
|
64
|
+
const transport = options.rpcUrl ? (0, viem_1.http)(options.rpcUrl) : (0, viem_1.http)();
|
|
65
|
+
this.wallet = (0, viem_1.createWalletClient)({
|
|
66
|
+
account: this.account,
|
|
67
|
+
chain: this.chain,
|
|
68
|
+
transport,
|
|
69
|
+
});
|
|
70
|
+
this.publicClient = (0, viem_1.createPublicClient)({
|
|
71
|
+
chain: this.chain,
|
|
72
|
+
transport,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
getAddress() {
|
|
76
|
+
return this.account.address;
|
|
77
|
+
}
|
|
78
|
+
/** Get native ETH balance (formatted). */
|
|
79
|
+
async getBalance() {
|
|
80
|
+
const balance = await this.publicClient.getBalance({
|
|
81
|
+
address: this.account.address,
|
|
82
|
+
});
|
|
83
|
+
return (0, viem_1.formatEther)(balance);
|
|
84
|
+
}
|
|
85
|
+
/** Get USDC balance (formatted, 6 decimals). */
|
|
86
|
+
async getUsdcBalance() {
|
|
87
|
+
const usdcAddress = USDC_ADDRESSES[this.chain.id];
|
|
88
|
+
if (!usdcAddress) {
|
|
89
|
+
return '0.00';
|
|
90
|
+
}
|
|
91
|
+
const balance = await this.publicClient.readContract({
|
|
92
|
+
address: usdcAddress,
|
|
93
|
+
abi: ERC20_TRANSFER_ABI,
|
|
94
|
+
functionName: 'balanceOf',
|
|
95
|
+
args: [this.account.address],
|
|
96
|
+
});
|
|
97
|
+
return (0, viem_1.formatUnits)(balance, 6);
|
|
98
|
+
}
|
|
99
|
+
async pay(destination, amount, network) {
|
|
100
|
+
if (this.asset === 'USDC') {
|
|
101
|
+
return this.payUsdc(destination, amount);
|
|
102
|
+
}
|
|
103
|
+
return this.payEth(destination, amount);
|
|
104
|
+
}
|
|
105
|
+
/** Execute a native ETH transfer. */
|
|
106
|
+
async payEth(destination, amount) {
|
|
107
|
+
try {
|
|
108
|
+
const amountWei = BigInt(amount);
|
|
109
|
+
const ethAmount = (0, viem_1.formatEther)(amountWei);
|
|
110
|
+
this.log(`[Base/ETH] ๐ ${ethAmount} ETH โ ${destination.slice(0, 8)}โฆ${destination.slice(-6)}`);
|
|
111
|
+
// Check balance
|
|
112
|
+
const balance = await this.publicClient.getBalance({
|
|
113
|
+
address: this.account.address,
|
|
114
|
+
});
|
|
115
|
+
if (balance < amountWei) {
|
|
116
|
+
this.log(`[Base/ETH] โ Insufficient: ${(0, viem_1.formatEther)(balance)} < ${ethAmount} ETH`);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const hash = await this.wallet.sendTransaction({
|
|
120
|
+
account: this.account,
|
|
121
|
+
to: destination,
|
|
122
|
+
value: amountWei,
|
|
123
|
+
chain: this.chain,
|
|
124
|
+
});
|
|
125
|
+
this.log(`[Base/ETH] โ
${hash}`);
|
|
126
|
+
return hash;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
this.log(`[Base/ETH] โ ${error.message}`);
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Execute a USDC ERC-20 transfer. */
|
|
134
|
+
async payUsdc(destination, amount) {
|
|
135
|
+
try {
|
|
136
|
+
const usdcAddress = USDC_ADDRESSES[this.chain.id];
|
|
137
|
+
if (!usdcAddress) {
|
|
138
|
+
this.log(`[Base/USDC] โ No USDC contract for chain ${this.chain.id}`);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const amountAtomic = BigInt(amount);
|
|
142
|
+
const usdcFormatted = (0, viem_1.formatUnits)(amountAtomic, 6);
|
|
143
|
+
this.log(`[Base/USDC] ๐ ${usdcFormatted} USDC โ ${destination.slice(0, 8)}โฆ${destination.slice(-6)}`);
|
|
144
|
+
// Check USDC balance
|
|
145
|
+
const balance = await this.publicClient.readContract({
|
|
146
|
+
address: usdcAddress,
|
|
147
|
+
abi: ERC20_TRANSFER_ABI,
|
|
148
|
+
functionName: 'balanceOf',
|
|
149
|
+
args: [this.account.address],
|
|
150
|
+
});
|
|
151
|
+
if (balance < amountAtomic) {
|
|
152
|
+
this.log(`[Base/USDC] โ Insufficient: ${(0, viem_1.formatUnits)(balance, 6)} < ${usdcFormatted} USDC`);
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
// Execute ERC-20 transfer
|
|
156
|
+
const hash = await this.wallet.writeContract({
|
|
157
|
+
address: usdcAddress,
|
|
158
|
+
abi: ERC20_TRANSFER_ABI,
|
|
159
|
+
functionName: 'transfer',
|
|
160
|
+
args: [destination, amountAtomic],
|
|
161
|
+
chain: this.chain,
|
|
162
|
+
account: this.account,
|
|
163
|
+
});
|
|
164
|
+
this.log(`[Base/USDC] โ
${hash}`);
|
|
165
|
+
return hash;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
this.log(`[Base/USDC] โ ${error.message}`);
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.BasePaymentAdapter = BasePaymentAdapter;
|
|
174
|
+
//# sourceMappingURL=base.js.map
|