@leashmarket/seller-kit 0.1.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/README.md +73 -0
- package/dist/hono/create-seller.d.ts +109 -0
- package/dist/hono/create-seller.d.ts.map +1 -0
- package/dist/hono/create-seller.js +325 -0
- package/dist/hono/create-seller.js.map +1 -0
- package/dist/hono/simple-x402.d.ts +7 -0
- package/dist/hono/simple-x402.d.ts.map +1 -0
- package/dist/hono/simple-x402.js +14 -0
- package/dist/hono/simple-x402.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/receipts/price.d.ts +29 -0
- package/dist/receipts/price.d.ts.map +1 -0
- package/dist/receipts/price.js +58 -0
- package/dist/receipts/price.js.map +1 -0
- package/dist/receipts/store.d.ts +5 -0
- package/dist/receipts/store.d.ts.map +1 -0
- package/dist/receipts/store.js +2 -0
- package/dist/receipts/store.js.map +1 -0
- package/dist/seller/agent-seller.d.ts +6 -0
- package/dist/seller/agent-seller.d.ts.map +1 -0
- package/dist/seller/agent-seller.js +8 -0
- package/dist/seller/agent-seller.js.map +1 -0
- package/dist/test-utils/stub-facilitator.d.ts +10 -0
- package/dist/test-utils/stub-facilitator.d.ts.map +1 -0
- package/dist/test-utils/stub-facilitator.js +39 -0
- package/dist/test-utils/stub-facilitator.js.map +1 -0
- package/dist/x402/svm-server.d.ts +42 -0
- package/dist/x402/svm-server.d.ts.map +1 -0
- package/dist/x402/svm-server.js +50 -0
- package/dist/x402/svm-server.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# @leashmarket/seller-kit
|
|
2
|
+
|
|
3
|
+
Hono integration for Leash sellers. Three responsibilities:
|
|
4
|
+
|
|
5
|
+
1. **Real x402 middleware on Solana.** `createSeller` mounts
|
|
6
|
+
`paymentMiddlewareFromHTTPServer` from `@x402/hono`, configured via
|
|
7
|
+
`createSvmResourceServer` (which wraps `ExactSvmScheme` from
|
|
8
|
+
`@x402/svm`) and pointed at an HTTPS facilitator (default
|
|
9
|
+
`https://facilitator.svmacc.tech`). Unauthenticated traffic gets
|
|
10
|
+
`402 + PAYMENT-REQUIRED`; settled traffic invokes the real handler.
|
|
11
|
+
2. **Asset Signer PDA `payTo`.** The middleware always credits the seller
|
|
12
|
+
agent's Asset Signer PDA (derived via `mpl-core`), so funds land in the
|
|
13
|
+
on-chain treasury without the seller agent needing a private key.
|
|
14
|
+
3. **`earn` receipts.** Every settled call emits a tamper-evident
|
|
15
|
+
`ReceiptV1` (with the real `tx_sig` and
|
|
16
|
+
`payment_requirements_hash` from the facilitator's
|
|
17
|
+
`PAYMENT-RESPONSE`) to the user-supplied `onReceipt` callback. Receipts
|
|
18
|
+
are nonce-ordered and hash-chained per seller agent, mirroring
|
|
19
|
+
`@leashmarket/buyer-kit` so explorers can verify both sides of the trade.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createSeller } from '@leashmarket/seller-kit';
|
|
23
|
+
|
|
24
|
+
createSeller(app, {
|
|
25
|
+
umi,
|
|
26
|
+
sellerAgent: { asset: assetMint },
|
|
27
|
+
routes: { 'POST /tag': { price: '$0.001', description: 'tag' } },
|
|
28
|
+
onReceipt: (r) =>
|
|
29
|
+
fetch(`${RUNNER}/a/${r.agent}/receipts`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
body: JSON.stringify(r),
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Receipt semantics
|
|
37
|
+
|
|
38
|
+
- **402 → no receipt.** No settled trade to record.
|
|
39
|
+
- **2xx after settle → one earn receipt** with `tx_sig` and
|
|
40
|
+
`payment_requirements_hash` lifted from `PAYMENT-RESPONSE`.
|
|
41
|
+
- **Handler 4xx/5xx after payment → no receipt.** Recording would lie
|
|
42
|
+
about a settled trade.
|
|
43
|
+
- **Chain.** `prev_receipt_hash` links to the previous receipt's
|
|
44
|
+
`receipt_hash` for the same seller agent (in-process state).
|
|
45
|
+
|
|
46
|
+
## Price parsing
|
|
47
|
+
|
|
48
|
+
`SellerRouteConfig.price` is a human display string. Use `parsePrice()` to
|
|
49
|
+
inspect what lands on a receipt:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
parsePrice('$0.001'); // { amount: '0.001', currency: 'USDC' }
|
|
53
|
+
parsePrice('0.5 USDT'); // { amount: '0.5', currency: 'USDT' }
|
|
54
|
+
parsePrice('0.01'); // { amount: '0.01', currency: 'USDC' }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`$` and `USD` normalise to `USDC` since SVM settlement uses USDC.
|
|
58
|
+
|
|
59
|
+
## Configuring the facilitator
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { createSvmResourceServer } from '@leashmarket/seller-kit/x402';
|
|
63
|
+
|
|
64
|
+
const server = createSvmResourceServer({
|
|
65
|
+
network: 'solana-devnet',
|
|
66
|
+
payTo,
|
|
67
|
+
asset: '<USDC mint>',
|
|
68
|
+
facilitatorUrl: 'https://your-facilitator.example.com',
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
See the [`Real x402 on Solana`](../../apps/docs/standards/x402-on-solana.mdx)
|
|
73
|
+
doc for the protocol-level walkthrough.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { Hono } from 'hono';
|
|
2
|
+
import type { Context as UmiContext } from '@metaplex-foundation/umi';
|
|
3
|
+
import type { ReceiptV1 } from '@leashmarket/schemas';
|
|
4
|
+
import { type KnownStableSymbol } from '@leashmarket/core';
|
|
5
|
+
import type { FacilitatorClient } from '@x402/core/server';
|
|
6
|
+
import { type LeashSellerNetwork } from '../x402/svm-server.js';
|
|
7
|
+
import { type AgentSellerConfig } from '../seller/agent-seller.js';
|
|
8
|
+
export type SellerRouteConfig = {
|
|
9
|
+
description: string;
|
|
10
|
+
/**
|
|
11
|
+
* Display price e.g. `"$0.001"`, `"0.01 USDC"`, or `"0.5"`. Parsed locally
|
|
12
|
+
* via {@link parsePrice} into atomic units against the route's `currency`
|
|
13
|
+
* (defaults to `'USDC'`), then advertised on the wire as an
|
|
14
|
+
* `AssetAmount` payment option so the facilitator settles in exactly that
|
|
15
|
+
* stablecoin. The same parsed `{ amount, currency, asset }` is stamped onto
|
|
16
|
+
* every `earn` `ReceiptV1` so explorers can render the correct value
|
|
17
|
+
* without re-parsing.
|
|
18
|
+
*/
|
|
19
|
+
price: string;
|
|
20
|
+
/**
|
|
21
|
+
* Settlement currency for the price. Must be a Leash-known stablecoin
|
|
22
|
+
* (`USDC` / `USDT` / `USDG`) so the seller-kit can resolve a real mint via
|
|
23
|
+
* `@leashmarket/core/tokens`. Defaults to `'USDC'`.
|
|
24
|
+
*/
|
|
25
|
+
currency?: KnownStableSymbol;
|
|
26
|
+
/**
|
|
27
|
+
* Additional stablecoins this route also accepts. When set, the runner
|
|
28
|
+
* advertises an `accepts[]` of equivalent payment options (same dollar
|
|
29
|
+
* amount across each stable, since v0.1 treats them as 1:1 USD pegs) so a
|
|
30
|
+
* paying agent can choose which token to debit. The route's primary
|
|
31
|
+
* `currency` is always included implicitly.
|
|
32
|
+
*/
|
|
33
|
+
acceptsCurrencies?: KnownStableSymbol[];
|
|
34
|
+
/** Optional MIME type for the response. Defaults to `application/json`. */
|
|
35
|
+
mimeType?: string;
|
|
36
|
+
};
|
|
37
|
+
export type CreateSellerOptions = {
|
|
38
|
+
umi: Pick<UmiContext, 'eddsa' | 'programs'>;
|
|
39
|
+
sellerAgent: AgentSellerConfig;
|
|
40
|
+
routes: Record<string, SellerRouteConfig>;
|
|
41
|
+
/**
|
|
42
|
+
* CAIP-2 Solana network to settle on. Defaults to `'solana-devnet'`. The
|
|
43
|
+
* same network is stamped onto `ReceiptV1.price.network` and into the
|
|
44
|
+
* `paymentRequirements.network` advertised in 402 responses.
|
|
45
|
+
*/
|
|
46
|
+
network?: LeashSellerNetwork;
|
|
47
|
+
/**
|
|
48
|
+
* Hosted x402 facilitator URL, or a pre-built `FacilitatorClient`. Defaults
|
|
49
|
+
* to `https://facilitator.svmacc.tech` (free, gas-sponsored). The URL is
|
|
50
|
+
* also stamped onto `ReceiptV1.facilitator` so consumers can verify the
|
|
51
|
+
* settlement out-of-band.
|
|
52
|
+
*/
|
|
53
|
+
facilitator?: string | FacilitatorClient;
|
|
54
|
+
/**
|
|
55
|
+
* Called with every settled `earn` receipt. Receipts only fire on
|
|
56
|
+
* successful x402 settlements (the underlying `onAfterSettle` hook), so a
|
|
57
|
+
* 402 / 4xx / 5xx never produces a (false) earn receipt. Use this to ship
|
|
58
|
+
* receipts to the Leash runner — e.g.
|
|
59
|
+
* `onReceipt: (r) => fetch(`${RUNNER}/a/${r.agent}/receipts`, { method: 'POST', body: JSON.stringify(r) })`.
|
|
60
|
+
* Errors thrown here are swallowed so a runner outage never breaks a
|
|
61
|
+
* paying customer's request.
|
|
62
|
+
*
|
|
63
|
+
* Pass `false` to explicitly disable receipt publishing, even if env-
|
|
64
|
+
* level defaults (LEASH_RUNNER_URL / LEASH_API_URL) are configured.
|
|
65
|
+
*/
|
|
66
|
+
onReceipt?: ((receipt: ReceiptV1) => void | Promise<void>) | false;
|
|
67
|
+
/**
|
|
68
|
+
* Optional fan-out destinations applied when `onReceipt` is undefined.
|
|
69
|
+
* Either or both can be set; `process.env.LEASH_RUNNER_URL`,
|
|
70
|
+
* `LEASH_API_URL`, and `LEASH_API_KEY` are also read so the most
|
|
71
|
+
* common production setup needs zero seller-kit code changes.
|
|
72
|
+
* Setting `LEASH_RECEIPTS_DISABLED=1` is the global kill switch.
|
|
73
|
+
*/
|
|
74
|
+
receipts?: SellerReceiptForwardConfig;
|
|
75
|
+
/** Override the policy version stamped onto receipts. Defaults to `'0.1'`. */
|
|
76
|
+
policyVersion?: string;
|
|
77
|
+
};
|
|
78
|
+
export type SellerReceiptForwardConfig = {
|
|
79
|
+
runnerUrl?: string;
|
|
80
|
+
apiUrl?: string;
|
|
81
|
+
apiKey?: string;
|
|
82
|
+
fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
83
|
+
};
|
|
84
|
+
export type Seller = {
|
|
85
|
+
/** Asset Signer PDA derived from `sellerAgent.asset` — the on-chain `payTo`. */
|
|
86
|
+
payTo: string;
|
|
87
|
+
/** Resolved facilitator URL written to receipts (null if a custom client was passed). */
|
|
88
|
+
facilitatorUrl: string | null;
|
|
89
|
+
/** CAIP-2 network the seller settles on. */
|
|
90
|
+
network: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Wires real x402-on-Solana payment enforcement onto a Hono app. For each
|
|
94
|
+
* route entry (`'METHOD /path'`), 402 responses include a proper
|
|
95
|
+
* `paymentRequirements[]` JSON; clients (e.g. `@leashmarket/buyer-kit` or any
|
|
96
|
+
* `@x402/fetch` consumer) sign an SPL `TransferChecked` to the agent's
|
|
97
|
+
* Asset Signer PDA and replay the request with `X-PAYMENT`. The configured
|
|
98
|
+
* facilitator verifies + settles the transaction on-chain, and `onReceipt`
|
|
99
|
+
* is invoked with a tamper-evident `earn` `ReceiptV1` populated with the
|
|
100
|
+
* real Solana transaction signature.
|
|
101
|
+
*/
|
|
102
|
+
export declare function createSeller(app: Hono, opts: CreateSellerOptions): Seller;
|
|
103
|
+
/**
|
|
104
|
+
* Resolver shared with `@leashmarket/buyer-kit`. Lives here as a small inline
|
|
105
|
+
* copy (instead of importing from buyer-kit) so the seller package stays
|
|
106
|
+
* server-only and doesn't pull in the buyer's `@solana/kit` dependency.
|
|
107
|
+
*/
|
|
108
|
+
export declare function resolveSellerReceiptSink(onReceipt: CreateSellerOptions['onReceipt'], forward: SellerReceiptForwardConfig | undefined): (receipt: ReceiptV1) => Promise<void>;
|
|
109
|
+
//# sourceMappingURL=create-seller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-seller.d.ts","sourceRoot":"","sources":["../../src/hono/create-seller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAUL,KAAK,iBAAiB,EAGvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGvF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACxC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,CAAC,CAAC;IAC5C,WAAW,EAAE,iBAAiB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC1C;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACzC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;IACnE;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IACtC,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAClF,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAOF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAwIzE;AA2ID;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAC3C,OAAO,EAAE,0BAA0B,GAAG,SAAS,GAC9C,CAAC,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAmDvC"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { buildLeashFeeExtra, computeFeeAtoms as computeFeeAtomsHelper, finalizeReceipt, KNOWN_STABLE_SYMBOLS, lookupTokenBySymbol, networkFromCaip2, parseLeashFeeExtra, paymentRequirementsHash, requestHash, } from '@leashmarket/core';
|
|
2
|
+
import { paymentMiddlewareFromHTTPServer } from '@x402/hono';
|
|
3
|
+
import { x402HTTPResourceServer } from '@x402/core/server';
|
|
4
|
+
import { caip2ForSellerNetwork, createSvmResourceServer, DEFAULT_FACILITATOR_URL, } from '../x402/svm-server.js';
|
|
5
|
+
import { resolveSellerPayTo } from '../seller/agent-seller.js';
|
|
6
|
+
import { parsePrice } from '../receipts/price.js';
|
|
7
|
+
/**
|
|
8
|
+
* Wires real x402-on-Solana payment enforcement onto a Hono app. For each
|
|
9
|
+
* route entry (`'METHOD /path'`), 402 responses include a proper
|
|
10
|
+
* `paymentRequirements[]` JSON; clients (e.g. `@leashmarket/buyer-kit` or any
|
|
11
|
+
* `@x402/fetch` consumer) sign an SPL `TransferChecked` to the agent's
|
|
12
|
+
* Asset Signer PDA and replay the request with `X-PAYMENT`. The configured
|
|
13
|
+
* facilitator verifies + settles the transaction on-chain, and `onReceipt`
|
|
14
|
+
* is invoked with a tamper-evident `earn` `ReceiptV1` populated with the
|
|
15
|
+
* real Solana transaction signature.
|
|
16
|
+
*/
|
|
17
|
+
export function createSeller(app, opts) {
|
|
18
|
+
const payTo = resolveSellerPayTo(opts.umi, opts.sellerAgent);
|
|
19
|
+
const agent = String(opts.sellerAgent.asset);
|
|
20
|
+
const policyVersion = opts.policyVersion ?? '0.1';
|
|
21
|
+
const sellerNetwork = opts.network ?? 'solana-devnet';
|
|
22
|
+
const networkCaip2 = caip2ForSellerNetwork(sellerNetwork);
|
|
23
|
+
const state = { nonce: 0, prevReceiptHash: null };
|
|
24
|
+
// Same precedence as buyer-kit: explicit `false` => off, function =>
|
|
25
|
+
// user controls the sink, undefined => env + opts fan-out.
|
|
26
|
+
const receiptSink = resolveSellerReceiptSink(opts.onReceipt, opts.receipts);
|
|
27
|
+
const { server, facilitatorUrl } = createSvmResourceServer({
|
|
28
|
+
networks: [sellerNetwork],
|
|
29
|
+
facilitator: opts.facilitator ?? DEFAULT_FACILITATOR_URL,
|
|
30
|
+
});
|
|
31
|
+
const recordedFacilitator = typeof opts.facilitator === 'string'
|
|
32
|
+
? opts.facilitator
|
|
33
|
+
: (facilitatorUrl ?? DEFAULT_FACILITATOR_URL);
|
|
34
|
+
const tokenNetwork = networkAliasFor(sellerNetwork) === 'solana-mainnet' ? 'mainnet' : 'devnet';
|
|
35
|
+
const routes = {};
|
|
36
|
+
for (const [routeKey, cfg] of Object.entries(opts.routes)) {
|
|
37
|
+
const [method, path] = routeKey.split(/\s+/, 2);
|
|
38
|
+
if (!method || !path) {
|
|
39
|
+
throw new Error(`Invalid route key: ${routeKey}`);
|
|
40
|
+
}
|
|
41
|
+
const accepts = buildAccepts({
|
|
42
|
+
payTo,
|
|
43
|
+
networkCaip2,
|
|
44
|
+
tokenNetwork,
|
|
45
|
+
priceString: cfg.price,
|
|
46
|
+
currency: cfg.currency ?? 'USDC',
|
|
47
|
+
extraCurrencies: cfg.acceptsCurrencies ?? [],
|
|
48
|
+
});
|
|
49
|
+
routes[`${method.toUpperCase()} ${path}`] = {
|
|
50
|
+
description: cfg.description,
|
|
51
|
+
mimeType: cfg.mimeType ?? 'application/json',
|
|
52
|
+
accepts: accepts.length === 1 ? accepts[0] : accepts,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const httpServer = new x402HTTPResourceServer(server, routes);
|
|
56
|
+
/**
|
|
57
|
+
* `onAfterSettle` fires once the facilitator has confirmed the SPL
|
|
58
|
+
* transfer. The `result.transaction` is the real Solana signature.
|
|
59
|
+
*
|
|
60
|
+
* The receipt's `price` is sourced from the **settled** payment
|
|
61
|
+
* requirements (so multi-currency endpoints stamp the actual debited
|
|
62
|
+
* token), then enriched with the friendly Leash network slug.
|
|
63
|
+
*
|
|
64
|
+
* We additionally stamp `result.paymentRequirements = requirements`
|
|
65
|
+
* BEFORE the x402 middleware encodes `PAYMENT-RESPONSE`. Why: the
|
|
66
|
+
* upstream x402 SDK only puts the settlement `transaction` (and
|
|
67
|
+
* payer / network / amount) into the response header, not the
|
|
68
|
+
* matched `PaymentRequirements`. That leaves any buyer reading the
|
|
69
|
+
* header — including our own buyer-kit's `parseSettlement` — unable
|
|
70
|
+
* to recover the price/asset and forces them to stamp `price: null`
|
|
71
|
+
* on the spend receipt. Mutating `result` here lets the encoder
|
|
72
|
+
* pick up the requirements via JSON spread (the field rides along
|
|
73
|
+
* inside the same base64 payload), and `parseSettlement` already
|
|
74
|
+
* looks for `obj.paymentRequirements` on the decoded side, so the
|
|
75
|
+
* fix is end-to-end with zero changes on the buyer.
|
|
76
|
+
*
|
|
77
|
+
* We also fan into `extensions['leash.paymentRequirements']` as a
|
|
78
|
+
* second carrier for future buyers that prefer the namespaced
|
|
79
|
+
* extension surface (per x402's extension contract).
|
|
80
|
+
*/
|
|
81
|
+
server.onAfterSettle(async ({ requirements, result, transportContext }) => {
|
|
82
|
+
if (!result.success)
|
|
83
|
+
return;
|
|
84
|
+
// Cast through `unknown` because `SettleResponse` doesn't declare
|
|
85
|
+
// `paymentRequirements` in its type but the JSON encoder is
|
|
86
|
+
// permissive — extra fields round-trip cleanly.
|
|
87
|
+
result.paymentRequirements =
|
|
88
|
+
requirements;
|
|
89
|
+
const extensions = (result.extensions ?? {});
|
|
90
|
+
extensions['leash.paymentRequirements'] = requirements;
|
|
91
|
+
result.extensions = extensions;
|
|
92
|
+
const httpCtx = transportContext;
|
|
93
|
+
const reqCtx = httpCtx?.request;
|
|
94
|
+
const method = reqCtx?.method ?? 'POST';
|
|
95
|
+
const url = reqCtx?.adapter.getUrl?.() ?? reqCtx?.path ?? '';
|
|
96
|
+
const route = findRouteForPath(opts.routes, reqCtx);
|
|
97
|
+
const settledCurrency = lookupTokenBySymbol('USDC', tokenNetwork)?.mint === requirements.asset
|
|
98
|
+
? 'USDC'
|
|
99
|
+
: (lookupCurrencyBySymbol(requirements.asset, tokenNetwork) ?? route?.currency ?? 'USDC');
|
|
100
|
+
// Enrich the receipt's price with protocol-fee context when the
|
|
101
|
+
// settled requirements carry an `extra['leash.fee']` block. We
|
|
102
|
+
// compute the atomic fee + gross from the seller's net amount + bps
|
|
103
|
+
// (same logic as the buyer scheme + facilitator), so explorers can
|
|
104
|
+
// render `gross / fee / net` without re-deriving anything. Vanilla
|
|
105
|
+
// x402 settlements (no fee block) keep the slim shape.
|
|
106
|
+
const feeExtra = parseLeashFeeExtra((requirements.extra ?? null));
|
|
107
|
+
const netAtomic = BigInt(requirements.amount);
|
|
108
|
+
const feeAtomic = feeExtra ? computeFeeAtomsHelper(netAtomic, feeExtra.bps) : 0n;
|
|
109
|
+
const grossAtomic = netAtomic + feeAtomic;
|
|
110
|
+
const enrichedPrice = {
|
|
111
|
+
amount: requirements.amount,
|
|
112
|
+
currency: settledCurrency,
|
|
113
|
+
network: networkFromCaip2(networkCaip2) ?? sellerNetwork,
|
|
114
|
+
asset: requirements.asset,
|
|
115
|
+
...(feeExtra
|
|
116
|
+
? {
|
|
117
|
+
fee: feeAtomic.toString(),
|
|
118
|
+
gross: grossAtomic.toString(),
|
|
119
|
+
feeBps: feeExtra.bps,
|
|
120
|
+
feeAuthority: feeExtra.feeAuthority,
|
|
121
|
+
}
|
|
122
|
+
: {}),
|
|
123
|
+
};
|
|
124
|
+
await emitEarnReceipt({
|
|
125
|
+
state,
|
|
126
|
+
agent,
|
|
127
|
+
policyVersion,
|
|
128
|
+
method,
|
|
129
|
+
url,
|
|
130
|
+
bodyText: null,
|
|
131
|
+
responseStatus: 200,
|
|
132
|
+
txSig: result.transaction ?? null,
|
|
133
|
+
facilitator: recordedFacilitator,
|
|
134
|
+
paymentReqHash: paymentRequirementsHash(requirements),
|
|
135
|
+
price: enrichedPrice,
|
|
136
|
+
sink: receiptSink,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
app.use(paymentMiddlewareFromHTTPServer(httpServer));
|
|
140
|
+
return { payTo, facilitatorUrl: recordedFacilitator, network: networkCaip2 };
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Find the user-supplied SellerRouteConfig that matches a verified payment.
|
|
144
|
+
* Matches `'METHOD /path'` keys against the live request context; falls back
|
|
145
|
+
* to the first entry so single-route sellers always resolve correctly.
|
|
146
|
+
*/
|
|
147
|
+
function findRouteForPath(routes, reqCtx) {
|
|
148
|
+
if (reqCtx) {
|
|
149
|
+
const path = reqCtx.path;
|
|
150
|
+
const method = reqCtx.method.toUpperCase();
|
|
151
|
+
for (const [key, cfg] of Object.entries(routes)) {
|
|
152
|
+
const [m, p] = key.split(/\s+/, 2);
|
|
153
|
+
if (m && p && m.toUpperCase() === method && p === path)
|
|
154
|
+
return cfg;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const first = Object.values(routes)[0];
|
|
158
|
+
return first ?? null;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Build the x402 `accepts[]` payment options for a route. The primary
|
|
162
|
+
* `currency` always comes first; any `extraCurrencies` are appended at
|
|
163
|
+
* the same dollar-equivalent amount (1:1 USD assumption is fine for v0.1
|
|
164
|
+
* since we only support 6-dec USD-pegged stables in the registry).
|
|
165
|
+
*
|
|
166
|
+
* Each option is encoded as an `AssetAmount` so the facilitator settles
|
|
167
|
+
* in exactly the buyer-chosen mint — no implicit USDC fallback.
|
|
168
|
+
*/
|
|
169
|
+
function buildAccepts(args) {
|
|
170
|
+
const all = uniq([args.currency, ...args.extraCurrencies]);
|
|
171
|
+
// One-shot fee descriptor reused across every accepts[] entry. Bps +
|
|
172
|
+
// authority are the same for the whole route — only the destination
|
|
173
|
+
// ATA differs per asset, and that's derived buyer/facilitator-side
|
|
174
|
+
// from `(asset, tokenProgram, authority)` so it never lives on the
|
|
175
|
+
// wire.
|
|
176
|
+
const leashFee = buildLeashFeeExtra({ network: args.tokenNetwork });
|
|
177
|
+
return all.map((currency) => {
|
|
178
|
+
const parsed = parsePrice(args.priceString, {
|
|
179
|
+
network: args.tokenNetwork,
|
|
180
|
+
defaultCurrency: currency,
|
|
181
|
+
});
|
|
182
|
+
if (!parsed) {
|
|
183
|
+
throw new Error(`Invalid price "${args.priceString}" for currency ${currency} on ${args.tokenNetwork}.`);
|
|
184
|
+
}
|
|
185
|
+
// `extra['leash.fee']` rides along inside the `AssetAmount.extra`
|
|
186
|
+
// bag and surfaces on `paymentRequirements.extra` at 402 time. The
|
|
187
|
+
// x402 SDK forwards arbitrary extras through verbatim, so the
|
|
188
|
+
// buyer-kit / facilitator can read it without touching this layer.
|
|
189
|
+
return {
|
|
190
|
+
scheme: 'exact',
|
|
191
|
+
network: args.networkCaip2,
|
|
192
|
+
payTo: args.payTo,
|
|
193
|
+
price: { asset: parsed.asset, amount: parsed.amount, extra: { 'leash.fee': leashFee } },
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
function uniq(arr) {
|
|
198
|
+
return Array.from(new Set(arr));
|
|
199
|
+
}
|
|
200
|
+
/** Reverse-resolve a stablecoin symbol from a settled mint, if known. */
|
|
201
|
+
function lookupCurrencyBySymbol(asset, network) {
|
|
202
|
+
for (const sym of KNOWN_STABLE_SYMBOLS) {
|
|
203
|
+
if (lookupTokenBySymbol(sym, network)?.mint === asset)
|
|
204
|
+
return sym;
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* v0.1 collapses `solana-testnet` → `solana-devnet` for the token registry
|
|
210
|
+
* lookup. Mirrors {@link networkAlias} from `../x402/svm-server.ts` but
|
|
211
|
+
* exists locally to avoid a circular import in barrel files.
|
|
212
|
+
*/
|
|
213
|
+
function networkAliasFor(net) {
|
|
214
|
+
return net === 'solana-mainnet' ? 'solana-mainnet' : 'solana-devnet';
|
|
215
|
+
}
|
|
216
|
+
async function emitEarnReceipt(args) {
|
|
217
|
+
// The sink is always callable; it short-circuits internally when the
|
|
218
|
+
// user passed `onReceipt: false` or `LEASH_RECEIPTS_DISABLED=1`.
|
|
219
|
+
// We still build the receipt in that case so the chain (`prev_receipt_hash`)
|
|
220
|
+
// stays consistent across calls — disabling publishing must not mutate
|
|
221
|
+
// the receipt graph.
|
|
222
|
+
const draft = {
|
|
223
|
+
v: '0.1',
|
|
224
|
+
kind: 'earn',
|
|
225
|
+
agent: args.agent,
|
|
226
|
+
nonce: args.state.nonce,
|
|
227
|
+
ts: new Date().toISOString(),
|
|
228
|
+
policy_v: args.policyVersion,
|
|
229
|
+
request: {
|
|
230
|
+
method: args.method,
|
|
231
|
+
url: args.url,
|
|
232
|
+
body_hash: args.bodyText
|
|
233
|
+
? requestHash({ method: args.method, url: args.url, body: args.bodyText })
|
|
234
|
+
: null,
|
|
235
|
+
},
|
|
236
|
+
decision: 'allow',
|
|
237
|
+
reason: null,
|
|
238
|
+
price: args.price,
|
|
239
|
+
facilitator: args.facilitator,
|
|
240
|
+
tx_sig: args.txSig,
|
|
241
|
+
payment_requirements_hash: args.paymentReqHash,
|
|
242
|
+
response: { status: args.responseStatus, body_hash: null },
|
|
243
|
+
prev_receipt_hash: args.state.prevReceiptHash,
|
|
244
|
+
};
|
|
245
|
+
const receipt = finalizeReceipt(draft);
|
|
246
|
+
args.state.nonce += 1;
|
|
247
|
+
args.state.prevReceiptHash = receipt.receipt_hash;
|
|
248
|
+
await args.sink(receipt);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Resolver shared with `@leashmarket/buyer-kit`. Lives here as a small inline
|
|
252
|
+
* copy (instead of importing from buyer-kit) so the seller package stays
|
|
253
|
+
* server-only and doesn't pull in the buyer's `@solana/kit` dependency.
|
|
254
|
+
*/
|
|
255
|
+
export function resolveSellerReceiptSink(onReceipt, forward) {
|
|
256
|
+
if (onReceipt === false || envFlag('LEASH_RECEIPTS_DISABLED')) {
|
|
257
|
+
return async () => { };
|
|
258
|
+
}
|
|
259
|
+
if (typeof onReceipt === 'function') {
|
|
260
|
+
return async (receipt) => {
|
|
261
|
+
try {
|
|
262
|
+
await onReceipt(receipt);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// Intentionally swallowed.
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
const env = readEnvForwardConfig();
|
|
270
|
+
const merged = {
|
|
271
|
+
runnerUrl: forward?.runnerUrl ?? env.runnerUrl,
|
|
272
|
+
apiUrl: forward?.apiUrl ?? env.apiUrl,
|
|
273
|
+
apiKey: forward?.apiKey ?? env.apiKey,
|
|
274
|
+
...(forward?.fetch ? { fetch: forward.fetch } : {}),
|
|
275
|
+
};
|
|
276
|
+
const fetchImpl = merged.fetch ?? globalThis.fetch;
|
|
277
|
+
return async (receipt) => {
|
|
278
|
+
const tasks = [];
|
|
279
|
+
if (merged.runnerUrl) {
|
|
280
|
+
tasks.push(doPost(fetchImpl, `${merged.runnerUrl.replace(/\/+$/, '')}/a/${encodeURIComponent(receipt.agent)}/receipts`, receipt));
|
|
281
|
+
}
|
|
282
|
+
if (merged.apiUrl && merged.apiKey) {
|
|
283
|
+
tasks.push(doPost(fetchImpl, `${merged.apiUrl.replace(/\/+$/, '')}/v1/receipts/${encodeURIComponent(receipt.agent)}`, receipt, { authorization: `Bearer ${merged.apiKey}` }));
|
|
284
|
+
}
|
|
285
|
+
if (tasks.length === 0)
|
|
286
|
+
return;
|
|
287
|
+
const settled = await Promise.allSettled(tasks);
|
|
288
|
+
for (const r of settled) {
|
|
289
|
+
if (r.status === 'rejected') {
|
|
290
|
+
// eslint-disable-next-line no-console
|
|
291
|
+
console.warn('[seller-kit] receipt forward failed:', r.reason.message);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
async function doPost(fetchImpl, url, receipt, extraHeaders = {}) {
|
|
297
|
+
const res = await fetchImpl(url, {
|
|
298
|
+
method: 'POST',
|
|
299
|
+
headers: { 'content-type': 'application/json', ...extraHeaders },
|
|
300
|
+
body: JSON.stringify(receipt),
|
|
301
|
+
});
|
|
302
|
+
if (!res.ok) {
|
|
303
|
+
const detail = await res.text().catch(() => '');
|
|
304
|
+
throw new Error(`POST ${url} -> ${res.status}: ${detail.slice(0, 200)}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function readEnvForwardConfig() {
|
|
308
|
+
if (typeof process === 'undefined' || !process.env)
|
|
309
|
+
return {};
|
|
310
|
+
const env = process.env;
|
|
311
|
+
return {
|
|
312
|
+
...(env.LEASH_RUNNER_URL ? { runnerUrl: env.LEASH_RUNNER_URL } : {}),
|
|
313
|
+
...(env.LEASH_API_URL ? { apiUrl: env.LEASH_API_URL } : {}),
|
|
314
|
+
...(env.LEASH_API_KEY ? { apiKey: env.LEASH_API_KEY } : {}),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function envFlag(name) {
|
|
318
|
+
if (typeof process === 'undefined' || !process.env)
|
|
319
|
+
return false;
|
|
320
|
+
const raw = process.env[name];
|
|
321
|
+
if (!raw)
|
|
322
|
+
return false;
|
|
323
|
+
return raw === '1' || raw.toLowerCase() === 'true';
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=create-seller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-seller.js","sourceRoot":"","sources":["../../src/hono/create-seller.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,kBAAkB,EAClB,eAAe,IAAI,qBAAqB,EACxC,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,GAIZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAQ3D,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,GAExB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAA0B,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA+FlD;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,GAAS,EAAE,IAAyB;IAC/D,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC;IAClD,MAAM,aAAa,GAAuB,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;IAC1E,MAAM,YAAY,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IAC/D,qEAAqE;IACrE,2DAA2D;IAC3D,MAAM,WAAW,GAAG,wBAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE5E,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,uBAAuB,CAAC;QACzD,QAAQ,EAAE,CAAC,aAAa,CAAC;QACzB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,uBAAuB;KACzD,CAAC,CAAC;IAEH,MAAM,mBAAmB,GACvB,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QAClC,CAAC,CAAC,IAAI,CAAC,WAAW;QAClB,CAAC,CAAC,CAAC,cAAc,IAAI,uBAAuB,CAAC,CAAC;IAElD,MAAM,YAAY,GAChB,eAAe,CAAC,aAAa,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE7E,MAAM,MAAM,GAAgC,EAAE,CAAC;IAC/C,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC;YAC3B,KAAK;YACL,YAAY;YACZ,YAAY;YACZ,WAAW,EAAE,GAAG,CAAC,KAAK;YACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,MAAM;YAChC,eAAe,EAAE,GAAG,CAAC,iBAAiB,IAAI,EAAE;SAC7C,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,GAAG;YAC1C,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,kBAAkB;YAC5C,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;SACrD,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9D;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACxE,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QAC5B,kEAAkE;QAClE,4DAA4D;QAC5D,gDAAgD;QAC/C,MAAkE,CAAC,mBAAmB;YACrF,YAAY,CAAC;QACf,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAA4B,CAAC;QACxE,UAAU,CAAC,2BAA2B,CAAC,GAAG,YAAY,CAAC;QACvD,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QAC/B,MAAM,OAAO,GAAG,gBAAoD,CAAC;QACrE,MAAM,MAAM,GAAmC,OAAO,EAAE,OAAO,CAAC;QAChE,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,eAAe,GACnB,mBAAmB,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,IAAI,KAAK,YAAY,CAAC,KAAK;YACpE,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,CAAC,sBAAsB,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,KAAK,EAAE,QAAQ,IAAI,MAAM,CAAC,CAAC;QAC9F,gEAAgE;QAChE,+DAA+D;QAC/D,oEAAoE;QACpE,mEAAmE;QACnE,mEAAmE;QACnE,uDAAuD;QACvD,MAAM,QAAQ,GAAG,kBAAkB,CACjC,CAAC,YAAY,CAAC,KAAK,IAAI,IAAI,CAAmC,CAC/D,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;QAC1C,MAAM,aAAa,GAAuB;YACxC,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,QAAQ,EAAE,eAAe;YACzB,OAAO,EAAE,gBAAgB,CAAC,YAAY,CAAC,IAAI,aAAa;YACxD,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,GAAG,CAAC,QAAQ;gBACV,CAAC,CAAC;oBACE,GAAG,EAAE,SAAS,CAAC,QAAQ,EAAE;oBACzB,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;oBAC7B,MAAM,EAAE,QAAQ,CAAC,GAAG;oBACpB,YAAY,EAAE,QAAQ,CAAC,YAAY;iBACpC;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;QACF,MAAM,eAAe,CAAC;YACpB,KAAK;YACL,KAAK;YACL,aAAa;YACb,MAAM;YACN,GAAG;YACH,QAAQ,EAAE,IAAI;YACd,cAAc,EAAE,GAAG;YACnB,KAAK,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;YACjC,WAAW,EAAE,mBAAmB;YAChC,cAAc,EAAE,uBAAuB,CAAC,YAAY,CAAC;YACrD,KAAK,EAAE,aAAa;YACpB,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,+BAA+B,CAAC,UAAU,CAAC,CAAC,CAAC;IAErD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,MAAyC,EACzC,MAAsC;IAEtC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI;gBAAE,OAAO,GAAG,CAAC;QACrE,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,IAOrB;IACC,MAAM,GAAG,GAAG,IAAI,CAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IAC9E,qEAAqE;IACrE,oEAAoE;IACpE,mEAAmE;IACnE,mEAAmE;IACnE,QAAQ;IACR,MAAM,QAAQ,GAAkB,kBAAkB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IACnF,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE;YAC1C,OAAO,EAAE,IAAI,CAAC,YAAY;YAC1B,eAAe,EAAE,QAAQ;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,CAAC,WAAW,kBAAkB,QAAQ,OAAO,IAAI,CAAC,YAAY,GAAG,CACxF,CAAC;QACJ,CAAC;QACD,kEAAkE;QAClE,mEAAmE;QACnE,8DAA8D;QAC9D,mEAAmE;QACnE,OAAO;YACL,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,IAAI,CAAC,YAAwC;YACtD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE;SACzF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,IAAI,CAAI,GAAqB;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,yEAAyE;AACzE,SAAS,sBAAsB,CAAC,KAAa,EAAE,OAAqB;IAClE,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACvC,IAAI,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC;IACpE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAuB;IAC9C,OAAO,GAAG,KAAK,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC;AACvE,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAa9B;IACC,qEAAqE;IACrE,iEAAiE;IACjE,6EAA6E;IAC7E,uEAAuE;IACvE,qBAAqB;IACrB,MAAM,KAAK,GAAG;QACZ,CAAC,EAAE,KAAc;QACjB,IAAI,EAAE,MAAe;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK;QACvB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,QAAQ,EAAE,IAAI,CAAC,aAAa;QAC5B,OAAO,EAAE;YACP,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,SAAS,EAAE,IAAI,CAAC,QAAQ;gBACtB,CAAC,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC1E,CAAC,CAAC,IAAI;SACT;QACD,QAAQ,EAAE,OAAgB;QAC1B,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,KAAK;QAClB,yBAAyB,EAAE,IAAI,CAAC,cAAc;QAC9C,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,IAAI,EAAE;QAC1D,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe;KAC9C,CAAC;IACF,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IAClD,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAA2C,EAC3C,OAA+C;IAE/C,IAAI,SAAS,KAAK,KAAK,IAAI,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC9D,OAAO,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,2BAA2B;YAC7B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IACnC,MAAM,MAAM,GAA+B;QACzC,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC,SAAS;QAC9C,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM;QACrC,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM;QACrC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IACnD,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,KAAK,GAAuB,EAAE,CAAC;QACrC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CACR,MAAM,CACJ,SAAS,EACT,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EACzF,OAAO,CACR,CACF,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CACR,MAAM,CACJ,SAAS,EACT,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EACvF,OAAO,EACP,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,EAAE,CAC7C,CACF,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC5B,sCAAsC;gBACtC,OAAO,CAAC,IAAI,CAAC,sCAAsC,EAAG,CAAC,CAAC,MAAgB,CAAC,OAAO,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,SAA2D,EAC3D,GAAW,EACX,OAAkB,EAClB,eAAuC,EAAE;IAEzC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;QAC/B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,YAAY,EAAE;QAChE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,OAAO;QACL,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACjE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal x402-shaped gate: 402 without payment header, forwards when present.
|
|
4
|
+
* Swap for `@x402/hono` `paymentMiddleware` + PayAI facilitator in production.
|
|
5
|
+
*/
|
|
6
|
+
export declare function simpleX402Gate(): MiddlewareHandler;
|
|
7
|
+
//# sourceMappingURL=simple-x402.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-x402.d.ts","sourceRoot":"","sources":["../../src/hono/simple-x402.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI9C;;;GAGG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAOlD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const HEADER = 'x-payment';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal x402-shaped gate: 402 without payment header, forwards when present.
|
|
4
|
+
* Swap for `@x402/hono` `paymentMiddleware` + PayAI facilitator in production.
|
|
5
|
+
*/
|
|
6
|
+
export function simpleX402Gate() {
|
|
7
|
+
return async (c, next) => {
|
|
8
|
+
if (!c.req.header(HEADER)) {
|
|
9
|
+
return c.json({ error: 'payment_required', protocol: 'x402-shaped' }, 402);
|
|
10
|
+
}
|
|
11
|
+
await next();
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=simple-x402.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-x402.js","sourceRoot":"","sources":["../../src/hono/simple-x402.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAG,WAAW,CAAC;AAE3B;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ReceiptV1 } from '@leashmarket/schemas';
|
|
2
|
+
import { type KnownStableSymbol, type TokenNetwork } from '@leashmarket/core';
|
|
3
|
+
type Price = NonNullable<ReceiptV1['price']>;
|
|
4
|
+
/**
|
|
5
|
+
* Parse a human-readable `price` string used in `SellerRouteConfig`
|
|
6
|
+
* (e.g. `"$0.001"`, `"0.01 USDG"`, `"0.5"`) into the structured
|
|
7
|
+
* `{ amount, currency, asset? }` shape stored inside `ReceiptV1.price`.
|
|
8
|
+
*
|
|
9
|
+
* `amount` is returned as the **atomic integer** for the resolved currency
|
|
10
|
+
* on the supplied `network` (e.g. `"$0.001"` → `"1000"` for USDC's 6
|
|
11
|
+
* decimals). This keeps every receipt — earn or spend — using the same
|
|
12
|
+
* on-the-wire representation, so format helpers in `@leashmarket/core/format`
|
|
13
|
+
* never have to guess whether a string is decimal or atomic.
|
|
14
|
+
*
|
|
15
|
+
* Resolution rules:
|
|
16
|
+
* - A leading `$` (or trailing `USD`) is treated as the supplied
|
|
17
|
+
* `defaultCurrency` (defaults to `'USDC'`). v0.1 settles only in known
|
|
18
|
+
* stablecoins on Solana, so dollars map cleanly onto a 6-dec stable.
|
|
19
|
+
* - A trailing token symbol (`USDC`, `USDT`, `USDG`) is preserved.
|
|
20
|
+
* - A bare number falls back to `defaultCurrency`.
|
|
21
|
+
* - Unknown stables (or non-stables in v0.1) return `null` so callers can
|
|
22
|
+
* fail loudly instead of stamping a wrong asset onto the receipt.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parsePrice(input: string, opts?: {
|
|
25
|
+
network?: TokenNetwork;
|
|
26
|
+
defaultCurrency?: KnownStableSymbol;
|
|
27
|
+
}): Price | null;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=price.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price.d.ts","sourceRoot":"","sources":["../../src/receipts/price.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAE3B,KAAK,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,YAAY,CAAC;IAAC,eAAe,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACzE,KAAK,GAAG,IAAI,CAyBd"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { decimalToAtomic, KNOWN_STABLE_SYMBOLS, lookupTokenBySymbol, } from '@leashmarket/core';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a human-readable `price` string used in `SellerRouteConfig`
|
|
4
|
+
* (e.g. `"$0.001"`, `"0.01 USDG"`, `"0.5"`) into the structured
|
|
5
|
+
* `{ amount, currency, asset? }` shape stored inside `ReceiptV1.price`.
|
|
6
|
+
*
|
|
7
|
+
* `amount` is returned as the **atomic integer** for the resolved currency
|
|
8
|
+
* on the supplied `network` (e.g. `"$0.001"` → `"1000"` for USDC's 6
|
|
9
|
+
* decimals). This keeps every receipt — earn or spend — using the same
|
|
10
|
+
* on-the-wire representation, so format helpers in `@leashmarket/core/format`
|
|
11
|
+
* never have to guess whether a string is decimal or atomic.
|
|
12
|
+
*
|
|
13
|
+
* Resolution rules:
|
|
14
|
+
* - A leading `$` (or trailing `USD`) is treated as the supplied
|
|
15
|
+
* `defaultCurrency` (defaults to `'USDC'`). v0.1 settles only in known
|
|
16
|
+
* stablecoins on Solana, so dollars map cleanly onto a 6-dec stable.
|
|
17
|
+
* - A trailing token symbol (`USDC`, `USDT`, `USDG`) is preserved.
|
|
18
|
+
* - A bare number falls back to `defaultCurrency`.
|
|
19
|
+
* - Unknown stables (or non-stables in v0.1) return `null` so callers can
|
|
20
|
+
* fail loudly instead of stamping a wrong asset onto the receipt.
|
|
21
|
+
*/
|
|
22
|
+
export function parsePrice(input, opts = {}) {
|
|
23
|
+
const trimmed = input.trim();
|
|
24
|
+
if (!trimmed)
|
|
25
|
+
return null;
|
|
26
|
+
const network = opts.network ?? 'devnet';
|
|
27
|
+
const defaultCurrency = opts.defaultCurrency ?? 'USDC';
|
|
28
|
+
const dollar = trimmed.match(/^\$\s*([0-9]+(?:\.[0-9]+)?)$/);
|
|
29
|
+
if (dollar) {
|
|
30
|
+
return finalize(dollar[1], defaultCurrency, network);
|
|
31
|
+
}
|
|
32
|
+
const suffixed = trimmed.match(/^([0-9]+(?:\.[0-9]+)?)\s*([A-Z][A-Z0-9]{1,9})$/i);
|
|
33
|
+
if (suffixed) {
|
|
34
|
+
const sym = suffixed[2].toUpperCase();
|
|
35
|
+
const currency = sym === 'USD' ? defaultCurrency : sym;
|
|
36
|
+
if (!isKnownStable(currency))
|
|
37
|
+
return null;
|
|
38
|
+
return finalize(suffixed[1], currency, network);
|
|
39
|
+
}
|
|
40
|
+
const bare = trimmed.match(/^([0-9]+(?:\.[0-9]+)?)$/);
|
|
41
|
+
if (bare) {
|
|
42
|
+
return finalize(bare[1], defaultCurrency, network);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function finalize(decimal, currency, network) {
|
|
47
|
+
const token = lookupTokenBySymbol(currency, network);
|
|
48
|
+
if (!token)
|
|
49
|
+
return null;
|
|
50
|
+
const atomic = decimalToAtomic(decimal, token.decimals);
|
|
51
|
+
if (atomic === null)
|
|
52
|
+
return null;
|
|
53
|
+
return { amount: atomic.toString(), currency, asset: token.mint };
|
|
54
|
+
}
|
|
55
|
+
function isKnownStable(symbol) {
|
|
56
|
+
return KNOWN_STABLE_SYMBOLS.includes(symbol);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=price.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price.js","sourceRoot":"","sources":["../../src/receipts/price.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAI3B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CACxB,KAAa,EACb,OAAwE,EAAE;IAE1E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,OAAO,GAAiB,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC;IACvD,MAAM,eAAe,GAAsB,IAAI,CAAC,eAAe,IAAI,MAAM,CAAC;IAE1E,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC7D,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAClF,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC;QACvD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACtD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CACf,OAAe,EACf,QAA2B,EAC3B,OAAqB;IAErB,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AACpE,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,OAAQ,oBAA8C,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/receipts/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/receipts/store.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Context, PublicKey } from '@metaplex-foundation/umi';
|
|
2
|
+
export type AgentSellerConfig = {
|
|
3
|
+
asset: string | PublicKey;
|
|
4
|
+
};
|
|
5
|
+
export declare function resolveSellerPayTo(umi: Pick<Context, 'eddsa' | 'programs'>, cfg: AgentSellerConfig): string;
|
|
6
|
+
//# sourceMappingURL=agent-seller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-seller.d.ts","sourceRoot":"","sources":["../../src/seller/agent-seller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC,EACxC,GAAG,EAAE,iBAAiB,GACrB,MAAM,CAIR"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { findAssetSignerPda } from '@metaplex-foundation/mpl-core';
|
|
2
|
+
import { publicKey } from '@metaplex-foundation/umi';
|
|
3
|
+
export function resolveSellerPayTo(umi, cfg) {
|
|
4
|
+
const asset = typeof cfg.asset === 'string' ? publicKey(cfg.asset) : cfg.asset;
|
|
5
|
+
const [addr] = findAssetSignerPda(umi, { asset });
|
|
6
|
+
return String(addr);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=agent-seller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-seller.js","sourceRoot":"","sources":["../../src/seller/agent-seller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAMrD,MAAM,UAAU,kBAAkB,CAChC,GAAwC,EACxC,GAAsB;IAEtB,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;IAC/E,MAAM,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FacilitatorClient } from '@x402/core/server';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory x402 facilitator for Vitest and demo smoke tests. Avoids HTTP
|
|
4
|
+
* round-trips to the default hosted facilitator (which may be unreachable
|
|
5
|
+
* in CI or offline).
|
|
6
|
+
*/
|
|
7
|
+
export declare function stubFacilitator(opts?: {
|
|
8
|
+
txSig?: string;
|
|
9
|
+
}): FacilitatorClient;
|
|
10
|
+
//# sourceMappingURL=stub-facilitator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub-facilitator.d.ts","sourceRoot":"","sources":["../../src/test-utils/stub-facilitator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAY3D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAoC5E"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { SOLANA_DEVNET_CAIP2 } from '@x402/svm';
|
|
2
|
+
const FACILITATOR_FEEPAYER = 'FaciliTatoR1111111111111111111111111111111';
|
|
3
|
+
/**
|
|
4
|
+
* In-memory x402 facilitator for Vitest and demo smoke tests. Avoids HTTP
|
|
5
|
+
* round-trips to the default hosted facilitator (which may be unreachable
|
|
6
|
+
* in CI or offline).
|
|
7
|
+
*/
|
|
8
|
+
export function stubFacilitator(opts) {
|
|
9
|
+
let nonce = 0;
|
|
10
|
+
return {
|
|
11
|
+
async getSupported() {
|
|
12
|
+
return {
|
|
13
|
+
kinds: [
|
|
14
|
+
{
|
|
15
|
+
x402Version: 2,
|
|
16
|
+
scheme: 'exact',
|
|
17
|
+
network: SOLANA_DEVNET_CAIP2,
|
|
18
|
+
extra: { feePayer: FACILITATOR_FEEPAYER },
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
extensions: [],
|
|
22
|
+
signers: {},
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
async verify(_payload, _requirements) {
|
|
26
|
+
return { isValid: true, payer: 'Buyer1111111111111111111111111111111111' };
|
|
27
|
+
},
|
|
28
|
+
async settle(_payload, requirements) {
|
|
29
|
+
nonce += 1;
|
|
30
|
+
return {
|
|
31
|
+
success: true,
|
|
32
|
+
transaction: `${opts?.txSig ?? 'sig'}-${nonce}`,
|
|
33
|
+
network: requirements.network,
|
|
34
|
+
payer: 'Buyer1111111111111111111111111111111111',
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=stub-facilitator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub-facilitator.js","sourceRoot":"","sources":["../../src/test-utils/stub-facilitator.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,oBAAoB,GAAG,4CAA4C,CAAC;AAE1E;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO;QACL,KAAK,CAAC,YAAY;YAChB,OAAO;gBACL,KAAK,EAAE;oBACL;wBACE,WAAW,EAAE,CAAC;wBACd,MAAM,EAAE,OAAO;wBACf,OAAO,EAAE,mBAAmB;wBAC5B,KAAK,EAAE,EAAE,QAAQ,EAAE,oBAAoB,EAAE;qBAC1C;iBACF;gBACD,UAAU,EAAE,EAAE;gBACd,OAAO,EAAE,EAAE;aACZ,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,MAAM,CACV,QAAwB,EACxB,aAAkC;YAElC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC;QAC7E,CAAC;QACD,KAAK,CAAC,MAAM,CACV,QAAwB,EACxB,YAAiC;YAEjC,KAAK,IAAI,CAAC,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE;gBAC/C,OAAO,EAAE,YAAY,CAAC,OAAO;gBAC7B,KAAK,EAAE,yCAAyC;aACjD,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { x402ResourceServer } from '@x402/core/server';
|
|
2
|
+
import type { FacilitatorClient } from '@x402/core/server';
|
|
3
|
+
import type { Network } from '@x402/core/types';
|
|
4
|
+
export type LeashSellerNetwork = 'solana-mainnet' | 'solana-devnet' | 'solana-testnet';
|
|
5
|
+
export declare function caip2ForSellerNetwork(network: LeashSellerNetwork): Network;
|
|
6
|
+
/**
|
|
7
|
+
* Collapse `solana-testnet` → `solana-devnet` for the purposes of choosing
|
|
8
|
+
* a facilitator / settlement network. v0.1 does not have a public testnet
|
|
9
|
+
* facilitator, so testnet endpoints settle on devnet rails.
|
|
10
|
+
*
|
|
11
|
+
* Used by the public `/x/<id>` route so seller links built on testnet
|
|
12
|
+
* still work end-to-end without a dedicated facilitator deploy.
|
|
13
|
+
*/
|
|
14
|
+
export declare function networkAlias(network: LeashSellerNetwork): 'solana-mainnet' | 'solana-devnet';
|
|
15
|
+
/**
|
|
16
|
+
* Backwards-compatible alias. New code should prefer
|
|
17
|
+
* {@link defaultFacilitatorFor} from `@leashmarket/core` so devnet and mainnet pick
|
|
18
|
+
* appropriate hosts and `LEASH_FACILITATOR_URL` overrides flow uniformly.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_FACILITATOR_URL = "https://devnet-facilitator.leash.market";
|
|
21
|
+
export type CreateSvmResourceServerOptions = {
|
|
22
|
+
/** CAIP-2 networks the seller accepts. Defaults to `['solana-devnet']`. */
|
|
23
|
+
networks?: LeashSellerNetwork[];
|
|
24
|
+
/**
|
|
25
|
+
* Hosted x402 facilitator. Defaults to `https://facilitator.svmacc.tech`,
|
|
26
|
+
* the public SVM facilitator (gas-sponsored, no signup). Pass a different
|
|
27
|
+
* URL or a fully-built `FacilitatorClient` to point at PayAI, Corbits, or
|
|
28
|
+
* a self-hosted instance.
|
|
29
|
+
*/
|
|
30
|
+
facilitator?: string | FacilitatorClient;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Build an `x402ResourceServer` configured with the SVM exact-payment scheme
|
|
34
|
+
* for one or more Solana clusters and a hosted facilitator client. This is
|
|
35
|
+
* what `createSeller` registers under the hood; export it so advanced
|
|
36
|
+
* callers can attach `onAfterSettle`/`onSettleFailure` hooks of their own.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSvmResourceServer(opts?: CreateSvmResourceServerOptions): {
|
|
39
|
+
server: x402ResourceServer;
|
|
40
|
+
facilitatorUrl: string | null;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=svm-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svm-server.d.ts","sourceRoot":"","sources":["../../src/x402/svm-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKhD,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAQvF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAE1E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,eAAe,CAE5F;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,4CAA2B,CAAC;AAEhE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;CAC1C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,8BAAmC,GAAG;IAClF,MAAM,EAAE,kBAAkB,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAiBA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { HTTPFacilitatorClient, x402ResourceServer } from '@x402/core/server';
|
|
2
|
+
import { ExactSvmScheme } from '@x402/svm/exact/server';
|
|
3
|
+
import { SOLANA_DEVNET_CAIP2, SOLANA_MAINNET_CAIP2, SOLANA_TESTNET_CAIP2 } from '@x402/svm';
|
|
4
|
+
import { defaultFacilitatorFor, FALLBACK_FACILITATOR_URL } from '@leashmarket/core';
|
|
5
|
+
const NETWORK_TO_CAIP2 = {
|
|
6
|
+
'solana-mainnet': SOLANA_MAINNET_CAIP2,
|
|
7
|
+
'solana-devnet': SOLANA_DEVNET_CAIP2,
|
|
8
|
+
'solana-testnet': SOLANA_TESTNET_CAIP2,
|
|
9
|
+
};
|
|
10
|
+
export function caip2ForSellerNetwork(network) {
|
|
11
|
+
return NETWORK_TO_CAIP2[network];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Collapse `solana-testnet` → `solana-devnet` for the purposes of choosing
|
|
15
|
+
* a facilitator / settlement network. v0.1 does not have a public testnet
|
|
16
|
+
* facilitator, so testnet endpoints settle on devnet rails.
|
|
17
|
+
*
|
|
18
|
+
* Used by the public `/x/<id>` route so seller links built on testnet
|
|
19
|
+
* still work end-to-end without a dedicated facilitator deploy.
|
|
20
|
+
*/
|
|
21
|
+
export function networkAlias(network) {
|
|
22
|
+
return network === 'solana-mainnet' ? 'solana-mainnet' : 'solana-devnet';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Backwards-compatible alias. New code should prefer
|
|
26
|
+
* {@link defaultFacilitatorFor} from `@leashmarket/core` so devnet and mainnet pick
|
|
27
|
+
* appropriate hosts and `LEASH_FACILITATOR_URL` overrides flow uniformly.
|
|
28
|
+
*/
|
|
29
|
+
export const DEFAULT_FACILITATOR_URL = FALLBACK_FACILITATOR_URL;
|
|
30
|
+
/**
|
|
31
|
+
* Build an `x402ResourceServer` configured with the SVM exact-payment scheme
|
|
32
|
+
* for one or more Solana clusters and a hosted facilitator client. This is
|
|
33
|
+
* what `createSeller` registers under the hood; export it so advanced
|
|
34
|
+
* callers can attach `onAfterSettle`/`onSettleFailure` hooks of their own.
|
|
35
|
+
*/
|
|
36
|
+
export function createSvmResourceServer(opts = {}) {
|
|
37
|
+
const networks = opts.networks ?? ['solana-devnet'];
|
|
38
|
+
const defaultUrl = defaultFacilitatorFor(networks);
|
|
39
|
+
const facilitatorClient = typeof opts.facilitator === 'string'
|
|
40
|
+
? new HTTPFacilitatorClient({ url: opts.facilitator })
|
|
41
|
+
: (opts.facilitator ?? new HTTPFacilitatorClient({ url: defaultUrl }));
|
|
42
|
+
const facilitatorUrl = facilitatorClient instanceof HTTPFacilitatorClient ? facilitatorClient.url : null;
|
|
43
|
+
const server = new x402ResourceServer(facilitatorClient);
|
|
44
|
+
const scheme = new ExactSvmScheme();
|
|
45
|
+
for (const n of networks) {
|
|
46
|
+
server.register(NETWORK_TO_CAIP2[n], scheme);
|
|
47
|
+
}
|
|
48
|
+
return { server, facilitatorUrl };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=svm-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svm-server.js","sourceRoot":"","sources":["../../src/x402/svm-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG9E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAIpF,MAAM,gBAAgB,GAAwC;IAC5D,gBAAgB,EAAE,oBAA+B;IACjD,eAAe,EAAE,mBAA8B;IAC/C,gBAAgB,EAAE,oBAA+B;CAClD,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,OAA2B;IAC/D,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,OAA2B;IACtD,OAAO,OAAO,KAAK,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;AAchE;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAuC,EAAE;IAI/E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,eAAe,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,iBAAiB,GACrB,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QAClC,CAAC,CAAC,IAAI,qBAAqB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QACtD,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,qBAAqB,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IAE3E,MAAM,cAAc,GAClB,iBAAiB,YAAY,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAEpF,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;AACpC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@leashmarket/seller-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./test-utils": {
|
|
14
|
+
"types": "./dist/test-utils/stub-facilitator.d.ts",
|
|
15
|
+
"import": "./dist/test-utils/stub-facilitator.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@metaplex-foundation/mpl-core": "^1.10.0",
|
|
23
|
+
"@metaplex-foundation/umi": "^1.5.1",
|
|
24
|
+
"@metaplex-foundation/umi-bundle-defaults": "^1.5.1",
|
|
25
|
+
"@solana/kit": "^5.1.0",
|
|
26
|
+
"@x402/core": "^2.10.0",
|
|
27
|
+
"@x402/hono": "^2.10.0",
|
|
28
|
+
"@x402/svm": "^2.10.0",
|
|
29
|
+
"hono": "^4.6.14",
|
|
30
|
+
"@leashmarket/core": "0.1.0",
|
|
31
|
+
"@leashmarket/schemas": "0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"typescript": "^5.7.2",
|
|
35
|
+
"vitest": "^2.1.8"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc -p tsconfig.build.json",
|
|
42
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
43
|
+
"lint": "eslint src",
|
|
44
|
+
"test": "vitest run"
|
|
45
|
+
}
|
|
46
|
+
}
|