@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.
- package/LICENSE +21 -0
- package/README.md +532 -4
- package/dist/MppSessionHandler-1EL8QBAn.d.cts +215 -0
- package/dist/MppSessionHandler-Bq4S-JTE.d.ts +215 -0
- package/dist/ProviderRegistry-CA_TdREG.d.ts +142 -0
- package/dist/ProviderRegistry-D-0rqK0N.d.cts +142 -0
- package/dist/RouteDockClient-Bh86bVly.d.ts +469 -0
- package/dist/RouteDockClient-go9aopfF.d.cts +469 -0
- package/dist/SessionReconciler-Bw-PoBVl.d.ts +134 -0
- package/dist/SessionReconciler-Cz2nuOlJ.d.cts +134 -0
- package/dist/SessionStore-B4-Hi4H8.d.cts +143 -0
- package/dist/SessionStore-BaYiegP0.d.ts +143 -0
- package/dist/client.cjs +2746 -217
- package/dist/client.d.cts +51 -81
- package/dist/client.d.ts +51 -81
- package/dist/client.js +2690 -218
- package/dist/index.cjs +3634 -420
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +3569 -419
- package/dist/logger-D8_Q2ytp.d.cts +467 -0
- package/dist/logger-D8_Q2ytp.d.ts +467 -0
- package/dist/provider/fastify.cjs +1099 -0
- package/dist/provider/fastify.d.cts +40 -0
- package/dist/provider/fastify.d.ts +40 -0
- package/dist/provider/fastify.js +1097 -0
- package/dist/provider/hono.cjs +1152 -0
- package/dist/provider/hono.d.cts +101 -0
- package/dist/provider/hono.d.ts +101 -0
- package/dist/provider/hono.js +1142 -0
- package/dist/provider.cjs +1105 -147
- package/dist/provider.d.cts +38 -27
- package/dist/provider.d.ts +38 -27
- package/dist/provider.js +1079 -148
- package/dist/react.cjs +2931 -0
- package/dist/react.d.cts +107 -0
- package/dist/react.d.ts +107 -0
- package/dist/react.js +2924 -0
- package/dist/routedockMiddleware-57gUaEMf.d.ts +64 -0
- package/dist/routedockMiddleware-DlyLrxp7.d.cts +64 -0
- package/dist/schema.cjs +404 -0
- package/dist/schema.d.cts +3 -0
- package/dist/schema.d.ts +3 -0
- package/dist/schema.js +399 -0
- package/dist/sign-AKH67sft.d.cts +53 -0
- package/dist/sign-BEq-OsSq.d.ts +53 -0
- package/dist/testing.cjs +59 -0
- package/dist/testing.d.cts +114 -0
- package/dist/testing.d.ts +114 -0
- package/dist/testing.js +56 -0
- package/package.json +143 -23
- package/PUBLISH_CHECKLIST.md +0 -70
- package/dist/SessionStore-CCVO0PHM.d.cts +0 -152
- package/dist/SessionStore-CCVO0PHM.d.ts +0 -152
- package/dist/routedockMiddleware-B7WTB3LT.d.cts +0 -53
- package/dist/routedockMiddleware-DRgdrycG.d.ts +0 -53
- package/src/client/ModeRouter.ts +0 -104
- package/src/client/MppChargeClient.ts +0 -44
- package/src/client/MppSessionClient.ts +0 -144
- package/src/client/RouteDockClient.ts +0 -124
- package/src/client/index.ts +0 -8
- package/src/client/x402Client.ts +0 -84
- package/src/index.ts +0 -9
- package/src/provider/MppChargeHandler.ts +0 -90
- package/src/provider/MppSessionHandler.ts +0 -157
- package/src/provider/index.ts +0 -7
- package/src/provider/routedockMiddleware.ts +0 -154
- package/src/provider/x402Handler.ts +0 -164
- package/src/schemas/routedock.schema.json +0 -159
- package/src/store/SessionStore.ts +0 -90
- package/src/tests/smoke.test.ts +0 -228
- package/src/types.ts +0 -165
- package/tsconfig.json +0 -14
- package/tsup.config.ts +0 -15
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { RequestHandler } from 'express';
|
|
2
|
+
import { P as PaymentMode } from './logger-D8_Q2ytp.js';
|
|
3
|
+
import { R as RouteDockMiddlewareOptions } from './routedockMiddleware-57gUaEMf.js';
|
|
4
|
+
import 'mppx';
|
|
5
|
+
import './MppSessionHandler-Bq4S-JTE.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Loosen a production callback's return type so a plain sync test spy works,
|
|
9
|
+
* while keeping its exact parameter list (the real adapter's signature).
|
|
10
|
+
*/
|
|
11
|
+
type TestCallback<F> = F extends (...args: infer A) => unknown ? (...args: A) => void | Promise<void> : never;
|
|
12
|
+
/**
|
|
13
|
+
* Provider settlement callbacks under test. Same parameter list as the real
|
|
14
|
+
* `RouteDockMiddlewareOptions` callbacks — including `payer` — but they accept
|
|
15
|
+
* sync or async fns so a plain test spy works without wrapping it in a Promise.
|
|
16
|
+
*/
|
|
17
|
+
interface MockRoutedockCallbacks {
|
|
18
|
+
/** Called after each (synthetic) on-chain settlement. */
|
|
19
|
+
onSettled?: TestCallback<NonNullable<RouteDockMiddlewareOptions['onSettled']>>;
|
|
20
|
+
/** Called once when a synthetic session is opened (first voucher). */
|
|
21
|
+
onSessionOpen?: TestCallback<NonNullable<RouteDockMiddlewareOptions['onSessionOpen']>>;
|
|
22
|
+
/** Called for each synthetic voucher in a session (1-based index). */
|
|
23
|
+
onVoucher?: TestCallback<NonNullable<RouteDockMiddlewareOptions['onVoucher']>>;
|
|
24
|
+
}
|
|
25
|
+
/** Synthetic settlement values handed to the callbacks. All optional — sensible defaults per mode. */
|
|
26
|
+
interface SyntheticPayment {
|
|
27
|
+
/** On-chain tx hash passed to onSettled. Default: a fixed 64-hex string. */
|
|
28
|
+
txHash?: string;
|
|
29
|
+
/** Settled amount (x402 / mpp-charge) passed to onSettled. Default: '0.001'. */
|
|
30
|
+
amount?: string;
|
|
31
|
+
/** Channel address (session modes) passed to onSessionOpen. Default: a fixed C... address. */
|
|
32
|
+
channelId?: string;
|
|
33
|
+
/** Per-voucher rate (session modes), in decimal string. Default: '0.0001'. */
|
|
34
|
+
rate?: string;
|
|
35
|
+
/** Number of vouchers to emit before close (session modes). Default: 3. */
|
|
36
|
+
voucherCount?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Payer passed to onSettled (4th arg) and onSessionOpen (2nd arg). Default: a
|
|
39
|
+
* valid Stellar G... account. Pass `null` to exercise the address-unavailable
|
|
40
|
+
* path; `null` is passed through untouched (an explicit null is not replaced
|
|
41
|
+
* by the default).
|
|
42
|
+
*/
|
|
43
|
+
payer?: string | null;
|
|
44
|
+
}
|
|
45
|
+
interface MockRoutedockOptions extends MockRoutedockCallbacks {
|
|
46
|
+
/** Payment mode the synthetic payment uses. Default: 'x402'. */
|
|
47
|
+
mode?: PaymentMode;
|
|
48
|
+
/**
|
|
49
|
+
* 'auto-pass' (default): synthesize a successful settlement, invoke the
|
|
50
|
+
* configured callbacks with synthetic data, then call the route handler.
|
|
51
|
+
* 'auto-fail': respond with `failStatus` and skip both callbacks and handler.
|
|
52
|
+
*/
|
|
53
|
+
payment?: 'auto-pass' | 'auto-fail';
|
|
54
|
+
/** Override the synthetic data handed to callbacks. */
|
|
55
|
+
synthetic?: SyntheticPayment;
|
|
56
|
+
/** HTTP status used on 'auto-fail'. Default: 402. */
|
|
57
|
+
failStatus?: number;
|
|
58
|
+
}
|
|
59
|
+
/** Synthetic settlement record attached to `req.routedock` for assertions. */
|
|
60
|
+
interface MockSettlementRecord {
|
|
61
|
+
mode: PaymentMode;
|
|
62
|
+
txHash: string;
|
|
63
|
+
amount: string;
|
|
64
|
+
channelId?: string;
|
|
65
|
+
vouchers?: Array<{
|
|
66
|
+
index: number;
|
|
67
|
+
cumulativeAmount: string;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Drive a provider's settlement callbacks with synthetic data, with no Express
|
|
72
|
+
* request involved. Useful for unit-testing an `onSettled` (e.g. a Supabase
|
|
73
|
+
* write) in complete isolation. Returns the synthetic settlement record.
|
|
74
|
+
*
|
|
75
|
+
* Honors `payment: 'auto-fail'` by invoking no callbacks and returning null.
|
|
76
|
+
*/
|
|
77
|
+
declare function runMockSettlement(opts: MockRoutedockOptions): Promise<MockSettlementRecord | null>;
|
|
78
|
+
/**
|
|
79
|
+
* Express middleware that mocks RouteDock payment verification — the testing
|
|
80
|
+
* counterpart to `routedock()`. Drop it in front of a route to drive that
|
|
81
|
+
* route's settlement callbacks with synthetic data, without any on-chain
|
|
82
|
+
* settlement, facilitator, or wallet. Think `msw` for RouteDock providers.
|
|
83
|
+
*
|
|
84
|
+
* On `payment: 'auto-pass'` (default) it invokes the configured callbacks with
|
|
85
|
+
* synthetic data and then calls the next handler (your route). On
|
|
86
|
+
* `payment: 'auto-fail'` it responds with `failStatus` (402 by default) and
|
|
87
|
+
* skips both the callbacks and the route handler — exactly as a real payment
|
|
88
|
+
* rejection would.
|
|
89
|
+
*
|
|
90
|
+
* The synthetic settlement is attached to `req.routedock` for assertions.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* import express from 'express'
|
|
95
|
+
* import request from 'supertest'
|
|
96
|
+
* import { createMockRoutedockMiddleware } from '@routedock/routedock/testing'
|
|
97
|
+
*
|
|
98
|
+
* const onSettled = vi.fn()
|
|
99
|
+
* const app = express()
|
|
100
|
+
* app.use('/price', createMockRoutedockMiddleware({ mode: 'x402', payment: 'auto-pass', onSettled }))
|
|
101
|
+
* app.get('/price', (_req, res) => res.json({ price: '42' }))
|
|
102
|
+
*
|
|
103
|
+
* await request(app).get('/price').expect(200)
|
|
104
|
+
* expect(onSettled).toHaveBeenCalledWith(
|
|
105
|
+
* expect.any(String),
|
|
106
|
+
* '0.001',
|
|
107
|
+
* 'x402',
|
|
108
|
+
* expect.any(String), // payer
|
|
109
|
+
* )
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
declare function createMockRoutedockMiddleware(opts?: MockRoutedockOptions): RequestHandler;
|
|
113
|
+
|
|
114
|
+
export { type MockRoutedockCallbacks, type MockRoutedockOptions, type MockSettlementRecord, type SyntheticPayment, createMockRoutedockMiddleware, runMockSettlement };
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/testing/createMockRoutedockMiddleware.ts
|
|
2
|
+
var DEFAULT_TX_HASH = "0000000000000000000000000000000000000000000000000000000000000000";
|
|
3
|
+
var DEFAULT_CHANNEL_ID = "CCK4XOW3YKQUEZFONUTINKMSNW7SNMRQZURME5U3UP7E6WNGK7UHUCAH";
|
|
4
|
+
var DEFAULT_PAYER = "GAIRCEIRCEIRCEIRCEIRCEIRCEIRCEIRCEIRCEIRCEIRCEIRCEIRCF6M";
|
|
5
|
+
function format7(scaled) {
|
|
6
|
+
return (Number(scaled) / 1e7).toFixed(7);
|
|
7
|
+
}
|
|
8
|
+
function toScaled(decimal) {
|
|
9
|
+
const [whole, frac = ""] = decimal.split(".");
|
|
10
|
+
const fracPadded = (frac + "0000000").slice(0, 7);
|
|
11
|
+
return BigInt(whole + fracPadded);
|
|
12
|
+
}
|
|
13
|
+
async function runMockSettlement(opts) {
|
|
14
|
+
const mode = opts.mode ?? "x402";
|
|
15
|
+
if ((opts.payment ?? "auto-pass") === "auto-fail") return null;
|
|
16
|
+
const s = opts.synthetic ?? {};
|
|
17
|
+
const txHash = s.txHash ?? DEFAULT_TX_HASH;
|
|
18
|
+
const payer = s.payer === void 0 ? DEFAULT_PAYER : s.payer;
|
|
19
|
+
if (mode === "mpp-session" || mode === "mpp-session-ws") {
|
|
20
|
+
const channelId = s.channelId ?? DEFAULT_CHANNEL_ID;
|
|
21
|
+
const rate = toScaled(s.rate ?? "0.0001");
|
|
22
|
+
const count = s.voucherCount ?? 3;
|
|
23
|
+
if (opts.onSessionOpen) await opts.onSessionOpen(channelId, payer);
|
|
24
|
+
const vouchers = [];
|
|
25
|
+
for (let i = 1; i <= count; i++) {
|
|
26
|
+
const cumulativeAmount = format7(rate * BigInt(i));
|
|
27
|
+
vouchers.push({ index: i, cumulativeAmount });
|
|
28
|
+
if (opts.onVoucher) await opts.onVoucher(channelId, i, cumulativeAmount, "0000000000000000000000000000000000000000000000000000000000000000");
|
|
29
|
+
}
|
|
30
|
+
const totalPaid = format7(rate * BigInt(count));
|
|
31
|
+
if (opts.onSettled) await opts.onSettled(txHash, totalPaid, mode, payer);
|
|
32
|
+
return { mode, txHash, amount: totalPaid, channelId, vouchers };
|
|
33
|
+
}
|
|
34
|
+
const amount = s.amount ?? "0.001";
|
|
35
|
+
if (opts.onSettled) await opts.onSettled(txHash, amount, mode, payer);
|
|
36
|
+
return { mode, txHash, amount };
|
|
37
|
+
}
|
|
38
|
+
function createMockRoutedockMiddleware(opts = {}) {
|
|
39
|
+
const payment = opts.payment ?? "auto-pass";
|
|
40
|
+
const failStatus = opts.failStatus ?? 402;
|
|
41
|
+
return (req, res, next) => {
|
|
42
|
+
if (payment === "auto-fail") {
|
|
43
|
+
res.status(failStatus).json({
|
|
44
|
+
error: "payment required",
|
|
45
|
+
detail: "mock routedock middleware: payment=auto-fail"
|
|
46
|
+
});
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
void runMockSettlement(opts).then((record) => {
|
|
50
|
+
if (record) req.routedock = record;
|
|
51
|
+
next();
|
|
52
|
+
}).catch((err) => next(err));
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { createMockRoutedockMiddleware, runMockSettlement };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@routedock/routedock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Unified payment execution layer for autonomous agents on Stellar",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,50 +12,170 @@
|
|
|
12
12
|
"main": "dist/index.cjs",
|
|
13
13
|
"module": "dist/index.js",
|
|
14
14
|
"types": "dist/index.d.ts",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
15
19
|
"typesVersions": {
|
|
16
20
|
"*": {
|
|
17
|
-
"client": [
|
|
18
|
-
|
|
21
|
+
"client": [
|
|
22
|
+
"dist/client.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"provider": [
|
|
25
|
+
"dist/provider.d.ts"
|
|
26
|
+
],
|
|
27
|
+
"react": [
|
|
28
|
+
"dist/react.d.ts"
|
|
29
|
+
],
|
|
30
|
+
"testing": [
|
|
31
|
+
"dist/testing.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"provider/hono": [
|
|
34
|
+
"dist/provider/hono.d.ts"
|
|
35
|
+
],
|
|
36
|
+
"provider/fastify": [
|
|
37
|
+
"dist/provider/fastify.d.ts"
|
|
38
|
+
],
|
|
39
|
+
"schema": [
|
|
40
|
+
"dist/schema.d.ts"
|
|
41
|
+
]
|
|
19
42
|
}
|
|
20
43
|
},
|
|
21
44
|
"exports": {
|
|
22
45
|
".": {
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"default": "./dist/index.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/index.d.cts",
|
|
52
|
+
"default": "./dist/index.cjs"
|
|
53
|
+
}
|
|
26
54
|
},
|
|
27
55
|
"./client": {
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./dist/client.d.ts",
|
|
58
|
+
"default": "./dist/client.js"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./dist/client.d.cts",
|
|
62
|
+
"default": "./dist/client.cjs"
|
|
63
|
+
}
|
|
31
64
|
},
|
|
32
65
|
"./provider": {
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
66
|
+
"import": {
|
|
67
|
+
"types": "./dist/provider.d.ts",
|
|
68
|
+
"default": "./dist/provider.js"
|
|
69
|
+
},
|
|
70
|
+
"require": {
|
|
71
|
+
"types": "./dist/provider.d.cts",
|
|
72
|
+
"default": "./dist/provider.cjs"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"./react": {
|
|
76
|
+
"import": {
|
|
77
|
+
"types": "./dist/react.d.ts",
|
|
78
|
+
"default": "./dist/react.js"
|
|
79
|
+
},
|
|
80
|
+
"require": {
|
|
81
|
+
"types": "./dist/react.d.cts",
|
|
82
|
+
"default": "./dist/react.cjs"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"./testing": {
|
|
86
|
+
"import": {
|
|
87
|
+
"types": "./dist/testing.d.ts",
|
|
88
|
+
"default": "./dist/testing.js"
|
|
89
|
+
},
|
|
90
|
+
"require": {
|
|
91
|
+
"types": "./dist/testing.d.cts",
|
|
92
|
+
"default": "./dist/testing.cjs"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"./provider/hono": {
|
|
96
|
+
"import": {
|
|
97
|
+
"types": "./dist/provider/hono.d.ts",
|
|
98
|
+
"default": "./dist/provider/hono.js"
|
|
99
|
+
},
|
|
100
|
+
"require": {
|
|
101
|
+
"types": "./dist/provider/hono.d.cts",
|
|
102
|
+
"default": "./dist/provider/hono.cjs"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"./provider/fastify": {
|
|
106
|
+
"import": {
|
|
107
|
+
"types": "./dist/provider/fastify.d.ts",
|
|
108
|
+
"default": "./dist/provider/fastify.js"
|
|
109
|
+
},
|
|
110
|
+
"require": {
|
|
111
|
+
"types": "./dist/provider/fastify.d.cts",
|
|
112
|
+
"default": "./dist/provider/fastify.cjs"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"./schema": {
|
|
116
|
+
"import": {
|
|
117
|
+
"types": "./dist/schema.d.ts",
|
|
118
|
+
"default": "./dist/schema.js"
|
|
119
|
+
},
|
|
120
|
+
"require": {
|
|
121
|
+
"types": "./dist/schema.d.cts",
|
|
122
|
+
"default": "./dist/schema.cjs"
|
|
123
|
+
}
|
|
36
124
|
}
|
|
37
125
|
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"build": "tsup",
|
|
40
|
-
"dev": "tsup --watch",
|
|
41
|
-
"typecheck": "tsc --noEmit"
|
|
42
|
-
},
|
|
43
126
|
"dependencies": {
|
|
127
|
+
"@cfworker/json-schema": "^4.0.0",
|
|
128
|
+
"@stellar/mpp": "^0.4.0",
|
|
44
129
|
"@stellar/stellar-sdk": "^14.6.1",
|
|
45
130
|
"@supabase/supabase-js": "^2.47.0",
|
|
46
131
|
"@x402/core": "^2.9.0",
|
|
47
132
|
"@x402/stellar": "^2.9.0",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"mppx": "^0.5.7"
|
|
133
|
+
"mppx": "^0.5.7",
|
|
134
|
+
"@routedock/nulth-sdk": "0.2.1"
|
|
51
135
|
},
|
|
52
136
|
"peerDependencies": {
|
|
53
|
-
"express": "^4.18.0"
|
|
137
|
+
"express": "^4.18.0",
|
|
138
|
+
"fastify": "^4.0.0 || ^5.0.0",
|
|
139
|
+
"hono": "^4.0.0",
|
|
140
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
141
|
+
},
|
|
142
|
+
"peerDependenciesMeta": {
|
|
143
|
+
"express": {
|
|
144
|
+
"optional": true
|
|
145
|
+
},
|
|
146
|
+
"hono": {
|
|
147
|
+
"optional": true
|
|
148
|
+
},
|
|
149
|
+
"fastify": {
|
|
150
|
+
"optional": true
|
|
151
|
+
},
|
|
152
|
+
"react": {
|
|
153
|
+
"optional": true
|
|
154
|
+
}
|
|
54
155
|
},
|
|
55
156
|
"devDependencies": {
|
|
157
|
+
"@happy-dom/global-registrator": "^15.11.7",
|
|
158
|
+
"@testing-library/dom": "^10.4.1",
|
|
159
|
+
"@testing-library/react": "^16.3.2",
|
|
56
160
|
"@types/express": "^4.17.21",
|
|
57
161
|
"@types/node": "^20.0.0",
|
|
162
|
+
"@types/react": "^19.0.0",
|
|
163
|
+
"ajv": "^8.17.1",
|
|
164
|
+
"ajv-formats": "^3.0.1",
|
|
165
|
+
"express": "^4.18.0",
|
|
166
|
+
"fastify": "^5.0.0",
|
|
167
|
+
"hono": "^4.12.23",
|
|
168
|
+
"react": "^19.0.0",
|
|
169
|
+
"react-dom": "^19.0.0",
|
|
58
170
|
"tsup": "^8.0.0",
|
|
59
|
-
"
|
|
171
|
+
"tsx": "^4.22.3",
|
|
172
|
+
"typescript": "^5.4.5",
|
|
173
|
+
"viem": "^2.52.0"
|
|
174
|
+
},
|
|
175
|
+
"scripts": {
|
|
176
|
+
"build": "tsup",
|
|
177
|
+
"dev": "tsup --watch",
|
|
178
|
+
"typecheck": "tsc --noEmit",
|
|
179
|
+
"test": "tsx --experimental-test-module-mocks --test $(find src -name '*.test.ts' -o -name '*.test.tsx' | sort)"
|
|
60
180
|
}
|
|
61
|
-
}
|
|
181
|
+
}
|
package/PUBLISH_CHECKLIST.md
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# @routedock/sdk Publish Checklist
|
|
2
|
-
|
|
3
|
-
Complete every step in order. Do not skip.
|
|
4
|
-
|
|
5
|
-
## Pre-publish
|
|
6
|
-
|
|
7
|
-
- [ ] **1. Build dist/**
|
|
8
|
-
```bash
|
|
9
|
-
cd packages/sdk
|
|
10
|
-
pnpm build
|
|
11
|
-
```
|
|
12
|
-
Verify: `dist/index.js`, `dist/index.cjs`, `dist/client.js`, `dist/client.cjs`, `dist/provider.js`, `dist/provider.cjs`, and all `.d.ts` files exist.
|
|
13
|
-
|
|
14
|
-
- [ ] **2. Typecheck**
|
|
15
|
-
```bash
|
|
16
|
-
pnpm typecheck
|
|
17
|
-
```
|
|
18
|
-
Must exit with 0 errors.
|
|
19
|
-
|
|
20
|
-
- [ ] **3. Smoke tests**
|
|
21
|
-
```bash
|
|
22
|
-
pnpm test
|
|
23
|
-
```
|
|
24
|
-
All 4 smoke tests must pass.
|
|
25
|
-
|
|
26
|
-
- [ ] **4. Confirm no secrets in pack**
|
|
27
|
-
```bash
|
|
28
|
-
npm pack --dry-run
|
|
29
|
-
```
|
|
30
|
-
Scan the file list: no `.env`, no `*.pem`, no files containing `SECRET` in the name.
|
|
31
|
-
|
|
32
|
-
- [ ] **5. Update `repository.url`**
|
|
33
|
-
In `packages/sdk/package.json`, replace `YOUR_ORG` with the actual GitHub org/user.
|
|
34
|
-
|
|
35
|
-
## Publish
|
|
36
|
-
|
|
37
|
-
- [ ] **6. Login to npm**
|
|
38
|
-
```bash
|
|
39
|
-
npm login
|
|
40
|
-
```
|
|
41
|
-
Verify you are logged in as the correct user: `npm whoami`
|
|
42
|
-
|
|
43
|
-
- [ ] **7. Publish**
|
|
44
|
-
```bash
|
|
45
|
-
cd packages/sdk
|
|
46
|
-
pnpm publish --access public
|
|
47
|
-
```
|
|
48
|
-
The `--access public` flag is required for scoped packages (`@routedock/sdk`) to be publicly accessible.
|
|
49
|
-
|
|
50
|
-
## Post-publish Verification
|
|
51
|
-
|
|
52
|
-
- [ ] **8. Verify on npm registry**
|
|
53
|
-
```bash
|
|
54
|
-
npm show @routedock/sdk
|
|
55
|
-
```
|
|
56
|
-
Confirms: version 0.1.0, correct description, MIT license.
|
|
57
|
-
|
|
58
|
-
- [ ] **9. Test install in a clean directory**
|
|
59
|
-
```bash
|
|
60
|
-
mkdir /tmp/test-install && cd /tmp/test-install
|
|
61
|
-
npm init -y
|
|
62
|
-
npm install @routedock/sdk
|
|
63
|
-
node -e "const { RouteDockClient } = require('@routedock/sdk'); console.log('ok')"
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
- [ ] **10. Add npm badge to README.md**
|
|
67
|
-
Once published, update the root README with the live npm badge:
|
|
68
|
-
```markdown
|
|
69
|
-

|
|
70
|
-
```
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* TypeScript types for the RouteDock manifest format.
|
|
5
|
-
* Derived from packages/sdk/src/schemas/routedock.schema.json (draft-07).
|
|
6
|
-
*
|
|
7
|
-
* Section 5 of ROUTEDOCK_MASTER.md is the canonical specification.
|
|
8
|
-
*/
|
|
9
|
-
type PaymentMode = 'x402' | 'mpp-charge' | 'mpp-session';
|
|
10
|
-
/** Per-request pricing config — used by x402 and mpp-charge modes */
|
|
11
|
-
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
|
-
/** Per-voucher pricing config — used by mpp-session (one-way-channel) mode */
|
|
19
|
-
interface SessionPricingConfig {
|
|
20
|
-
/** Cost per voucher, e.g. "0.0001" */
|
|
21
|
-
rate: string;
|
|
22
|
-
per: 'voucher';
|
|
23
|
-
/** Soroban contract address (C...) for the one-way-channel contract */
|
|
24
|
-
channel_contract: string;
|
|
25
|
-
/** Minimum initial deposit to open a channel, e.g. "0.10" */
|
|
26
|
-
min_deposit: string;
|
|
27
|
-
/**
|
|
28
|
-
* Ledgers the server has to settle before the funder can reclaim.
|
|
29
|
-
* Default: 17280 (~24h). Do NOT reduce in production — this is a
|
|
30
|
-
* security parameter the server depends on to settle first.
|
|
31
|
-
*/
|
|
32
|
-
refund_waiting_period_ledgers: number;
|
|
33
|
-
}
|
|
34
|
-
/** Full RouteDock discovery manifest — served at /.well-known/routedock.json */
|
|
35
|
-
interface RouteDockManifest {
|
|
36
|
-
/** Schema version — always "1.0" */
|
|
37
|
-
routedock: '1.0';
|
|
38
|
-
/** Human-readable provider name */
|
|
39
|
-
name: string;
|
|
40
|
-
/** Human-readable description of the provider's data or service */
|
|
41
|
-
description: string;
|
|
42
|
-
/** Payment modes supported by this provider */
|
|
43
|
-
modes: PaymentMode[];
|
|
44
|
-
/** Stellar network this provider operates on */
|
|
45
|
-
network: 'testnet' | 'mainnet';
|
|
46
|
-
/** Asset ticker symbol, e.g. "USDC" */
|
|
47
|
-
asset: string;
|
|
48
|
-
/** Stellar Asset Contract (SAC) address for the payment asset */
|
|
49
|
-
asset_contract: string;
|
|
50
|
-
/** Stellar address (G...) that receives payments */
|
|
51
|
-
payee: string;
|
|
52
|
-
/** Pricing configuration per supported payment mode */
|
|
53
|
-
pricing: {
|
|
54
|
-
x402?: PricingConfig;
|
|
55
|
-
'mpp-charge'?: PricingConfig;
|
|
56
|
-
'mpp-session'?: SessionPricingConfig;
|
|
57
|
-
};
|
|
58
|
-
/** Map of endpoint name to HTTP method + path, e.g. { price: "GET /price" } */
|
|
59
|
-
endpoints: Record<string, string>;
|
|
60
|
-
/** Capability tags indexed with trigram search in the provider registry */
|
|
61
|
-
tags: string[];
|
|
62
|
-
}
|
|
63
|
-
/** Result returned by client.pay() for any payment mode */
|
|
64
|
-
interface PaymentResult {
|
|
65
|
-
/** Parsed response body from the provider */
|
|
66
|
-
data: unknown;
|
|
67
|
-
/** On-chain Stellar transaction hash, or null for session voucher calls */
|
|
68
|
-
txHash: string | null;
|
|
69
|
-
/** Payment mode that was used for this call */
|
|
70
|
-
mode: PaymentMode;
|
|
71
|
-
/** Amount paid in the payment asset (decimal string) */
|
|
72
|
-
amount: string;
|
|
73
|
-
/** Unix timestamp (ms) when the payment completed */
|
|
74
|
-
timestamp: number;
|
|
75
|
-
}
|
|
76
|
-
/** Result returned by session.close() */
|
|
77
|
-
interface SessionCloseResult {
|
|
78
|
-
/** On-chain transaction hash for the channel close */
|
|
79
|
-
closeTxHash: string;
|
|
80
|
-
/** Total amount settled across all vouchers (decimal string) */
|
|
81
|
-
totalPaid: string;
|
|
82
|
-
/** Number of vouchers issued during the session */
|
|
83
|
-
vouchersIssued: number;
|
|
84
|
-
}
|
|
85
|
-
/** Handle for a live MPP session returned by client.openSession() */
|
|
86
|
-
interface SessionHandle {
|
|
87
|
-
/** Stellar channel contract address (C...) */
|
|
88
|
-
channelId: string;
|
|
89
|
-
/** Transaction hash from the channel-open on-chain call */
|
|
90
|
-
openTxHash: string;
|
|
91
|
-
/**
|
|
92
|
-
* Async generator of server-sent event data.
|
|
93
|
-
* Each iteration sends a voucher and yields the parsed response.
|
|
94
|
-
* UNAUDITED: uses stellar-experimental/one-way-channel contract.
|
|
95
|
-
*/
|
|
96
|
-
stream(): AsyncIterable<unknown>;
|
|
97
|
-
/** Close the channel on-chain with the highest signed voucher */
|
|
98
|
-
close(): Promise<SessionCloseResult>;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Durable session state stored in Supabase (sessions table).
|
|
102
|
-
* cumulative_amount is a decimal string to avoid float precision loss.
|
|
103
|
-
* The monotonic invariant is enforced both here and at the DB level via trigger.
|
|
104
|
-
*/
|
|
105
|
-
interface SessionState {
|
|
106
|
-
channel_id: string;
|
|
107
|
-
payee: string;
|
|
108
|
-
payer: string;
|
|
109
|
-
/** Monotonically increasing cumulative amount — stored as string to preserve precision */
|
|
110
|
-
cumulative_amount: string;
|
|
111
|
-
last_signature: string;
|
|
112
|
-
status: 'open' | 'closing' | 'closed';
|
|
113
|
-
opened_at: string;
|
|
114
|
-
updated_at: string;
|
|
115
|
-
settlement_tx_hash: string | null;
|
|
116
|
-
}
|
|
117
|
-
declare class RouteDockError extends Error {
|
|
118
|
-
constructor(message: string);
|
|
119
|
-
}
|
|
120
|
-
/** Manifest fetch failed, schema invalid, or required fields missing */
|
|
121
|
-
declare class RouteDockManifestError extends RouteDockError {
|
|
122
|
-
constructor(message: string);
|
|
123
|
-
}
|
|
124
|
-
/** No payment mode in the manifest is supported by this client */
|
|
125
|
-
declare class RouteDockNoSupportedModeError extends RouteDockError {
|
|
126
|
-
constructor(message: string);
|
|
127
|
-
}
|
|
128
|
-
/** Session invariant violated (e.g. non-monotonic voucher amount) */
|
|
129
|
-
declare class RouteDockSessionError extends RouteDockError {
|
|
130
|
-
constructor(message: string);
|
|
131
|
-
}
|
|
132
|
-
/** Local spend cap or on-chain policy rejected the payment */
|
|
133
|
-
declare class RouteDockPolicyRejectedError extends RouteDockError {
|
|
134
|
-
readonly reason: string;
|
|
135
|
-
constructor(reason: string);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
interface SessionStore {
|
|
139
|
-
get(channelId: string): Promise<SessionState | null>;
|
|
140
|
-
/** Enforce monotonic invariant at application level before writing */
|
|
141
|
-
upsert(channelId: string, state: SessionState): Promise<void>;
|
|
142
|
-
close(channelId: string): Promise<void>;
|
|
143
|
-
}
|
|
144
|
-
declare class SupabaseSessionStore implements SessionStore {
|
|
145
|
-
private readonly supabase;
|
|
146
|
-
constructor(supabase: SupabaseClient);
|
|
147
|
-
get(channelId: string): Promise<SessionState | null>;
|
|
148
|
-
upsert(channelId: string, state: SessionState): Promise<void>;
|
|
149
|
-
close(channelId: string): Promise<void>;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export { type PaymentMode as P, RouteDockError as R, type SessionCloseResult as S, type PaymentResult as a, type PricingConfig as b, type RouteDockManifest as c, RouteDockManifestError as d, RouteDockNoSupportedModeError as e, RouteDockPolicyRejectedError as f, RouteDockSessionError as g, type SessionHandle as h, type SessionPricingConfig as i, type SessionState as j, type SessionStore as k, SupabaseSessionStore as l };
|