@routedock/routedock 0.1.1 → 0.1.2
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/README.md +61 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,35 +1,33 @@
|
|
|
1
|
-
# @routedock/
|
|
1
|
+
# @routedock/routedock
|
|
2
2
|
|
|
3
3
|
Unified payment execution layer for autonomous agents on Stellar. One SDK for x402, MPP charge, and MPP session — mode selected automatically from the provider's `routedock.json` manifest.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @routedock/
|
|
9
|
-
# or
|
|
10
|
-
pnpm add @routedock/sdk
|
|
8
|
+
npm install @routedock/routedock
|
|
11
9
|
```
|
|
12
10
|
|
|
13
11
|
## Agent Usage
|
|
14
12
|
|
|
15
13
|
```ts
|
|
16
|
-
import { RouteDockClient } from '@routedock/
|
|
14
|
+
import { RouteDockClient } from '@routedock/routedock/client'
|
|
17
15
|
import { Keypair } from '@stellar/stellar-sdk'
|
|
18
16
|
|
|
19
17
|
const client = new RouteDockClient({
|
|
20
18
|
wallet: Keypair.fromSecret(process.env.AGENT_SECRET),
|
|
21
19
|
network: 'testnet',
|
|
22
|
-
spendCap: { daily: '1.00', asset: 'USDC' },
|
|
20
|
+
spendCap: { daily: '1.00', asset: 'USDC' },
|
|
23
21
|
})
|
|
24
22
|
|
|
25
23
|
// Single call — SDK reads manifest, picks mode automatically
|
|
26
|
-
const result = await client.pay('https://provider.
|
|
24
|
+
const result = await client.pay('https://provider.example.com/price')
|
|
27
25
|
// result.data — response body
|
|
28
26
|
// result.txHash — settlement hash (or null for session vouchers)
|
|
29
27
|
// result.mode — 'x402' | 'mpp-charge' | 'mpp-session'
|
|
30
28
|
|
|
31
29
|
// Sustained streaming access
|
|
32
|
-
const session = await client.openSession('https://provider.
|
|
30
|
+
const session = await client.openSession('https://provider.example.com/stream/orderbook')
|
|
33
31
|
for await (const update of session.stream()) {
|
|
34
32
|
console.log(update)
|
|
35
33
|
if (done) break
|
|
@@ -41,47 +39,88 @@ await session.close() // triggers on-chain settlement
|
|
|
41
39
|
|
|
42
40
|
```ts
|
|
43
41
|
import express from 'express'
|
|
44
|
-
import { routedock
|
|
45
|
-
import { createClient } from '@supabase/supabase-js'
|
|
42
|
+
import { routedock } from '@routedock/routedock/provider'
|
|
46
43
|
|
|
47
44
|
const app = express()
|
|
48
45
|
|
|
49
|
-
// Price endpoint — x402 + MPP charge
|
|
50
46
|
app.use('/price', routedock({
|
|
51
47
|
modes: ['x402', 'mpp-charge'],
|
|
52
48
|
pricing: { x402: '0.001', 'mpp-charge': '0.0008' },
|
|
53
49
|
asset: 'USDC',
|
|
50
|
+
assetContract: process.env.USDC_ASSET_CONTRACT,
|
|
54
51
|
payee: process.env.STELLAR_PAYEE_ADDRESS,
|
|
55
|
-
network:
|
|
56
|
-
|
|
52
|
+
network: 'testnet',
|
|
53
|
+
payeeSecretKey: process.env.STELLAR_PAYEE_SECRET,
|
|
54
|
+
manifest,
|
|
55
|
+
onSettled: async (txHash, amount, mode) => {
|
|
56
|
+
console.log(`settled: ${mode} ${amount} USDC — ${txHash}`)
|
|
57
|
+
},
|
|
57
58
|
}))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Session Lifecycle Hooks
|
|
62
|
+
|
|
63
|
+
For `mpp-session` mode, the middleware exposes three hooks that fire at each stage of the payment channel lifecycle:
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
app.use('/stream/orderbook', routedock({
|
|
65
|
+
```ts
|
|
66
|
+
app.use('/stream', routedock({
|
|
62
67
|
modes: ['mpp-session'],
|
|
63
|
-
pricing: { 'mpp-session': { rate: '0.0001', channelContract:
|
|
68
|
+
pricing: { 'mpp-session': { rate: '0.0001', channelContract: CHANNEL_CONTRACT } },
|
|
64
69
|
asset: 'USDC',
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
assetContract: USDC_ASSET_CONTRACT,
|
|
71
|
+
payee: PAYEE_ADDRESS,
|
|
72
|
+
network: 'testnet',
|
|
73
|
+
payeeSecretKey: PAYEE_SECRET,
|
|
74
|
+
manifest,
|
|
75
|
+
commitmentPublicKey: COMMITMENT_PUBLIC_KEY,
|
|
76
|
+
|
|
77
|
+
// Fires once when the first voucher is verified for a new session
|
|
78
|
+
onSessionOpen: async (channelId) => {
|
|
79
|
+
await db.from('sessions').insert({
|
|
80
|
+
channel_id: channelId,
|
|
81
|
+
status: 'open',
|
|
82
|
+
voucher_count: 0,
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// Fires after each verified ed25519 commitment (off-chain, no tx fee)
|
|
87
|
+
onVoucher: async (voucherIndex, cumulativeAmount) => {
|
|
88
|
+
await db.from('sessions').update({
|
|
89
|
+
voucher_count: voucherIndex,
|
|
90
|
+
cumulative_amount: parseFloat(cumulativeAmount),
|
|
91
|
+
}).eq('channel_id', channelId)
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// Fires after the on-chain channel close settles the cumulative amount
|
|
95
|
+
onSettled: async (txHash, totalPaid, mode) => {
|
|
96
|
+
await db.from('sessions').update({
|
|
97
|
+
status: 'closed',
|
|
98
|
+
settlement_tx_hash: txHash,
|
|
99
|
+
}).eq('channel_id', channelId)
|
|
100
|
+
},
|
|
68
101
|
}))
|
|
69
102
|
```
|
|
70
103
|
|
|
104
|
+
| Hook | When it fires | On-chain? |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `onSessionOpen(channelId)` | First verified voucher in a new session | No |
|
|
107
|
+
| `onVoucher(index, cumulativeAmount)` | Each verified ed25519 commitment | No |
|
|
108
|
+
| `onSettled(txHash, amount, mode)` | Channel close transaction confirmed | Yes |
|
|
109
|
+
|
|
71
110
|
## Mode Selection Logic
|
|
72
111
|
|
|
73
112
|
The `ModeRouter` uses this decision tree (deterministic, no randomness):
|
|
74
113
|
|
|
75
114
|
1. If `{ sustained: true }` passed AND manifest supports `mpp-session` → session
|
|
76
115
|
2. Else if manifest supports `mpp-charge` AND network is Stellar → MPP charge (lower fees)
|
|
77
|
-
3. Else if manifest supports `x402` → x402 with
|
|
116
|
+
3. Else if manifest supports `x402` → x402 with facilitator
|
|
78
117
|
4. Else throw `RouteDockNoSupportedModeError`
|
|
79
118
|
|
|
80
119
|
Override with `{ forceMode: 'x402' }` to bypass auto-selection.
|
|
81
120
|
|
|
82
121
|
## Security
|
|
83
122
|
|
|
84
|
-
The `one-way-channel` Soroban contract wrapped by `MppSessionClient` is **unaudited** (`stellar-experimental/one-way-channel`). Safe defaults are enforced: 17280 ledger refund window,
|
|
123
|
+
The `one-way-channel` Soroban contract wrapped by `MppSessionClient` is **unaudited** (`stellar-experimental/one-way-channel`). Safe defaults are enforced: 17280 ledger refund window, monotonic cumulative enforcement at application, database, and contract layers. Production mainnet use should await a formal audit.
|
|
85
124
|
|
|
86
125
|
## License
|
|
87
126
|
|