@routedock/routedock 0.1.2 → 0.3.0

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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +532 -4
  3. package/dist/MppSessionHandler-1EL8QBAn.d.cts +215 -0
  4. package/dist/MppSessionHandler-Bq4S-JTE.d.ts +215 -0
  5. package/dist/ProviderRegistry-CA_TdREG.d.ts +142 -0
  6. package/dist/ProviderRegistry-D-0rqK0N.d.cts +142 -0
  7. package/dist/RouteDockClient-Bh86bVly.d.ts +469 -0
  8. package/dist/RouteDockClient-go9aopfF.d.cts +469 -0
  9. package/dist/SessionReconciler-Bw-PoBVl.d.ts +134 -0
  10. package/dist/SessionReconciler-Cz2nuOlJ.d.cts +134 -0
  11. package/dist/SessionStore-B4-Hi4H8.d.cts +143 -0
  12. package/dist/SessionStore-BaYiegP0.d.ts +143 -0
  13. package/dist/client.cjs +2746 -217
  14. package/dist/client.d.cts +51 -81
  15. package/dist/client.d.ts +51 -81
  16. package/dist/client.js +2690 -218
  17. package/dist/index.cjs +3634 -420
  18. package/dist/index.d.cts +12 -3
  19. package/dist/index.d.ts +12 -3
  20. package/dist/index.js +3569 -419
  21. package/dist/logger-D8_Q2ytp.d.cts +467 -0
  22. package/dist/logger-D8_Q2ytp.d.ts +467 -0
  23. package/dist/provider/fastify.cjs +1099 -0
  24. package/dist/provider/fastify.d.cts +40 -0
  25. package/dist/provider/fastify.d.ts +40 -0
  26. package/dist/provider/fastify.js +1097 -0
  27. package/dist/provider/hono.cjs +1152 -0
  28. package/dist/provider/hono.d.cts +101 -0
  29. package/dist/provider/hono.d.ts +101 -0
  30. package/dist/provider/hono.js +1142 -0
  31. package/dist/provider.cjs +1105 -147
  32. package/dist/provider.d.cts +38 -27
  33. package/dist/provider.d.ts +38 -27
  34. package/dist/provider.js +1079 -148
  35. package/dist/react.cjs +2931 -0
  36. package/dist/react.d.cts +107 -0
  37. package/dist/react.d.ts +107 -0
  38. package/dist/react.js +2924 -0
  39. package/dist/routedockMiddleware-57gUaEMf.d.ts +64 -0
  40. package/dist/routedockMiddleware-DlyLrxp7.d.cts +64 -0
  41. package/dist/schema.cjs +404 -0
  42. package/dist/schema.d.cts +3 -0
  43. package/dist/schema.d.ts +3 -0
  44. package/dist/schema.js +399 -0
  45. package/dist/sign-AKH67sft.d.cts +53 -0
  46. package/dist/sign-BEq-OsSq.d.ts +53 -0
  47. package/dist/testing.cjs +59 -0
  48. package/dist/testing.d.cts +114 -0
  49. package/dist/testing.d.ts +114 -0
  50. package/dist/testing.js +56 -0
  51. package/package.json +143 -23
  52. package/PUBLISH_CHECKLIST.md +0 -70
  53. package/dist/SessionStore-CCVO0PHM.d.cts +0 -152
  54. package/dist/SessionStore-CCVO0PHM.d.ts +0 -152
  55. package/dist/routedockMiddleware-B7WTB3LT.d.cts +0 -53
  56. package/dist/routedockMiddleware-DRgdrycG.d.ts +0 -53
  57. package/src/client/ModeRouter.ts +0 -104
  58. package/src/client/MppChargeClient.ts +0 -44
  59. package/src/client/MppSessionClient.ts +0 -144
  60. package/src/client/RouteDockClient.ts +0 -124
  61. package/src/client/index.ts +0 -8
  62. package/src/client/x402Client.ts +0 -84
  63. package/src/index.ts +0 -9
  64. package/src/provider/MppChargeHandler.ts +0 -90
  65. package/src/provider/MppSessionHandler.ts +0 -157
  66. package/src/provider/index.ts +0 -7
  67. package/src/provider/routedockMiddleware.ts +0 -154
  68. package/src/provider/x402Handler.ts +0 -164
  69. package/src/schemas/routedock.schema.json +0 -159
  70. package/src/store/SessionStore.ts +0 -90
  71. package/src/tests/smoke.test.ts +0 -228
  72. package/src/types.ts +0 -165
  73. package/tsconfig.json +0 -14
  74. package/tsup.config.ts +0 -15
@@ -1,159 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://routedock.dev/schemas/routedock.schema.json",
4
- "title": "RouteDock Manifest",
5
- "description": "Discovery manifest served at /.well-known/routedock.json on every RouteDock provider endpoint",
6
- "type": "object",
7
- "required": [
8
- "routedock",
9
- "name",
10
- "description",
11
- "modes",
12
- "network",
13
- "asset",
14
- "asset_contract",
15
- "payee",
16
- "pricing",
17
- "endpoints",
18
- "tags"
19
- ],
20
- "additionalProperties": false,
21
- "properties": {
22
- "routedock": {
23
- "type": "string",
24
- "const": "1.0",
25
- "description": "Manifest schema version. Always '1.0' for this version."
26
- },
27
- "name": {
28
- "type": "string",
29
- "minLength": 1,
30
- "maxLength": 120,
31
- "description": "Human-readable provider name"
32
- },
33
- "description": {
34
- "type": "string",
35
- "minLength": 1,
36
- "maxLength": 500,
37
- "description": "Human-readable description of the provider's data or service"
38
- },
39
- "modes": {
40
- "type": "array",
41
- "minItems": 1,
42
- "uniqueItems": true,
43
- "items": {
44
- "$ref": "#/definitions/PaymentMode"
45
- },
46
- "description": "Payment modes supported by this provider"
47
- },
48
- "network": {
49
- "type": "string",
50
- "enum": ["testnet", "mainnet"],
51
- "description": "Stellar network this provider operates on"
52
- },
53
- "asset": {
54
- "type": "string",
55
- "description": "Asset ticker symbol (e.g. 'USDC')"
56
- },
57
- "asset_contract": {
58
- "type": "string",
59
- "description": "Stellar Asset Contract (SAC) address for the payment asset"
60
- },
61
- "payee": {
62
- "type": "string",
63
- "description": "Stellar address (G...) that receives payments"
64
- },
65
- "pricing": {
66
- "type": "object",
67
- "description": "Pricing configuration per supported payment mode",
68
- "additionalProperties": false,
69
- "properties": {
70
- "x402": {
71
- "$ref": "#/definitions/PricingConfig"
72
- },
73
- "mpp-charge": {
74
- "$ref": "#/definitions/PricingConfig"
75
- },
76
- "mpp-session": {
77
- "$ref": "#/definitions/SessionPricingConfig"
78
- }
79
- },
80
- "minProperties": 1
81
- },
82
- "endpoints": {
83
- "type": "object",
84
- "description": "Map of endpoint name to HTTP method + path (e.g. { 'price': 'GET /price' })",
85
- "additionalProperties": {
86
- "type": "string"
87
- },
88
- "minProperties": 1
89
- },
90
- "tags": {
91
- "type": "array",
92
- "items": {
93
- "type": "string",
94
- "minLength": 1,
95
- "maxLength": 64
96
- },
97
- "uniqueItems": true,
98
- "description": "Capability tags indexed with trigram search in the provider registry"
99
- }
100
- },
101
- "definitions": {
102
- "PaymentMode": {
103
- "type": "string",
104
- "enum": ["x402", "mpp-charge", "mpp-session"],
105
- "description": "A supported RouteDock payment mode"
106
- },
107
- "PricingConfig": {
108
- "type": "object",
109
- "description": "Per-request pricing for x402 or mpp-charge modes",
110
- "required": ["amount", "per"],
111
- "additionalProperties": false,
112
- "properties": {
113
- "amount": {
114
- "type": "string",
115
- "description": "Cost per request in the payment asset (decimal string, e.g. '0.001')"
116
- },
117
- "per": {
118
- "type": "string",
119
- "const": "request",
120
- "description": "Billing unit — always 'request' for non-session modes"
121
- },
122
- "facilitator": {
123
- "type": "string",
124
- "description": "x402 facilitator URL (required for x402 mode). OpenZeppelin Channels endpoint."
125
- }
126
- }
127
- },
128
- "SessionPricingConfig": {
129
- "type": "object",
130
- "description": "Per-voucher pricing for mpp-session (one-way-channel) mode",
131
- "required": ["rate", "per", "channel_contract", "min_deposit", "refund_waiting_period_ledgers"],
132
- "additionalProperties": false,
133
- "properties": {
134
- "rate": {
135
- "type": "string",
136
- "description": "Cost per voucher in the payment asset (decimal string, e.g. '0.0001')"
137
- },
138
- "per": {
139
- "type": "string",
140
- "const": "voucher",
141
- "description": "Billing unit — always 'voucher' for session mode"
142
- },
143
- "channel_contract": {
144
- "type": "string",
145
- "description": "Soroban contract address (C...) for the one-way-channel contract"
146
- },
147
- "min_deposit": {
148
- "type": "string",
149
- "description": "Minimum initial deposit to open a channel (decimal string)"
150
- },
151
- "refund_waiting_period_ledgers": {
152
- "type": "integer",
153
- "minimum": 1,
154
- "description": "Ledgers the server has to settle before the funder can reclaim. Default: 17280 (~24h). Do not reduce in production."
155
- }
156
- }
157
- }
158
- }
159
- }
@@ -1,90 +0,0 @@
1
- import type { SupabaseClient } from '@supabase/supabase-js'
2
- import type { SessionState } from '../types.js'
3
- import { RouteDockSessionError } from '../types.js'
4
-
5
- // ── Interface ──────────────────────────────────────────────────────────────────
6
-
7
- export interface SessionStore {
8
- get(channelId: string): Promise<SessionState | null>
9
- /** Enforce monotonic invariant at application level before writing */
10
- upsert(channelId: string, state: SessionState): Promise<void>
11
- close(channelId: string): Promise<void>
12
- }
13
-
14
- // ── Supabase implementation ────────────────────────────────────────────────────
15
-
16
- export class SupabaseSessionStore implements SessionStore {
17
- constructor(private readonly supabase: SupabaseClient) {}
18
-
19
- async get(channelId: string): Promise<SessionState | null> {
20
- const { data, error } = await this.supabase
21
- .from('sessions')
22
- .select('*')
23
- .eq('channel_id', channelId)
24
- .maybeSingle()
25
-
26
- if (error) throw new RouteDockSessionError(`SessionStore.get failed: ${error.message}`)
27
- if (!data) return null
28
-
29
- return {
30
- channel_id: data.channel_id as string,
31
- payee: data.payee as string,
32
- payer: data.payer as string,
33
- cumulative_amount: String(data.cumulative_amount),
34
- last_signature: data.last_signature as string,
35
- status: data.status as SessionState['status'],
36
- opened_at: data.opened_at as string,
37
- updated_at: data.updated_at as string,
38
- settlement_tx_hash: data.settlement_tx_hash as string | null,
39
- }
40
- }
41
-
42
- async upsert(channelId: string, state: SessionState): Promise<void> {
43
- // Application-level monotonic invariant check — catches non-increasing
44
- // amounts before hitting the DB trigger, giving a typed error.
45
- const existing = await this.get(channelId)
46
- if (existing) {
47
- const prev = parseFloat(existing.cumulative_amount)
48
- const next = parseFloat(state.cumulative_amount)
49
- if (next <= prev) {
50
- throw new RouteDockSessionError(
51
- `cumulative_amount must be strictly increasing: ${next} <= ${prev}`,
52
- )
53
- }
54
- }
55
-
56
- const { error } = await this.supabase.from('sessions').upsert(
57
- {
58
- channel_id: state.channel_id,
59
- payee: state.payee,
60
- payer: state.payer,
61
- cumulative_amount: state.cumulative_amount,
62
- last_signature: state.last_signature,
63
- status: state.status,
64
- opened_at: state.opened_at,
65
- updated_at: new Date().toISOString(),
66
- settlement_tx_hash: state.settlement_tx_hash,
67
- },
68
- { onConflict: 'channel_id' },
69
- )
70
-
71
- if (error) {
72
- // DB trigger will raise 'cumulative_amount must be strictly increasing'
73
- if (error.message.includes('strictly increasing')) {
74
- throw new RouteDockSessionError(
75
- `cumulative_amount must be strictly increasing (DB): ${error.message}`,
76
- )
77
- }
78
- throw new RouteDockSessionError(`SessionStore.upsert failed: ${error.message}`)
79
- }
80
- }
81
-
82
- async close(channelId: string): Promise<void> {
83
- const { error } = await this.supabase
84
- .from('sessions')
85
- .update({ status: 'closed', updated_at: new Date().toISOString() })
86
- .eq('channel_id', channelId)
87
-
88
- if (error) throw new RouteDockSessionError(`SessionStore.close failed: ${error.message}`)
89
- }
90
- }
@@ -1,228 +0,0 @@
1
- /**
2
- * Integration smoke tests for @routedock/sdk.
3
- *
4
- * These tests run against actual package imports to verify:
5
- * 1. x402 flow against a local mock server (402 → payment → 200)
6
- * 2. ModeRouter manifest fetch + validation
7
- * 3. SessionStore monotonic invariant rejection
8
- *
9
- * Run with: pnpm --filter @routedock/sdk test
10
- * No testnet RPC calls are made — all network calls are mocked via fetch interception.
11
- */
12
-
13
- import * as http from 'node:http'
14
- import { createServer } from 'node:http'
15
- import type { IncomingMessage, ServerResponse } from 'node:http'
16
- import assert from 'node:assert/strict'
17
-
18
- // ── Helpers ───────────────────────────────────────────────────────────────────
19
-
20
- function startTestServer(
21
- handler: (req: IncomingMessage, res: ServerResponse) => void,
22
- ): Promise<{ url: string; close: () => Promise<void> }> {
23
- return new Promise((resolve) => {
24
- const server = createServer(handler)
25
- server.listen(0, '127.0.0.1', () => {
26
- const addr = server.address() as { port: number }
27
- resolve({
28
- url: `http://127.0.0.1:${addr.port}`,
29
- close: () => new Promise<void>((res) => server.close(() => res())),
30
- })
31
- })
32
- })
33
- }
34
-
35
- // ── Test 1: ModeRouter — manifest fetch + schema validation ───────────────────
36
-
37
- {
38
- const validManifest = {
39
- routedock: '1.0',
40
- name: 'Test Provider',
41
- description: 'Smoke test provider',
42
- modes: ['x402', 'mpp-charge'],
43
- network: 'testnet',
44
- asset: 'USDC',
45
- asset_contract: 'CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA',
46
- payee: 'GDHLJWBM6Z2Y4KF6Z4JAFIUUO2KAXAJ6MAIUK2XMGBQ7ZUUZ7HFPW2BK',
47
- pricing: {
48
- x402: { amount: '0.001', per: 'request', facilitator: 'https://channels.openzeppelin.com/x402/testnet' },
49
- 'mpp-charge': { amount: '0.0008', per: 'request' },
50
- },
51
- endpoints: { price: 'GET /price' },
52
- tags: ['price', 'stellar'],
53
- }
54
-
55
- const server = await startTestServer((req, res) => {
56
- if (req.url === '/.well-known/routedock.json') {
57
- res.writeHead(200, { 'Content-Type': 'application/json' })
58
- res.end(JSON.stringify(validManifest))
59
- } else {
60
- res.writeHead(404)
61
- res.end()
62
- }
63
- })
64
-
65
- try {
66
- const { fetchManifest, selectMode } = await import('../client/ModeRouter.js')
67
-
68
- const manifest = await fetchManifest(server.url)
69
- assert.equal(manifest.routedock, '1.0', 'manifest version should be 1.0')
70
- assert.equal(manifest.name, 'Test Provider', 'manifest name should match')
71
- assert.ok(manifest.modes.includes('x402'), 'manifest should include x402 mode')
72
-
73
- // Second fetch should be cached
74
- const cached = await fetchManifest(server.url)
75
- assert.equal(cached, manifest, 'second fetch should return cached manifest')
76
-
77
- // Mode selection
78
- const mode = selectMode(manifest)
79
- assert.equal(mode, 'mpp-charge', 'mpp-charge should be preferred over x402')
80
-
81
- const modeForced = selectMode(manifest, { sustained: true })
82
- assert.equal(modeForced, 'mpp-charge', 'sustained without mpp-session falls back to mpp-charge')
83
-
84
- console.log('✓ Test 1: ModeRouter manifest fetch + validation PASSED')
85
- } finally {
86
- await server.close()
87
- }
88
- }
89
-
90
- // ── Test 2: ModeRouter — invalid manifest rejected ────────────────────────────
91
-
92
- {
93
- const badManifest = { routedock: '2.0', name: 'bad' }
94
-
95
- const server = await startTestServer((req, res) => {
96
- res.writeHead(200, { 'Content-Type': 'application/json' })
97
- res.end(JSON.stringify(badManifest))
98
- })
99
-
100
- try {
101
- const { fetchManifest } = await import('../client/ModeRouter.js')
102
- const { RouteDockManifestError: ManifestError } = await import('../types.js')
103
-
104
- let threw = false
105
- try {
106
- await fetchManifest(server.url + '/bad-url')
107
- } catch (err) {
108
- threw = true
109
- assert.ok(
110
- err instanceof ManifestError,
111
- `should throw RouteDockManifestError, got ${String(err)}`,
112
- )
113
- }
114
- assert.ok(threw, 'should have thrown for invalid manifest')
115
-
116
- console.log('✓ Test 2: Invalid manifest rejection PASSED')
117
- } finally {
118
- await server.close()
119
- }
120
- }
121
-
122
- // ── Test 3: SessionStore — monotonic invariant rejection ─────────────────────
123
-
124
- {
125
- // Use an in-memory store implementation to test monotonic invariant
126
- // without a real Supabase connection.
127
-
128
- const { RouteDockSessionError } = await import('../types.js')
129
-
130
- // Build a minimal in-memory SessionStore-compatible implementation
131
- const sessions = new Map<string, import('../types.js').SessionState>()
132
- const memStore = {
133
- async get(channelId: string) {
134
- return sessions.get(channelId) ?? null
135
- },
136
- async upsert(channelId: string, state: import('../types.js').SessionState) {
137
- const existing = sessions.get(channelId)
138
- if (existing) {
139
- const prev = parseFloat(existing.cumulative_amount)
140
- const next = parseFloat(state.cumulative_amount)
141
- if (next <= prev) {
142
- throw new RouteDockSessionError(
143
- `cumulative_amount must be strictly increasing: ${next} <= ${prev}`,
144
- )
145
- }
146
- }
147
- sessions.set(channelId, { ...state })
148
- },
149
- async close(channelId: string) {
150
- const s = sessions.get(channelId)
151
- if (s) sessions.set(channelId, { ...s, status: 'closed' })
152
- },
153
- }
154
-
155
- const baseState: import('../types.js').SessionState = {
156
- channel_id: 'test-channel-1',
157
- payee: 'GPAYEE',
158
- payer: 'GPAYER',
159
- cumulative_amount: '0.0010000',
160
- last_signature: 'sig1',
161
- status: 'open',
162
- opened_at: new Date().toISOString(),
163
- updated_at: new Date().toISOString(),
164
- settlement_tx_hash: null,
165
- }
166
-
167
- // First upsert — should succeed
168
- await memStore.upsert('test-channel-1', baseState)
169
-
170
- // Second upsert with higher amount — should succeed
171
- await memStore.upsert('test-channel-1', { ...baseState, cumulative_amount: '0.0020000' })
172
-
173
- // Third upsert with same amount — should throw
174
- let threw = false
175
- try {
176
- await memStore.upsert('test-channel-1', { ...baseState, cumulative_amount: '0.0020000' })
177
- } catch (err) {
178
- threw = true
179
- assert.ok(
180
- err instanceof RouteDockSessionError,
181
- `should throw RouteDockSessionError, got ${String(err)}`,
182
- )
183
- }
184
- assert.ok(threw, 'equal cumulative amount should be rejected')
185
-
186
- // Upsert with lower amount — should also throw
187
- threw = false
188
- try {
189
- await memStore.upsert('test-channel-1', { ...baseState, cumulative_amount: '0.0010000' })
190
- } catch (err) {
191
- threw = true
192
- assert.ok(err instanceof RouteDockSessionError)
193
- }
194
- assert.ok(threw, 'lower cumulative amount should be rejected')
195
-
196
- console.log('✓ Test 3: SessionStore monotonic invariant rejection PASSED')
197
- }
198
-
199
- // ── Test 4: Error subclass hierarchy ─────────────────────────────────────────
200
-
201
- {
202
- const {
203
- RouteDockError,
204
- RouteDockManifestError,
205
- RouteDockNoSupportedModeError,
206
- RouteDockSessionError,
207
- RouteDockPolicyRejectedError,
208
- } = await import('../types.js')
209
-
210
- const errors = [
211
- new RouteDockManifestError('test'),
212
- new RouteDockNoSupportedModeError('test'),
213
- new RouteDockSessionError('test'),
214
- new RouteDockPolicyRejectedError('test'),
215
- ]
216
-
217
- for (const err of errors) {
218
- assert.ok(err instanceof RouteDockError, `${err.name} should be instance of RouteDockError`)
219
- assert.ok(err instanceof Error, `${err.name} should be instance of Error`)
220
- }
221
-
222
- const policyErr = new RouteDockPolicyRejectedError('local_daily_cap_exceeded')
223
- assert.equal(policyErr.reason, 'local_daily_cap_exceeded')
224
-
225
- console.log('✓ Test 4: Error subclass hierarchy PASSED')
226
- }
227
-
228
- console.log('\nAll smoke tests passed.')
package/src/types.ts DELETED
@@ -1,165 +0,0 @@
1
- /**
2
- * TypeScript types for the RouteDock manifest format.
3
- * Derived from packages/sdk/src/schemas/routedock.schema.json (draft-07).
4
- *
5
- * Section 5 of ROUTEDOCK_MASTER.md is the canonical specification.
6
- */
7
-
8
- export type PaymentMode = 'x402' | 'mpp-charge' | 'mpp-session'
9
-
10
- /** Per-request pricing config — used by x402 and mpp-charge modes */
11
- export interface PricingConfig {
12
- /** Cost per request in the payment asset, e.g. "0.001" */
13
- amount: string
14
- per: 'request'
15
- /** x402 facilitator URL (OpenZeppelin Channels). Required for x402 mode. */
16
- facilitator?: string
17
- }
18
-
19
- /** Per-voucher pricing config — used by mpp-session (one-way-channel) mode */
20
- export interface SessionPricingConfig {
21
- /** Cost per voucher, e.g. "0.0001" */
22
- rate: string
23
- per: 'voucher'
24
- /** Soroban contract address (C...) for the one-way-channel contract */
25
- channel_contract: string
26
- /** Minimum initial deposit to open a channel, e.g. "0.10" */
27
- min_deposit: string
28
- /**
29
- * Ledgers the server has to settle before the funder can reclaim.
30
- * Default: 17280 (~24h). Do NOT reduce in production — this is a
31
- * security parameter the server depends on to settle first.
32
- */
33
- refund_waiting_period_ledgers: number
34
- }
35
-
36
- /** Full RouteDock discovery manifest — served at /.well-known/routedock.json */
37
- export interface RouteDockManifest {
38
- /** Schema version — always "1.0" */
39
- routedock: '1.0'
40
- /** Human-readable provider name */
41
- name: string
42
- /** Human-readable description of the provider's data or service */
43
- description: string
44
- /** Payment modes supported by this provider */
45
- modes: PaymentMode[]
46
- /** Stellar network this provider operates on */
47
- network: 'testnet' | 'mainnet'
48
- /** Asset ticker symbol, e.g. "USDC" */
49
- asset: string
50
- /** Stellar Asset Contract (SAC) address for the payment asset */
51
- asset_contract: string
52
- /** Stellar address (G...) that receives payments */
53
- payee: string
54
- /** Pricing configuration per supported payment mode */
55
- pricing: {
56
- x402?: PricingConfig
57
- 'mpp-charge'?: PricingConfig
58
- 'mpp-session'?: SessionPricingConfig
59
- }
60
- /** Map of endpoint name to HTTP method + path, e.g. { price: "GET /price" } */
61
- endpoints: Record<string, string>
62
- /** Capability tags indexed with trigram search in the provider registry */
63
- tags: string[]
64
- }
65
-
66
- /** Result returned by client.pay() for any payment mode */
67
- export interface PaymentResult {
68
- /** Parsed response body from the provider */
69
- data: unknown
70
- /** On-chain Stellar transaction hash, or null for session voucher calls */
71
- txHash: string | null
72
- /** Payment mode that was used for this call */
73
- mode: PaymentMode
74
- /** Amount paid in the payment asset (decimal string) */
75
- amount: string
76
- /** Unix timestamp (ms) when the payment completed */
77
- timestamp: number
78
- }
79
-
80
- /** Result returned by session.close() */
81
- export interface SessionCloseResult {
82
- /** On-chain transaction hash for the channel close */
83
- closeTxHash: string
84
- /** Total amount settled across all vouchers (decimal string) */
85
- totalPaid: string
86
- /** Number of vouchers issued during the session */
87
- vouchersIssued: number
88
- }
89
-
90
- /** Handle for a live MPP session returned by client.openSession() */
91
- export interface SessionHandle {
92
- /** Stellar channel contract address (C...) */
93
- channelId: string
94
- /** Transaction hash from the channel-open on-chain call */
95
- openTxHash: string
96
- /**
97
- * Async generator of server-sent event data.
98
- * Each iteration sends a voucher and yields the parsed response.
99
- * UNAUDITED: uses stellar-experimental/one-way-channel contract.
100
- */
101
- stream(): AsyncIterable<unknown>
102
- /** Close the channel on-chain with the highest signed voucher */
103
- close(): Promise<SessionCloseResult>
104
- }
105
-
106
- /**
107
- * Durable session state stored in Supabase (sessions table).
108
- * cumulative_amount is a decimal string to avoid float precision loss.
109
- * The monotonic invariant is enforced both here and at the DB level via trigger.
110
- */
111
- export interface SessionState {
112
- channel_id: string
113
- payee: string
114
- payer: string
115
- /** Monotonically increasing cumulative amount — stored as string to preserve precision */
116
- cumulative_amount: string
117
- last_signature: string
118
- status: 'open' | 'closing' | 'closed'
119
- opened_at: string
120
- updated_at: string
121
- settlement_tx_hash: string | null
122
- }
123
-
124
- // ── Error hierarchy ────────────────────────────────────────────────────────────
125
-
126
- export class RouteDockError extends Error {
127
- constructor(message: string) {
128
- super(message)
129
- this.name = 'RouteDockError'
130
- }
131
- }
132
-
133
- /** Manifest fetch failed, schema invalid, or required fields missing */
134
- export class RouteDockManifestError extends RouteDockError {
135
- constructor(message: string) {
136
- super(message)
137
- this.name = 'RouteDockManifestError'
138
- }
139
- }
140
-
141
- /** No payment mode in the manifest is supported by this client */
142
- export class RouteDockNoSupportedModeError extends RouteDockError {
143
- constructor(message: string) {
144
- super(message)
145
- this.name = 'RouteDockNoSupportedModeError'
146
- }
147
- }
148
-
149
- /** Session invariant violated (e.g. non-monotonic voucher amount) */
150
- export class RouteDockSessionError extends RouteDockError {
151
- constructor(message: string) {
152
- super(message)
153
- this.name = 'RouteDockSessionError'
154
- }
155
- }
156
-
157
- /** Local spend cap or on-chain policy rejected the payment */
158
- export class RouteDockPolicyRejectedError extends RouteDockError {
159
- readonly reason: string
160
- constructor(reason: string) {
161
- super(`Payment rejected by policy: ${reason}`)
162
- this.name = 'RouteDockPolicyRejectedError'
163
- this.reason = reason
164
- }
165
- }
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src",
6
- "module": "ESNext",
7
- "moduleResolution": "bundler",
8
- "resolveJsonModule": true,
9
- "allowImportingTsExtensions": false,
10
- "lib": ["ES2022"],
11
- "target": "ES2022"
12
- },
13
- "include": ["src/**/*"]
14
- }
package/tsup.config.ts DELETED
@@ -1,15 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
-
3
- export default defineConfig({
4
- entry: {
5
- index: 'src/index.ts',
6
- client: 'src/client/index.ts',
7
- provider: 'src/provider/index.ts',
8
- },
9
- format: ['cjs', 'esm'],
10
- dts: true,
11
- clean: true,
12
- splitting: false,
13
- sourcemap: false,
14
- treeshake: true,
15
- })