agentcash 0.16.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/run-server.cjs +2331 -1310
- package/dist/esm/{chunk-CAQPJTGD.js → chunk-3XQN4TFL.js} +2 -2
- package/dist/esm/{chunk-3GFWQSSI.js → chunk-C5TXI374.js} +2 -2
- package/dist/esm/{chunk-DFR33XGE.js → chunk-CQ5ZSAKD.js} +2 -2
- package/dist/esm/{chunk-XGPAWZOW.js → chunk-F4YE5YSG.js} +16 -14
- package/dist/esm/chunk-F4YE5YSG.js.map +1 -0
- package/dist/esm/{chunk-W2TBFY7Y.js → chunk-FRESP5ZE.js} +8 -16
- package/dist/esm/chunk-FRESP5ZE.js.map +1 -0
- package/dist/esm/{chunk-B5G7TGCZ.js → chunk-H2JGMFEG.js} +56 -20
- package/dist/esm/chunk-H2JGMFEG.js.map +1 -0
- package/dist/esm/{chunk-MGMZAP3N.js → chunk-V264YU5J.js} +2 -2
- package/dist/esm/{fetch-HZN5PZFT.js → fetch-OXPSOIQ3.js} +3 -3
- package/dist/esm/index.js +10 -10
- package/dist/esm/{install-BYUVEOSA.js → install-RCJYUZA6.js} +3 -3
- package/dist/esm/{onboard-GRU6ILR7.js → onboard-263VMOOP.js} +3 -3
- package/dist/esm/{register-BPCEZI5M.js → register-35JC4M2E.js} +3 -3
- package/dist/esm/{report-error-LE4ENBTZ.js → report-error-TXNPOHTY.js} +3 -3
- package/dist/esm/{search-LFRFBZ4B.js → search-ZFXKWMRP.js} +4 -4
- package/dist/esm/{server-SZ26QZQT.js → server-ABCU7Y46.js} +8 -8
- package/dist/esm/{server-3IWGKL7C.js → server-ECAFH7U2.js} +2 -2
- package/dist/esm/{sessions-A5ELSD5L.js → sessions-RXMJRALZ.js} +3 -3
- package/package.json +3 -3
- package/dist/esm/chunk-B5G7TGCZ.js.map +0 -1
- package/dist/esm/chunk-W2TBFY7Y.js.map +0 -1
- package/dist/esm/chunk-XGPAWZOW.js.map +0 -1
- /package/dist/esm/{chunk-CAQPJTGD.js.map → chunk-3XQN4TFL.js.map} +0 -0
- /package/dist/esm/{chunk-3GFWQSSI.js.map → chunk-C5TXI374.js.map} +0 -0
- /package/dist/esm/{chunk-DFR33XGE.js.map → chunk-CQ5ZSAKD.js.map} +0 -0
- /package/dist/esm/{chunk-MGMZAP3N.js.map → chunk-V264YU5J.js.map} +0 -0
- /package/dist/esm/{fetch-HZN5PZFT.js.map → fetch-OXPSOIQ3.js.map} +0 -0
- /package/dist/esm/{install-BYUVEOSA.js.map → install-RCJYUZA6.js.map} +0 -0
- /package/dist/esm/{onboard-GRU6ILR7.js.map → onboard-263VMOOP.js.map} +0 -0
- /package/dist/esm/{register-BPCEZI5M.js.map → register-35JC4M2E.js.map} +0 -0
- /package/dist/esm/{report-error-LE4ENBTZ.js.map → report-error-TXNPOHTY.js.map} +0 -0
- /package/dist/esm/{search-LFRFBZ4B.js.map → search-ZFXKWMRP.js.map} +0 -0
- /package/dist/esm/{server-SZ26QZQT.js.map → server-ABCU7Y46.js.map} +0 -0
- /package/dist/esm/{server-3IWGKL7C.js.map → server-ECAFH7U2.js.map} +0 -0
- /package/dist/esm/{sessions-A5ELSD5L.js.map → sessions-RXMJRALZ.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-27DZCYDB.js";
|
|
7
7
|
import {
|
|
8
8
|
INSTALL_PACKAGE_SPECIFIER
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-V264YU5J.js";
|
|
10
10
|
import {
|
|
11
11
|
log,
|
|
12
12
|
safeReadFile,
|
|
@@ -628,4 +628,4 @@ export {
|
|
|
628
628
|
tryAddServer,
|
|
629
629
|
addServer
|
|
630
630
|
};
|
|
631
|
-
//# sourceMappingURL=chunk-
|
|
631
|
+
//# sourceMappingURL=chunk-3XQN4TFL.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-H5V6L7NG.js";
|
|
4
4
|
import {
|
|
5
5
|
executeFetch
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-F4YE5YSG.js";
|
|
7
7
|
import {
|
|
8
8
|
safeParseResponse
|
|
9
9
|
} from "./chunk-RAS5DZPQ.js";
|
|
@@ -89,4 +89,4 @@ export {
|
|
|
89
89
|
searchSchema,
|
|
90
90
|
search
|
|
91
91
|
};
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-C5TXI374.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MCP_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-V264YU5J.js";
|
|
4
4
|
import {
|
|
5
5
|
safeFetchJson
|
|
6
6
|
} from "./chunk-RAS5DZPQ.js";
|
|
@@ -51,4 +51,4 @@ async function submitErrorReport(surface, input, address, dev) {
|
|
|
51
51
|
export {
|
|
52
52
|
submitErrorReport
|
|
53
53
|
};
|
|
54
|
-
//# sourceMappingURL=chunk-
|
|
54
|
+
//# sourceMappingURL=chunk-CQ5ZSAKD.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertTempoUsdc,
|
|
3
|
-
|
|
3
|
+
createSessionChannelStore,
|
|
4
4
|
createTempoClient,
|
|
5
5
|
mppErr,
|
|
6
6
|
mppOk,
|
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
safeCreateMppCredential,
|
|
9
9
|
safeGetMppChallenge,
|
|
10
10
|
safeGetMppReceipt,
|
|
11
|
-
sessionRequestFailedErr
|
|
12
|
-
|
|
13
|
-
} from "./chunk-B5G7TGCZ.js";
|
|
11
|
+
sessionRequestFailedErr
|
|
12
|
+
} from "./chunk-H2JGMFEG.js";
|
|
14
13
|
import {
|
|
15
14
|
DEFAULT_MAX_AMOUNT,
|
|
16
15
|
getSettings
|
|
@@ -434,7 +433,7 @@ var insufficientBalanceErrorMessage = (props, balance) => {
|
|
|
434
433
|
|
|
435
434
|
// src/shared/protocols/mpp/session/handle-session-payment.ts
|
|
436
435
|
import { formatUnits } from "viem";
|
|
437
|
-
import {
|
|
436
|
+
import { sessionManager } from "mppx/client";
|
|
438
437
|
|
|
439
438
|
// src/shared/protocols/mpp/session/run-request-session.ts
|
|
440
439
|
async function runRequestSession(surface, sm, url, init) {
|
|
@@ -559,20 +558,23 @@ async function handleMppSessionPayment(challenge, { request, options }) {
|
|
|
559
558
|
)
|
|
560
559
|
);
|
|
561
560
|
if (replayInitResult.isErr()) return replayInitResult;
|
|
562
|
-
const sm =
|
|
561
|
+
const sm = sessionManager({
|
|
563
562
|
account: wallets.evm,
|
|
564
563
|
client: createTempoClient(),
|
|
565
564
|
maxDeposit: formatDepositCap(depositUsd),
|
|
566
565
|
decimals: USDC_DECIMALS,
|
|
567
|
-
// Persist the channel (with its TIP-1034 descriptor) per wallet
|
|
568
|
-
//
|
|
569
|
-
//
|
|
570
|
-
|
|
571
|
-
sessionScopeForUrl(request.url, wallets.evm.address)
|
|
572
|
-
)
|
|
566
|
+
// Persist the channel (with its TIP-1034 descriptor) per wallet so it can be
|
|
567
|
+
// reused across requests/restarts and closed later via sessions_close — and
|
|
568
|
+
// only ever by the wallet that opened it.
|
|
569
|
+
channelStore: createSessionChannelStore(wallets.evm.address)
|
|
573
570
|
});
|
|
574
571
|
const isStreaming = challenge.meta?.streaming === "true" || options.params.stream === true;
|
|
575
|
-
const sessionResult = isStreaming ? await runStreamingSession(
|
|
572
|
+
const sessionResult = isStreaming ? await runStreamingSession(
|
|
573
|
+
surface,
|
|
574
|
+
sm,
|
|
575
|
+
request.url,
|
|
576
|
+
replayInitResult.value
|
|
577
|
+
) : await runRequestSession(surface, sm, request.url, replayInitResult.value);
|
|
576
578
|
if (sessionResult.isErr()) return sessionResult;
|
|
577
579
|
const { response: finalResponse, receipt } = sessionResult.value;
|
|
578
580
|
const price = receipt ? formatUsd(tokenStringToNumber(receipt.spent, USDC_DECIMALS)) : `from ${formatUsd(tickCostUsd)}/tick`;
|
|
@@ -990,4 +992,4 @@ async function executeFetch(input, options) {
|
|
|
990
992
|
export {
|
|
991
993
|
executeFetch
|
|
992
994
|
};
|
|
993
|
-
//# sourceMappingURL=chunk-
|
|
995
|
+
//# sourceMappingURL=chunk-F4YE5YSG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/operations/fetch/auth.ts","../../src/shared/protocols/x402/index.ts","../../src/shared/protocols/x402/patched-exact-svm-scheme.ts","../../src/shared/protocols/x402/policies.ts","../../src/shared/protocols/detect.ts","../../src/shared/protocols/mpp/handle-payment.ts","../../src/shared/protocols/before-payment.ts","../../src/shared/protocols/mpp/session/handle-session-payment.ts","../../src/shared/protocols/mpp/session/run-request-session.ts","../../src/shared/protocols/mpp/session/run-streaming-session.ts","../../src/shared/protocols/mpp/session/utils.ts","../../src/shared/protocols/pick.ts","../../src/shared/protocols/x402/choose-payment-requirement.ts","../../src/shared/protocols/x402/handle-payment.ts","../../src/operations/fetch/payment.ts","../../src/operations/fetch/index.ts"],"sourcesContent":["import { encodeSIWxHeader } from '@x402/extensions/sign-in-with-x';\n\nimport { fetchOk, safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n getSiwxExtension,\n safeCreateSIWxPayload,\n safeGetPaymentRequired,\n} from '@/shared/protocols/x402';\n\nimport type { ExecuteFetchOptions } from './types';\n\nexport async function attemptSiwxAuth(\n response: Response,\n authRetryRequest: Request,\n paymentRetryRequest: Request,\n options: ExecuteFetchOptions\n) {\n const { surface, wallets } = options;\n const { timeout, paymentNetwork } = options.params;\n\n if (!response.headers.has('payment-required')) {\n return fetchOk({\n response,\n paymentRetryRequest,\n });\n }\n\n const paymentRequiredResult = await safeGetPaymentRequired(surface, response);\n\n if (paymentRequiredResult.isErr()) {\n return paymentRequiredResult;\n }\n\n const siwxExtension = getSiwxExtension(\n paymentRequiredResult.value.extensions,\n paymentNetwork\n );\n\n if (!siwxExtension) {\n return fetchOk({\n response,\n paymentRetryRequest,\n });\n }\n\n const payloadResult = await safeCreateSIWxPayload(\n surface,\n siwxExtension,\n wallets\n );\n\n if (payloadResult.isErr()) {\n return payloadResult;\n }\n\n const siwxHeader = encodeSIWxHeader(payloadResult.value);\n authRetryRequest.headers.set('SIGN-IN-WITH-X', siwxHeader);\n paymentRetryRequest.headers.set('SIGN-IN-WITH-X', siwxHeader);\n\n return (await safeFetch(surface, authRetryRequest, timeout)).andThen(\n authResponse =>\n fetchOk({\n response: authResponse,\n paymentRetryRequest,\n })\n );\n}\n","import {\n err,\n ok,\n resultFromPromise,\n resultFromThrowable,\n} from '@agentcash/neverthrow';\n\nimport type { SelectPaymentRequirements } from '@x402/core/client';\nimport { x402Client, x402HTTPClient } from '@x402/core/client';\n\nimport { toClientEvmSigner } from '@x402/evm';\nimport { toClientSvmSigner } from '@x402/svm';\n\nimport { ExactEvmScheme } from '@x402/evm/exact/client';\nimport { UptoEvmScheme } from '@x402/evm/upto/client';\nimport { PatchedExactSvmScheme } from './patched-exact-svm-scheme';\nimport { capUptoDeadline } from './policies';\n\nimport { createSIWxPayload } from '@x402/extensions/sign-in-with-x';\n\nimport type { BaseX402Error } from './types';\nimport type { PaymentRequired } from '@x402/core/types';\nimport type {\n CompleteSIWxInfo,\n SIWxExtensionInfo,\n SolanaSigner,\n SupportedChain,\n} from '@x402/extensions/sign-in-with-x';\nimport type { Wallets } from '@/wallet';\nimport { Network, networkToCaip2 } from '@agentcash/networks';\nimport type { Network as PaymentNetwork } from '@agentcash/networks';\nimport { createPublicClient, http } from 'viem';\nimport { base } from 'viem/chains';\n\nconst errorType = 'x402';\n\nexport const x402Ok = <T>(value: T) => ok(value);\nexport const x402Err = (cause: string, error: BaseX402Error) =>\n err(errorType, cause, error);\n\nconst x402ResultFromPromise = <T>(\n surface: string,\n promise: Promise<T>,\n error: (e: unknown) => BaseX402Error\n) => resultFromPromise(errorType, surface, promise, error);\n\nconst x402ResultFromThrowable = <T>(\n surface: string,\n fn: () => T,\n error: (e: unknown) => BaseX402Error\n) => resultFromThrowable(errorType, surface, fn, error);\n\nexport const x402ProbeClient = new x402HTTPClient(new x402Client());\n\nexport const safeGetPaymentRequired = (surface: string, response: Response) => {\n // Read the body from a clone so the caller's Response stays unconsumed.\n // Dual-protocol 402s (x402 header + MPP `WWW-Authenticate`) reuse the same\n // Response downstream, and mppx >=0.6 clones it internally when creating a\n // credential — consuming it here would make that clone throw.\n const probe = response.clone();\n return x402ResultFromPromise(\n surface,\n probe.json().then(\n json =>\n x402ProbeClient.getPaymentRequiredResponse(\n name => response.headers.get(name),\n json\n ),\n () =>\n x402ProbeClient.getPaymentRequiredResponse(name =>\n response.headers.get(name)\n )\n ),\n error => ({\n cause: 'parse_payment_required',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse payment required',\n })\n );\n};\n\nexport const getSiwxExtension = (\n extensions: PaymentRequired['extensions'],\n paymentNetwork?: PaymentNetwork\n): CompleteSIWxInfo | undefined => {\n const siwx = extensions?.['sign-in-with-x'] as\n | { info?: SIWxExtensionInfo; supportedChains?: SupportedChain[] }\n | undefined;\n\n if (!siwx?.info) {\n return undefined;\n }\n\n const chain = siwx.supportedChains?.find(c =>\n paymentNetwork\n ? c.chainId === networkToCaip2(paymentNetwork)\n : c.chainId.startsWith('eip155:')\n );\n\n return {\n ...siwx.info,\n chainId: chain?.chainId ?? 'eip155:8453',\n type: chain?.type ?? 'eip191',\n signatureScheme: chain?.signatureScheme,\n };\n};\n\nexport const safeCreatePaymentPayload = (\n surface: string,\n wallets: Wallets,\n paymentRequired: PaymentRequired,\n paymentRequirementsSelector?: SelectPaymentRequirements\n) => {\n const client = new x402HTTPClient(\n x402Client.fromConfig({\n schemes: [\n {\n network: networkToCaip2(Network.BASE),\n client: new ExactEvmScheme(\n toClientEvmSigner(\n wallets.evm,\n createPublicClient({\n chain: base,\n transport: http(),\n })\n )\n ),\n },\n {\n network: networkToCaip2(Network.BASE),\n client: new UptoEvmScheme(\n toClientEvmSigner(\n wallets.evm,\n createPublicClient({\n chain: base,\n transport: http(),\n })\n )\n ),\n },\n {\n network: networkToCaip2(Network.SOLANA),\n client: new PatchedExactSvmScheme(toClientSvmSigner(wallets.svm)),\n },\n ],\n policies: [capUptoDeadline],\n paymentRequirementsSelector,\n })\n );\n return x402ResultFromPromise(\n surface,\n client.createPaymentPayload(paymentRequired),\n error => ({\n cause: 'create_payment_payload',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to create payment payload',\n })\n );\n};\n\nexport const safeGetPaymentSettlement = (\n surface: string,\n response: Response\n) => {\n return x402ResultFromThrowable(\n surface,\n () =>\n x402ProbeClient.getPaymentSettleResponse(name =>\n response.headers.get(name)\n ),\n error => ({\n cause: 'get_payment_settlement',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to get payment settlement',\n })\n );\n};\n\nexport const safeCreateSIWxPayload = (\n surface: string,\n serverInfo: CompleteSIWxInfo,\n wallets: Wallets\n) => {\n return x402ResultFromPromise(\n surface,\n createSIWxPayload(\n serverInfo,\n serverInfo.chainId.startsWith('eip155:')\n ? wallets.evm\n : (wallets.svm as unknown as SolanaSigner)\n ),\n error => ({\n cause: 'create_siwx_payload',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to create SIWX payload',\n })\n );\n};\n","import {\n getSetComputeUnitLimitInstruction,\n setTransactionMessageComputeUnitPrice,\n} from '@solana-program/compute-budget';\nimport { TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';\nimport {\n fetchMint,\n findAssociatedTokenPda,\n getTransferCheckedInstruction,\n TOKEN_2022_PROGRAM_ADDRESS,\n} from '@solana-program/token-2022';\nimport {\n appendTransactionMessageInstructions,\n createTransactionMessage,\n getBase64EncodedWireTransaction,\n partiallySignTransactionMessageWithSigners,\n pipe,\n prependTransactionMessageInstruction,\n setTransactionMessageFeePayer,\n setTransactionMessageLifetimeUsingBlockhash,\n type Address,\n} from '@solana/kit';\n\nimport type {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkClient,\n} from '@x402/core/types';\nimport {\n DEFAULT_COMPUTE_UNIT_LIMIT,\n DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n createRpcClient,\n type ClientSvmConfig,\n type ClientSvmSigner,\n type ExactSvmPayloadV2,\n} from '@x402/svm';\n\ntype BlockhashLifetime = Parameters<\n typeof setTransactionMessageLifetimeUsingBlockhash\n>[0];\n\ninterface PatchedPaymentExtra {\n feePayer?: Address;\n recentBlockhash?:\n | string\n | Partial<{\n blockhash: string;\n lastValidBlockHeight: bigint | number | string;\n }>;\n lastValidBlockHeight?: bigint | number | string;\n}\n\nfunction parseLastValidBlockHeight(\n value: bigint | number | string | undefined\n): bigint | undefined {\n if (typeof value === 'bigint') {\n return value;\n }\n\n if (typeof value === 'number' && Number.isFinite(value)) {\n return BigInt(value);\n }\n\n if (typeof value === 'string' && value.length > 0) {\n return BigInt(value);\n }\n\n return undefined;\n}\n\nfunction asBlockhash(blockhash: string): BlockhashLifetime['blockhash'] {\n return blockhash as BlockhashLifetime['blockhash'];\n}\n\n/**\n * Local compatibility patch for Coinbase ExactSvmScheme.\n *\n * Changes from upstream:\n * - omits the trailing memo instruction\n * - prefers paymentRequirements.extra.recentBlockhash when provided\n */\nexport class PatchedExactSvmScheme implements SchemeNetworkClient {\n readonly scheme = 'exact';\n\n constructor(\n private readonly signer: ClientSvmSigner,\n private readonly config?: ClientSvmConfig\n ) {}\n\n async createPaymentPayload(\n x402Version: number,\n paymentRequirements: PaymentRequirements\n ): Promise<Pick<PaymentPayload, 'x402Version' | 'payload'>> {\n const rpc = createRpcClient(\n paymentRequirements.network,\n this.config?.rpcUrl\n );\n\n const tokenMint = await fetchMint(\n rpc,\n paymentRequirements.asset as Address\n );\n const tokenProgramAddress = tokenMint.programAddress;\n\n if (\n tokenProgramAddress.toString() !== TOKEN_PROGRAM_ADDRESS.toString() &&\n tokenProgramAddress.toString() !== TOKEN_2022_PROGRAM_ADDRESS.toString()\n ) {\n throw new Error('Asset was not created by a known token program');\n }\n\n const [sourceATA] = await findAssociatedTokenPda({\n mint: paymentRequirements.asset as Address,\n owner: this.signer.address,\n tokenProgram: tokenProgramAddress,\n });\n\n const [destinationATA] = await findAssociatedTokenPda({\n mint: paymentRequirements.asset as Address,\n owner: paymentRequirements.payTo as Address,\n tokenProgram: tokenProgramAddress,\n });\n\n const transferIx = getTransferCheckedInstruction(\n {\n source: sourceATA,\n mint: paymentRequirements.asset as Address,\n destination: destinationATA,\n authority: this.signer,\n amount: BigInt(paymentRequirements.amount),\n decimals: tokenMint.data.decimals,\n },\n { programAddress: tokenProgramAddress }\n );\n\n const extra = paymentRequirements.extra as PatchedPaymentExtra;\n const feePayer = extra.feePayer;\n\n if (!feePayer) {\n throw new Error(\n 'feePayer is required in paymentRequirements.extra for SVM transactions'\n );\n }\n\n const latestBlockhash = await this.resolveBlockhashLifetime(rpc, extra);\n\n const tx = pipe(\n createTransactionMessage({ version: 0 }),\n tx =>\n setTransactionMessageComputeUnitPrice(\n DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n tx\n ),\n tx => setTransactionMessageFeePayer(feePayer, tx),\n tx =>\n prependTransactionMessageInstruction(\n getSetComputeUnitLimitInstruction({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n }),\n tx\n ),\n tx => appendTransactionMessageInstructions([transferIx], tx),\n tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx)\n );\n\n const signedTransaction =\n await partiallySignTransactionMessageWithSigners(tx);\n const base64EncodedWireTransaction =\n getBase64EncodedWireTransaction(signedTransaction);\n\n const payload: ExactSvmPayloadV2 = {\n transaction: base64EncodedWireTransaction,\n };\n\n return {\n x402Version,\n payload,\n };\n }\n\n private async resolveBlockhashLifetime(\n rpc: ReturnType<typeof createRpcClient>,\n extra: PatchedPaymentExtra\n ): Promise<BlockhashLifetime> {\n const providedLastValidBlockHeight = parseLastValidBlockHeight(\n extra.lastValidBlockHeight\n );\n\n if (typeof extra.recentBlockhash === 'string') {\n if (providedLastValidBlockHeight !== undefined) {\n return {\n blockhash: asBlockhash(extra.recentBlockhash),\n lastValidBlockHeight: providedLastValidBlockHeight,\n };\n }\n\n const { value } = await rpc.getLatestBlockhash().send();\n return {\n blockhash: asBlockhash(extra.recentBlockhash),\n lastValidBlockHeight: value.lastValidBlockHeight,\n };\n }\n\n if (\n extra.recentBlockhash &&\n typeof extra.recentBlockhash === 'object' &&\n typeof extra.recentBlockhash.blockhash === 'string'\n ) {\n const lastValidBlockHeight =\n parseLastValidBlockHeight(extra.recentBlockhash.lastValidBlockHeight) ??\n providedLastValidBlockHeight;\n\n if (lastValidBlockHeight !== undefined) {\n return {\n blockhash: asBlockhash(extra.recentBlockhash.blockhash),\n lastValidBlockHeight,\n };\n }\n\n const { value } = await rpc.getLatestBlockhash().send();\n return {\n blockhash: asBlockhash(extra.recentBlockhash.blockhash),\n lastValidBlockHeight: value.lastValidBlockHeight,\n };\n }\n\n return (await rpc.getLatestBlockhash().send()).value;\n }\n}\n","import type { PaymentPolicy } from '@x402/core/client';\n\n/**\n * Maximum deadline (in seconds) we accept for `upto` payment requirements.\n *\n * The `upto` Permit2 signature is bound by `paymentRequirements.maxTimeoutSeconds`,\n * which the SDK passes straight through from the merchant's 402 response with no\n * upper bound. Within that window, the (merchant + facilitator) pair can settle\n * for any amount in `[0, cap]` — and the only on-chain check is the deadline.\n *\n * A long deadline therefore extends the window of facilitator-discretion settlement\n * at the signed cap. 7 days lets a long-running agent keep working without\n * re-signing, but bounds the trust window if a merchant declares an unreasonably\n * large `maxTimeoutSeconds` (accidentally or otherwise).\n *\n * `exact` requirements are unaffected: their amount is fixed in the signature, so\n * a long validity window is just an annoyance, not a discretion surface.\n */\nexport const MAX_UPTO_DEADLINE_SECONDS = 7 * 24 * 60 * 60; // 7 days\n\n/**\n * Caps `maxTimeoutSeconds` on `upto` requirements at {@link MAX_UPTO_DEADLINE_SECONDS}.\n * Leaves `exact` and any other scheme untouched. Pass to `x402Client.fromConfig({ policies })`.\n */\nexport const capUptoDeadline: PaymentPolicy = (_x402Version, requirements) =>\n requirements.map(r =>\n r.scheme === 'upto' && r.maxTimeoutSeconds > MAX_UPTO_DEADLINE_SECONDS\n ? { ...r, maxTimeoutSeconds: MAX_UPTO_DEADLINE_SECONDS }\n : r\n );\n","import { PaymentProtocol } from './types';\n\nexport function detectPaymentProtocols(response: Response): PaymentProtocol[] {\n const protocols: PaymentProtocol[] = [];\n\n const wwwAuth = response.headers.get('WWW-Authenticate');\n if (wwwAuth?.startsWith('Payment')) {\n protocols.push(PaymentProtocol.MPP);\n }\n\n const paymentRequired = response.headers.get('payment-required');\n if (paymentRequired) {\n protocols.push(PaymentProtocol.X402);\n }\n // If we couldn't detect either explicitly, default to x402\n if (protocols.length === 0) {\n protocols.push(PaymentProtocol.X402);\n }\n return protocols;\n}\n","import type { Address } from 'viem';\nimport { formatUnits } from 'viem';\n\nimport { safeFetch, safeReadResponseText } from '@/shared/neverthrow/fetch';\nimport {\n assertTempoUsdc,\n safeGetMppChallenge,\n safeCreateMppCredential,\n safeGetMppReceipt,\n mppErr,\n mppOk,\n} from '@/shared/protocols/mpp';\n\nimport { PaymentProtocol } from '../types';\nimport { Network } from '@agentcash/networks';\nimport { formatUsd } from '@/shared/utils';\n\nimport type { ExecuteFetchResult } from '@/operations/fetch/types';\nimport type { HandlePaymentParams } from '@/shared/protocols/types';\nimport { beforePayment } from '../before-payment';\nimport { handleMppSessionPayment } from './session/handle-session-payment';\n\nexport async function handleMppPayment(params: HandlePaymentParams) {\n const { response, request, options } = params;\n const { surface, wallets } = options;\n const { timeout } = options.params;\n\n // Prevent retry loops\n if (request.headers.has('Authorization')) {\n return mppErr(surface, {\n cause: 'mpp_payment_already_attempted',\n message: 'MPP payment already attempted',\n });\n }\n\n // Parse the challenge from the WWW-Authenticate header\n const challengeResult = safeGetMppChallenge(surface, response);\n\n if (challengeResult.isErr()) {\n return challengeResult;\n }\n\n const challenge = challengeResult.value;\n\n if (challenge.intent === 'session') {\n return handleMppSessionPayment(challenge, params);\n }\n\n const amount = Number(formatUnits(BigInt(challenge.request.amount), 6));\n const tokenAddress = challenge.request.currency as Address;\n\n const tokenCheck = assertTempoUsdc(surface, tokenAddress);\n if (tokenCheck.isErr()) {\n return tokenCheck;\n }\n\n const beforePaymentResult = await beforePayment({\n options,\n balanceInput: {\n address: wallets.evm.address,\n network: Network.TEMPO,\n tokenAddress,\n },\n amount,\n protocol: PaymentProtocol.MPP,\n });\n\n if (beforePaymentResult.isErr()) {\n return beforePaymentResult;\n }\n\n const credentialResult = await safeCreateMppCredential(\n surface,\n wallets,\n response\n );\n\n if (credentialResult.isErr()) {\n return credentialResult;\n }\n\n const credential = credentialResult.value;\n\n // Set Authorization header on cloned request\n request.headers.set('Authorization', credential);\n\n // Retry the fetch with the credential\n const paidFetchResult = await safeFetch(surface, request, timeout);\n if (paidFetchResult.isErr()) {\n return paidFetchResult;\n }\n\n const paidResponse = paidFetchResult.value;\n\n // If the server still returns 402, the payment was rejected\n if (paidResponse.status === 402) {\n const body = await safeReadResponseText(surface, paidResponse).unwrapOr('');\n const detail = body ? `: ${body}` : '';\n return mppErr(surface, {\n cause: 'mpp_payment_rejected',\n message: `MPP payment was rejected by the server (402)${detail}`,\n });\n }\n\n // Parse the receipt for transaction hash\n const receiptResult = safeGetMppReceipt(surface, paidResponse);\n\n return mppOk<ExecuteFetchResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: PaymentProtocol.MPP,\n network: Network.TEMPO,\n price: formatUsd(amount),\n payment: receiptResult.isOk()\n ? {\n success: true,\n transactionHash: receiptResult.value.reference,\n }\n : null,\n },\n });\n}\n","import { err, ok } from '@agentcash/neverthrow';\n\nimport { getBalance } from '../balance';\nimport { getDepositLink } from '../utils';\nimport { getSettings } from '../settings';\n\nimport { DEFAULT_MAX_AMOUNT } from '@/operations/fetch/types';\n\nimport type { GetBalanceInput } from '@agentcash/balance';\nimport type { ExecuteFetchOptions } from '@/operations/fetch/types';\nimport type { PaymentProtocol } from './types';\n\ninterface BeforePaymentProps {\n options: ExecuteFetchOptions;\n balanceInput: GetBalanceInput;\n protocol: PaymentProtocol;\n amount: number;\n}\n\nexport const beforePayment = async (props: BeforePaymentProps) => {\n const { options, balanceInput, amount } = props;\n const maxAmount =\n options.params.maxAmount ?? getSettings().maxAmount ?? DEFAULT_MAX_AMOUNT;\n if (amount > maxAmount) {\n return err('before_payment', options.surface, {\n cause: 'amount_exceeds_max_amount' as const,\n message: `Endpoint requested $${amount} which exceeds the maximum allowed amount of $${maxAmount}. Pass a higher maxAmount on this call, or use update_settings to raise the default permanently.`,\n });\n }\n\n const balanceResult = await getBalance(\n options.surface,\n balanceInput,\n options.flags\n );\n\n if (balanceResult.isErr()) {\n return balanceResult;\n }\n\n const balance = balanceResult.value.balance;\n\n if (balance < amount) {\n return err('before_payment', options.surface, {\n cause: 'insufficient_balance' as const,\n message: insufficientBalanceErrorMessage(props, balance),\n });\n }\n\n return ok(true);\n};\n\nconst insufficientBalanceErrorMessage = (\n props: BeforePaymentProps,\n balance: number\n) => {\n const { options, balanceInput, amount } = props;\n return [\n `You are attempting to use an endpoint via ${props.protocol} that costs ${amount} USDC on ${balanceInput.network}.`,\n `Your current balance is ${balance} USDC.`,\n `You can bridge between accounts or deposit at ${getDepositLink(balanceInput.address, options.flags, balanceInput.network)} to top up your balance.`,\n `Before bridging, you can check the users account with npx agentcash@latest accounts or if you are within the MCP, you can use the list_accounts tool.`,\n ].join('\\n');\n};\n","import type { Address } from 'viem';\nimport { formatUnits } from 'viem';\n\nimport { sessionManager } from 'mppx/client';\n\nimport { Network } from '@agentcash/networks';\n\nimport type { ExecuteFetchResult } from '@/operations/fetch/types';\nimport { formatUsd, tokenStringToNumber } from '@/shared/utils';\n\nimport { beforePayment } from '../../before-payment';\nimport type { HandlePaymentParams } from '../../types';\nimport { PaymentProtocol } from '../../types';\nimport {\n assertTempoUsdc,\n createTempoClient,\n mppOk,\n mppResultFromPromise,\n sessionRequestFailedErr,\n} from '../index';\nimport { runRequestSession } from './run-request-session';\nimport { runStreamingSession } from './run-streaming-session';\nimport { createSessionChannelStore } from './session-store';\nimport type { SessionChallenge } from './types';\nimport {\n USDC_DECIMALS,\n bufferRequestForReplay,\n formatDepositCap,\n resolveDepositUsd,\n} from './utils';\n\nexport async function handleMppSessionPayment(\n challenge: SessionChallenge,\n { request, options }: HandlePaymentParams\n) {\n const { surface, wallets } = options;\n\n const tickCostAtomic = BigInt(challenge.request.amount);\n const tickCostUsd = Number(formatUnits(tickCostAtomic, USDC_DECIMALS));\n const tokenAddress = challenge.request.currency as Address;\n\n const tokenCheck = assertTempoUsdc(surface, tokenAddress);\n if (tokenCheck.isErr()) return tokenCheck;\n\n const depositUsd = resolveDepositUsd(\n challenge.request.suggestedDeposit,\n tickCostUsd,\n options\n );\n\n const beforePaymentResult = await beforePayment({\n options,\n balanceInput: {\n address: wallets.evm.address,\n network: Network.TEMPO,\n tokenAddress,\n },\n amount: depositUsd,\n protocol: PaymentProtocol.MPP,\n });\n if (beforePaymentResult.isErr()) return beforePaymentResult;\n\n const replayInitResult = await mppResultFromPromise(\n surface,\n bufferRequestForReplay(request),\n e =>\n sessionRequestFailedErr(\n e,\n 'Failed to buffer request body for session replay'\n )\n );\n if (replayInitResult.isErr()) return replayInitResult;\n\n const sm = sessionManager({\n account: wallets.evm,\n client: createTempoClient(),\n maxDeposit: formatDepositCap(depositUsd),\n decimals: USDC_DECIMALS,\n // Persist the channel (with its TIP-1034 descriptor) per wallet so it can be\n // reused across requests/restarts and closed later via sessions_close — and\n // only ever by the wallet that opened it.\n channelStore: createSessionChannelStore(wallets.evm.address),\n });\n\n const isStreaming =\n challenge.meta?.streaming === 'true' || options.params.stream === true;\n\n const sessionResult = isStreaming\n ? await runStreamingSession(\n surface,\n sm,\n request.url,\n replayInitResult.value\n )\n : await runRequestSession(surface, sm, request.url, replayInitResult.value);\n if (sessionResult.isErr()) return sessionResult;\n\n const { response: finalResponse, receipt } = sessionResult.value;\n\n const price = receipt\n ? formatUsd(tokenStringToNumber(receipt.spent, USDC_DECIMALS))\n : `from ${formatUsd(tickCostUsd)}/tick`;\n\n return mppOk<ExecuteFetchResult>({\n response: finalResponse,\n paymentInfo: {\n protocol: PaymentProtocol.MPP,\n network: Network.TEMPO,\n price,\n payment: receipt ? { success: true, channelId: receipt.channelId } : null,\n },\n });\n}\n","import { safeReadResponseText } from '@/shared/neverthrow/fetch';\n\nimport {\n mppErr,\n mppOk,\n mppResultFromPromise,\n sessionRequestFailedErr,\n} from '../index';\nimport type { SessionManager, SessionOutcome } from './types';\n\nexport async function runRequestSession(\n surface: string,\n sm: SessionManager,\n url: string,\n init: RequestInit\n) {\n const fetchResult = await mppResultFromPromise(\n surface,\n sm.fetch(url, init),\n e => sessionRequestFailedErr(e)\n );\n if (fetchResult.isErr()) return fetchResult;\n\n const paymentResponse = fetchResult.value;\n\n if (paymentResponse.status === 402) {\n const body = await safeReadResponseText(surface, paymentResponse).unwrapOr(\n ''\n );\n const detail = body ? `: ${body}` : '';\n return mppErr(surface, {\n cause: 'mpp_payment_rejected',\n message: `MPP session payment was rejected by the server (402)${detail}`,\n });\n }\n\n return mppOk<SessionOutcome>({\n response: paymentResponse,\n receipt: paymentResponse.receipt,\n });\n}\n","import { mppErr, mppOk } from '../index';\nimport type { SessionManager, SessionOutcome, SessionReceipt } from './types';\n\nconst MAX_BUFFERED_BYTES = 50 * 1024 * 1024;\n\nexport async function runStreamingSession(\n surface: string,\n sm: SessionManager,\n url: string,\n init: RequestInit\n) {\n let latestReceipt: SessionReceipt | null = null;\n\n const { signal, ...rest } = init;\n const sseResult = await sm.sse(url, {\n ...rest,\n ...(signal ? { signal } : {}),\n onReceipt: receipt => {\n latestReceipt = receipt;\n },\n });\n\n const chunks: string[] = [];\n let bytes = 0;\n for await (const chunk of sseResult) {\n bytes += chunk.length;\n chunks.push(chunk);\n if (bytes > MAX_BUFFERED_BYTES) {\n return mppErr(surface, {\n cause: 'mpp_session_response_too_large',\n message: `Streaming response exceeded the ${MAX_BUFFERED_BYTES}-byte buffering cap (got ${bytes} bytes).`,\n });\n }\n }\n\n // mppx's `sm.sse()` yields the `data:` payloads of `message` events\n // (voucher/receipt events are consumed internally), so join with `\\n`\n // to keep object-yielding streams valid NDJSON.\n const response = new Response(chunks.join('\\n'), {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain',\n 'Cache-Control': 'private',\n },\n });\n\n return mppOk<SessionOutcome>({ response, receipt: latestReceipt });\n}\n","import {\n DEFAULT_MAX_AMOUNT,\n type ExecuteFetchOptions,\n} from '@/operations/fetch/types';\nimport { getSettings } from '@/shared/settings';\nimport { tokenStringToNumber } from '@/shared/utils';\n\nexport const USDC_DECIMALS = 6;\nconst DEFAULT_TICK_BUDGET = 10;\n\nexport function resolveDepositUsd(\n suggestedDeposit: string | undefined,\n tickCostUsd: number,\n options: ExecuteFetchOptions\n): number {\n const maxAmount =\n options.params.maxAmount ?? getSettings().maxAmount ?? DEFAULT_MAX_AMOUNT;\n const desired =\n suggestedDeposit !== undefined\n ? tokenStringToNumber(suggestedDeposit, USDC_DECIMALS)\n : tickCostUsd * DEFAULT_TICK_BUDGET;\n return Math.min(desired, maxAmount);\n}\n\n// toFixed rather than toString so very small deposits don't serialize in\n// scientific notation, which viem's parseUnits rejects.\nexport function formatDepositCap(depositUsd: number): string {\n if (!Number.isFinite(depositUsd) || depositUsd <= 0) {\n return '0';\n }\n return depositUsd.toFixed(USDC_DECIMALS);\n}\n\nexport async function bufferRequestForReplay(\n request: Request\n): Promise<RequestInit> {\n const init: RequestInit = {\n method: request.method,\n headers: new Headers(request.headers),\n credentials: request.credentials,\n redirect: request.redirect,\n referrer: request.referrer === '' ? undefined : request.referrer,\n integrity: request.integrity || undefined,\n signal: request.signal,\n };\n\n const hasBody =\n request.method !== 'GET' &&\n request.method !== 'HEAD' &&\n request.body !== null;\n\n if (hasBody) {\n init.body = await request.arrayBuffer();\n }\n\n return init;\n}\n","import { safeGetMppChallenge } from '@/shared/protocols/mpp';\n\nimport { log } from '@/shared/log';\nimport { getBalance } from '@/shared/balance';\nimport { Network } from '@agentcash/networks';\n\nimport { PaymentProtocol } from './types';\n\nimport type { ExecuteFetchOptions } from '@/operations/fetch/types';\n\n/**\n * Pick the preferred protocol by comparing wallet balances.\n * Falls back to 'mpp' if both balances fail to fetch.\n */\nexport async function pickByBalance(\n response: Response,\n options: ExecuteFetchOptions\n): Promise<PaymentProtocol> {\n const { surface, wallets, flags } = options;\n\n // Get x402 (USDC on Base and Solana) balances in parallel\n const x402Balances = await Promise.all([\n getBalance(\n surface,\n {\n address: wallets.evm.address,\n network: Network.BASE,\n },\n flags\n ),\n getBalance(\n surface,\n {\n address: wallets.svm.address,\n network: Network.SOLANA,\n },\n flags\n ),\n ]);\n\n const x402Balance = x402Balances.reduce(\n (acc, balance) => acc + (balance.isOk() ? balance.value.balance : 0),\n 0\n );\n\n // Get MPP (Tempo) balance — need token address from the challenge\n let mppBalance = 0;\n const challengeResult = safeGetMppChallenge(surface, response);\n if (challengeResult.isOk()) {\n const currency = challengeResult.value.request.currency;\n if (currency) {\n const tempoResult = await getBalance(\n surface,\n {\n address: wallets.evm.address,\n network: Network.TEMPO,\n },\n flags\n );\n if (tempoResult.isOk()) {\n mppBalance = tempoResult.value.balance ?? 0;\n }\n }\n }\n\n log.info(`Protocol selection — x402: $${x402Balance}, mpp: $${mppBalance}`);\n return x402Balance >= mppBalance ? PaymentProtocol.X402 : PaymentProtocol.MPP;\n}\n","import { getBalance } from '@/shared/balance';\nimport { caip2ToNetwork, Network, networkToCaip2 } from '@agentcash/networks';\n\nimport type { PaymentRequirements } from '@x402/core/types';\nimport type { ExecuteFetchOptions } from '@/operations/fetch/types';\n\ninterface ChoosePaymentRequirementParams {\n paymentRequirements: PaymentRequirements[];\n options: ExecuteFetchOptions;\n}\n\n// Prefer `upto` over `exact` when a server offers both on the same network.\n// `upto` authorizes a maximum via Permit2 and settles for actual usage, which\n// matches usage-priced endpoints (e.g. per-token LLM inference) better than\n// `exact`, which charges the upper bound regardless. Servers that surface\n// both schemes — like Surplus Intelligence — explicitly recommend preferring\n// `upto`. Falls back to the first match when `upto` isn't offered.\nexport const preferUpto = (\n requirements: PaymentRequirements[]\n): PaymentRequirements | undefined => {\n return requirements.find(pr => pr.scheme === 'upto') ?? requirements[0];\n};\n\nexport const choosePaymentRequirement = async ({\n paymentRequirements,\n options,\n}: ChoosePaymentRequirementParams) => {\n const { surface, wallets, flags } = options;\n const { paymentNetwork } = options.params;\n if (paymentNetwork) {\n const caip2 = networkToCaip2(paymentNetwork);\n return preferUpto(paymentRequirements.filter(pr => pr.network === caip2));\n }\n\n const requirementsWithBalance = await Promise.all(\n paymentRequirements.map(async pr => {\n const network = caip2ToNetwork(pr.network);\n if (network === null) {\n return {\n balance: 0,\n requirement: pr,\n };\n }\n if (network === Network.SOLANA) {\n const balanceResult = await getBalance(\n surface,\n {\n address: wallets.svm.address,\n network,\n },\n flags\n );\n return {\n requirement: pr,\n balance: balanceResult.isOk() ? balanceResult.value.balance : 0,\n };\n } else {\n const balanceResult = await getBalance(\n surface,\n {\n address: wallets.evm.address,\n network,\n },\n flags\n );\n return {\n requirement: pr,\n balance: balanceResult.isOk() ? balanceResult.value.balance : 0,\n };\n }\n })\n );\n const bestNetwork = requirementsWithBalance.sort(\n (a, b) => b.balance - a.balance\n )[0]!.requirement.network;\n return preferUpto(\n paymentRequirements.filter(pr => pr.network === bestNetwork)\n );\n};\n","import { caip2ToNetwork, Network } from '@agentcash/networks';\n\nimport { choosePaymentRequirement } from './choose-payment-requirement';\n\nimport { safeFetch, safeReadResponseText } from '@/shared/neverthrow/fetch';\nimport {\n safeCreatePaymentPayload,\n safeGetPaymentRequired,\n safeGetPaymentSettlement,\n x402Err,\n x402Ok,\n x402ProbeClient,\n} from '@/shared/protocols/x402';\nimport { tokenStringToNumber, formatUsd } from '@/shared/utils';\n\nimport { beforePayment } from '../before-payment';\n\nimport { PaymentProtocol } from '../types';\n\nimport type { ExecuteFetchResult } from '@/operations/fetch/types';\nimport type { HandlePaymentParams } from '../types';\nimport type { BaseX402Error } from './types';\n\nexport const isPermit2AllowanceFailureBody = (body: string): boolean =>\n body.includes('permit2') && body.includes('allowance_required');\n\nexport const buildPermit2AllowanceErrorMessage = (params: {\n walletAddress: string;\n scheme: string;\n}): string => {\n const { walletAddress, scheme } = params;\n return [\n `Payment failed: this endpoint's \\`${scheme}\\` scheme settles via the Permit2 contract, but your agentcash wallet (${walletAddress}) has not approved Permit2 to spend USDC.`,\n '',\n 'The clean fix is server-side. The merchant should adopt the EIP-2612 gas-sponsoring extension — agentcash will then auto-sign an off-chain permit on each call and the facilitator pays the approval gas, with no setup required from the user. See https://docs.x402.org/extensions/eip2612-gas-sponsoring',\n '',\n `Until the merchant adopts that extension, you can do a one-time \\`USDC.approve(0x000000000022D473030F116dDEE9F6B43aC78BA3, MAX_UINT256)\\` on Base from this wallet (requires a small amount of ETH for gas, ~$0.01–0.10). After that, all future Permit2-based payments from this wallet work without further on-chain transactions.`,\n ].join('\\n');\n};\n\nexport async function handleX402Payment({\n response,\n request,\n options,\n}: HandlePaymentParams) {\n const { surface, wallets } = options;\n const { timeout } = options.params;\n\n const paymentRequiredResult = await safeGetPaymentRequired(surface, response);\n\n if (paymentRequiredResult.isErr()) {\n return paymentRequiredResult;\n }\n\n const paymentRequired = paymentRequiredResult.value;\n\n if (paymentRequired.x402Version === 1) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message:\n 'This endpoint uses the x402 v1 format, which is not supported by agentcash. Only x402 v2 servers (with an `accepts` array in the Payment-Required header) are supported.',\n });\n }\n\n if (!paymentRequired.accepts || !Array.isArray(paymentRequired.accepts)) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message:\n 'This endpoint has a missing or malformed accepts array in the Payment-Required header.',\n });\n }\n\n // Check amount against maxAmount before any payment logic\n const accept = await choosePaymentRequirement({\n options,\n paymentRequirements: paymentRequired.accepts,\n });\n\n if (accept) {\n const amount = tokenStringToNumber(accept.amount);\n\n const typedNetwork = caip2ToNetwork(accept.network)!;\n if (!typedNetwork) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message: `Invalid network: ${accept.network}`,\n });\n }\n\n const beforePaymentResult = await beforePayment({\n options,\n balanceInput:\n typedNetwork === Network.SOLANA\n ? {\n address: wallets.svm.address,\n network: Network.SOLANA,\n }\n : {\n address: wallets.evm.address,\n network: typedNetwork,\n },\n amount,\n protocol: PaymentProtocol.X402,\n });\n\n if (beforePaymentResult.isErr()) {\n return beforePaymentResult;\n }\n }\n\n const paymentPayloadResult = await safeCreatePaymentPayload(\n surface,\n wallets,\n paymentRequired,\n accept ? () => accept : undefined\n );\n\n if (paymentPayloadResult.isErr()) {\n return paymentPayloadResult;\n }\n\n const paymentPayload = paymentPayloadResult.value;\n\n const paymentHeaders =\n x402ProbeClient.encodePaymentSignatureHeader(paymentPayload);\n\n if (\n request.headers.has('PAYMENT-SIGNATURE') ||\n request.headers.has('X-PAYMENT')\n ) {\n return x402Err(surface, {\n cause: 'payment_already_attempted',\n message: 'Payment already attempted',\n });\n }\n\n for (const [key, value] of Object.entries(paymentHeaders)) {\n request.headers.set(key, value);\n }\n request.headers.set(\n 'Access-Control-Expose-Headers',\n 'PAYMENT-RESPONSE,X-PAYMENT-RESPONSE'\n );\n\n const paidResult = await safeFetch(surface, request, timeout);\n if (paidResult.isErr()) {\n return paidResult;\n }\n const paidResponse = paidResult.value;\n\n const permit2Error = await detectPermit2AllowanceError(\n surface,\n paidResponse,\n {\n walletAddress: wallets.evm.address,\n scheme: paymentPayload.accepted.scheme,\n }\n );\n if (permit2Error) {\n return x402Err(surface, permit2Error);\n }\n\n const settlementResult = safeGetPaymentSettlement(surface, paidResponse);\n\n const settlement = settlementResult.isOk() ? settlementResult.value : null;\n\n const maxAmount = tokenStringToNumber(paymentPayload.accepted.amount);\n const settledAmount = settlement?.amount\n ? tokenStringToNumber(settlement.amount)\n : null;\n const isUpTo = paymentPayload.accepted.scheme === 'upto';\n\n const price =\n settledAmount != null\n ? formatUsd(settledAmount)\n : isUpTo\n ? `up to ${formatUsd(maxAmount)}`\n : formatUsd(maxAmount);\n\n return x402Ok<ExecuteFetchResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: PaymentProtocol.X402,\n network: caip2ToNetwork(paymentPayload.accepted.network)!,\n price,\n payment: settlement\n ? {\n success: settlement.success,\n transactionHash: settlement.transaction,\n }\n : null,\n },\n });\n}\n\nasync function detectPermit2AllowanceError(\n surface: string,\n response: Response,\n context: { walletAddress: string; scheme: string }\n): Promise<BaseX402Error | null> {\n if (response.ok) {\n return null;\n }\n const body = await safeReadResponseText(surface, response).unwrapOr('');\n if (!isPermit2AllowanceFailureBody(body)) {\n return null;\n }\n return {\n cause: 'permit2_allowance_required',\n message: buildPermit2AllowanceErrorMessage(context),\n };\n}\n","import { detectPaymentProtocols } from '@/shared/protocols/detect';\nimport { handleMppPayment } from '@/shared/protocols/mpp/handle-payment';\nimport { pickByBalance } from '@/shared/protocols/pick';\nimport { PaymentProtocol } from '@/shared/protocols/types';\nimport { handleX402Payment } from '@/shared/protocols/x402/handle-payment';\n\nimport type { ExecuteFetchOptions } from './types';\n\nexport async function executePayment(\n response: Response,\n request: Request,\n options: ExecuteFetchOptions\n) {\n const { paymentProtocol } = options.params;\n\n const params = {\n response,\n request,\n options,\n };\n\n if (paymentProtocol) {\n return handlerMap[paymentProtocol](params);\n }\n\n const available = detectPaymentProtocols(response);\n const preferred =\n available.length === 1\n ? available[0]!\n : await pickByBalance(response, options);\n const fallback =\n available.length > 1\n ? preferred === PaymentProtocol.MPP\n ? PaymentProtocol.X402\n : PaymentProtocol.MPP\n : null;\n\n const fallbackRetryRequest = fallback ? request.clone() : null;\n const result = await handlerMap[preferred](params);\n\n if (result.isErr() && fallback && fallbackRetryRequest) {\n return handlerMap[fallback]({\n ...params,\n request: fallbackRetryRequest,\n });\n }\n\n return result;\n}\n\nconst handlerMap = {\n [PaymentProtocol.MPP]: handleMppPayment,\n [PaymentProtocol.X402]: handleX402Payment,\n};\n","import { fetchErr, fetchOk, safeFetch } from '@/shared/neverthrow/fetch';\nimport { BLACKLISTED_ORIGINS } from '@/shared/origins';\n\nimport { attemptSiwxAuth } from './auth';\nimport { executePayment } from './payment';\n\nimport type { ExecuteFetchOptions } from './types';\nimport { buildRequest } from '@/shared/request/build';\nimport type { RequestInput } from '@/shared/request/types';\n\n/**\n * Executes a request with automatic SIWX authentication and payment handling.\n *\n * 1. Probe the endpoint\n * 2. If 402 with SIWX challenge, retry with SIGN-IN-WITH-X\n * 3. If still 402, execute payment\n */\nexport async function executeFetch(\n input: RequestInput,\n options: ExecuteFetchOptions\n) {\n const request = buildRequest(input, options);\n\n const { surface } = options;\n const { timeout } = options.params;\n\n const blocked = BLACKLISTED_ORIGINS.find(origin =>\n request.url.startsWith(origin)\n );\n if (blocked) {\n return fetchErr(surface, {\n cause: 'network',\n message: `${blocked} is no longer available. This origin has been deprecated.`,\n });\n }\n\n const authRetryRequest = request.clone();\n const paymentRetryRequest = request.clone();\n\n const probeResult = await safeFetch(surface, request, timeout);\n\n if (probeResult.isErr()) {\n return fetchErr(surface, probeResult.error);\n }\n\n const initialResponse = probeResult.value;\n if (initialResponse.status !== 402) {\n return fetchOk({\n response: initialResponse,\n paymentInfo: null,\n });\n }\n\n const authResult = await attemptSiwxAuth(\n initialResponse,\n authRetryRequest,\n paymentRetryRequest,\n options\n );\n\n if (authResult.isErr()) {\n return authResult;\n }\n\n const latestResponse = authResult.value.response;\n if (latestResponse.status !== 402) {\n return fetchOk({\n response: latestResponse,\n paymentInfo: null,\n });\n }\n\n return executePayment(\n latestResponse,\n authResult.value.paymentRetryRequest,\n options\n );\n}\n"],"mappings":"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","names":["tx","formatUnits","formatUnits"]}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createSessionStore,
|
|
3
2
|
createTempoClient,
|
|
3
|
+
deleteStoredChannel,
|
|
4
|
+
findStoredChannel,
|
|
4
5
|
mppErr,
|
|
5
6
|
mppOk,
|
|
6
7
|
mppResultFromPromise,
|
|
7
|
-
readStoredChannel,
|
|
8
8
|
safeGetMppChallenge,
|
|
9
|
-
sessionCloseFailedErr
|
|
10
|
-
|
|
11
|
-
} from "./chunk-B5G7TGCZ.js";
|
|
9
|
+
sessionCloseFailedErr
|
|
10
|
+
} from "./chunk-H2JGMFEG.js";
|
|
12
11
|
import {
|
|
13
12
|
safeFetch,
|
|
14
13
|
safeReadResponseText
|
|
@@ -20,18 +19,11 @@ import { Session } from "mppx/tempo";
|
|
|
20
19
|
async function closeMppSession(input, options) {
|
|
21
20
|
const { surface, wallets } = options;
|
|
22
21
|
const { channelId, url, cumulativeAmountRaw } = input;
|
|
23
|
-
const
|
|
24
|
-
const stored = readStoredChannel(scope);
|
|
22
|
+
const stored = findStoredChannel(wallets.evm.address, channelId);
|
|
25
23
|
if (!stored) {
|
|
26
24
|
return mppErr(surface, {
|
|
27
25
|
cause: "mpp_session_close_no_channel",
|
|
28
|
-
message: `No tracked MPP session for ${
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (channelId.toLowerCase() !== stored.channelId.toLowerCase()) {
|
|
32
|
-
return mppErr(surface, {
|
|
33
|
-
cause: "mpp_session_close_channel_mismatch",
|
|
34
|
-
message: `Requested channel ${channelId} does not match the tracked channel ${stored.channelId} for ${scope}.`
|
|
26
|
+
message: `No tracked MPP session channel ${channelId} for wallet ${wallets.evm.address}. agentcash records open channels per wallet; there is nothing to close (it may already be closed, or was opened by a different client).`
|
|
35
27
|
});
|
|
36
28
|
}
|
|
37
29
|
const probeResult = await safeFetch(
|
|
@@ -116,7 +108,7 @@ async function closeMppSession(input, options) {
|
|
|
116
108
|
}
|
|
117
109
|
const receiptHeader = closeResponse.headers.get("Payment-Receipt");
|
|
118
110
|
const receipt = receiptHeader ? Session.Precompile.Receipt.deserializeSessionReceipt(receiptHeader) : null;
|
|
119
|
-
|
|
111
|
+
deleteStoredChannel(wallets.evm.address, stored.channelId);
|
|
120
112
|
return mppOk({
|
|
121
113
|
channelId: stored.channelId,
|
|
122
114
|
cumulativeAmount: receipt?.spent ?? cumulativeRaw,
|
|
@@ -127,4 +119,4 @@ async function closeMppSession(input, options) {
|
|
|
127
119
|
export {
|
|
128
120
|
closeMppSession
|
|
129
121
|
};
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-FRESP5ZE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/operations/sessions/close.ts"],"sourcesContent":["import type { Hex } from 'viem';\n\nimport { Mppx, tempo as tempoMethod } from 'mppx/client';\nimport { Session } from 'mppx/tempo';\n\nimport { safeFetch, safeReadResponseText } from '@/shared/neverthrow/fetch';\nimport {\n createTempoClient,\n mppErr,\n mppOk,\n mppResultFromPromise,\n safeGetMppChallenge,\n sessionCloseFailedErr,\n} from '@/shared/protocols/mpp';\nimport {\n deleteStoredChannel,\n findStoredChannel,\n} from '@/shared/protocols/mpp/session/session-store';\n\nimport type { GlobalFlags } from '@/types';\nimport type { Wallets } from '@/wallet';\n\nexport interface CloseSessionInput {\n channelId: Hex;\n url: string;\n cumulativeAmountRaw?: string;\n}\n\nexport interface CloseSessionOptions {\n surface: string;\n wallets: Wallets;\n flags: GlobalFlags;\n}\n\nexport interface CloseSessionResult {\n channelId: Hex;\n cumulativeAmount: string;\n transactionHash?: string;\n}\n\n/**\n * Closes a TIP-1034 (v2) Tempo session out of band.\n *\n * v2 channels can only be closed with their on-chain descriptor, which the\n * fetch flow persists per wallet via {@link createSessionChannelStore}. We load\n * that stored channel, sign a `close` credential against a fresh server\n * challenge, POST it for the server to settle on-chain, and drop the stored\n * hint.\n */\nexport async function closeMppSession(\n input: CloseSessionInput,\n options: CloseSessionOptions\n) {\n const { surface, wallets } = options;\n const { channelId, url, cumulativeAmountRaw } = input;\n\n const stored = findStoredChannel(wallets.evm.address, channelId);\n if (!stored) {\n return mppErr(surface, {\n cause: 'mpp_session_close_no_channel',\n message: `No tracked MPP session channel ${channelId} for wallet ${wallets.evm.address}. agentcash records open channels per wallet; there is nothing to close (it may already be closed, or was opened by a different client).`,\n });\n }\n\n const probeResult = await safeFetch(\n surface,\n new Request(url, { method: 'POST' })\n );\n if (probeResult.isErr()) {\n return mppErr(\n surface,\n sessionCloseFailedErr(\n probeResult.error.message,\n `Failed to probe ${url} for a session challenge`\n )\n );\n }\n const probeResponse = probeResult.value;\n\n if (probeResponse.status !== 402) {\n return mppErr(surface, {\n cause: 'mpp_session_close_no_challenge',\n message: `Expected a 402 session challenge from ${url}, received ${probeResponse.status} ${probeResponse.statusText}. The endpoint may not be MPP-protected or the channel has already been closed.`,\n });\n }\n\n const challengeResult = safeGetMppChallenge(surface, probeResponse);\n if (challengeResult.isErr()) {\n return challengeResult;\n }\n const challenge = challengeResult.value;\n\n if (challenge.intent !== 'session') {\n return mppErr(surface, {\n cause: 'mpp_session_close_no_challenge',\n message: `${url} returned a ${challenge.method}:${challenge.intent} challenge, not a session challenge.`,\n });\n }\n\n const cumulativeRaw = cumulativeAmountRaw ?? stored.cumulativeAmount;\n\n const mppx = Mppx.create({\n polyfill: false,\n methods: [\n tempoMethod({ account: wallets.evm, getClient: createTempoClient }),\n ],\n });\n\n const credentialResult = await mppResultFromPromise(\n surface,\n mppx.createCredential(probeResponse, {\n action: 'close',\n channelId: stored.channelId,\n cumulativeAmountRaw: cumulativeRaw,\n descriptor: stored.descriptor,\n }),\n e => sessionCloseFailedErr(e, 'Failed to sign close credential')\n );\n if (credentialResult.isErr()) {\n return credentialResult;\n }\n\n const closeResult = await safeFetch(\n surface,\n new Request(url, {\n method: 'POST',\n headers: { Authorization: credentialResult.value },\n })\n );\n if (closeResult.isErr()) {\n return mppErr(\n surface,\n sessionCloseFailedErr(\n closeResult.error.message,\n `Close POST to ${url} failed`\n )\n );\n }\n const closeResponse = closeResult.value;\n\n if (!closeResponse.ok) {\n const body = await safeReadResponseText(surface, closeResponse).unwrapOr(\n ''\n );\n const detail = body ? `: ${body}` : '';\n return mppErr(\n surface,\n sessionCloseFailedErr(\n `Server rejected close credential with ${closeResponse.status} ${closeResponse.statusText}${detail}. The cumulative-amount may be below the server's voucher state — retry with --cumulative-amount-raw set to the server's expected value.`\n )\n );\n }\n\n const receiptHeader = closeResponse.headers.get('Payment-Receipt');\n const receipt = receiptHeader\n ? Session.Precompile.Receipt.deserializeSessionReceipt(receiptHeader)\n : null;\n\n // Channel is settled on-chain — drop the stored hint so the next request to\n // this payee opens a fresh channel instead of reusing a closed one.\n deleteStoredChannel(wallets.evm.address, stored.channelId);\n\n return mppOk<CloseSessionResult>({\n channelId: stored.channelId,\n cumulativeAmount: receipt?.spent ?? cumulativeRaw,\n ...(receipt?.txHash ? { transactionHash: receipt.txHash } : {}),\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -89,6 +89,7 @@ var safeGetMppReceipt = (surface, response) => {
|
|
|
89
89
|
|
|
90
90
|
// src/shared/protocols/mpp/session/session-store.ts
|
|
91
91
|
import fs from "fs";
|
|
92
|
+
import { createJsonChannelStore } from "mppx/client";
|
|
92
93
|
var SESSIONS_FILE = configFile("sessions.json");
|
|
93
94
|
function readAll() {
|
|
94
95
|
if (!fs.existsSync(SESSIONS_FILE)) return {};
|
|
@@ -107,35 +108,70 @@ function readAll() {
|
|
|
107
108
|
function writeAll(all) {
|
|
108
109
|
fs.writeFileSync(SESSIONS_FILE, JSON.stringify(all, null, 2));
|
|
109
110
|
}
|
|
110
|
-
function
|
|
111
|
-
return
|
|
111
|
+
function namespaceFor(walletAddress) {
|
|
112
|
+
return walletAddress.toLowerCase();
|
|
112
113
|
}
|
|
113
|
-
function
|
|
114
|
+
function walletKv(walletAddress) {
|
|
115
|
+
const ns = namespaceFor(walletAddress);
|
|
114
116
|
return {
|
|
115
|
-
get() {
|
|
116
|
-
|
|
117
|
-
return isUsableEntry(entry) ? entry : null;
|
|
117
|
+
get(key) {
|
|
118
|
+
return readAll()[ns]?.[key];
|
|
118
119
|
},
|
|
119
|
-
set(
|
|
120
|
+
set(key, value) {
|
|
120
121
|
const all = readAll();
|
|
121
|
-
all[
|
|
122
|
+
(all[ns] ??= {})[key] = value;
|
|
122
123
|
writeAll(all);
|
|
123
124
|
},
|
|
124
|
-
delete() {
|
|
125
|
+
delete(key) {
|
|
125
126
|
const all = readAll();
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
const bucket = all[ns];
|
|
128
|
+
if (bucket && key in bucket) {
|
|
129
|
+
delete bucket[key];
|
|
128
130
|
writeAll(all);
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
};
|
|
132
134
|
}
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
return isUsableEntry(entry) ? entry : null;
|
|
135
|
+
function createSessionChannelStore(walletAddress) {
|
|
136
|
+
return createJsonChannelStore(walletKv(walletAddress));
|
|
136
137
|
}
|
|
137
|
-
function
|
|
138
|
-
|
|
138
|
+
function parseStored(value) {
|
|
139
|
+
const parsed = resultFromThrowable(
|
|
140
|
+
"sessions_read_failed",
|
|
141
|
+
"mpp:session-store",
|
|
142
|
+
() => JSON.parse(value),
|
|
143
|
+
(e) => ({
|
|
144
|
+
cause: "sessions_read_failed",
|
|
145
|
+
message: e instanceof Error ? e.message : String(e)
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
if (parsed.isErr()) return null;
|
|
149
|
+
const obj = parsed.value;
|
|
150
|
+
return obj && typeof obj === "object" && typeof obj.channelId === "string" && typeof obj.cumulativeAmount === "string" && obj.descriptor != null ? obj : null;
|
|
151
|
+
}
|
|
152
|
+
function findStoredChannel(walletAddress, channelId) {
|
|
153
|
+
const bucket = readAll()[namespaceFor(walletAddress)];
|
|
154
|
+
if (!bucket) return null;
|
|
155
|
+
for (const value of Object.values(bucket)) {
|
|
156
|
+
const parsed = parseStored(value);
|
|
157
|
+
if (parsed?.channelId.toLowerCase() === channelId.toLowerCase()) {
|
|
158
|
+
return parsed;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
function deleteStoredChannel(walletAddress, channelId) {
|
|
164
|
+
const all = readAll();
|
|
165
|
+
const bucket = all[namespaceFor(walletAddress)];
|
|
166
|
+
if (!bucket) return;
|
|
167
|
+
for (const [key, value] of Object.entries(bucket)) {
|
|
168
|
+
const parsed = parseStored(value);
|
|
169
|
+
if (parsed?.channelId.toLowerCase() === channelId.toLowerCase()) {
|
|
170
|
+
delete bucket[key];
|
|
171
|
+
writeAll(all);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
139
175
|
}
|
|
140
176
|
|
|
141
177
|
export {
|
|
@@ -149,8 +185,8 @@ export {
|
|
|
149
185
|
safeGetMppChallenge,
|
|
150
186
|
safeCreateMppCredential,
|
|
151
187
|
safeGetMppReceipt,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
188
|
+
createSessionChannelStore,
|
|
189
|
+
findStoredChannel,
|
|
190
|
+
deleteStoredChannel
|
|
155
191
|
};
|
|
156
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-H2JGMFEG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shared/protocols/mpp/index.ts","../../src/shared/protocols/mpp/session/session-store.ts"],"sourcesContent":["import { Challenge, Receipt } from 'mppx';\nimport { Methods } from 'mppx/tempo';\nimport {\n err,\n ok,\n resultFromPromise,\n resultFromThrowable,\n} from '@agentcash/neverthrow';\n\nimport { Mppx, tempo as tempoMethod } from 'mppx/client';\n\nimport { type Address, createClient, http } from 'viem';\n\nimport { EVM_CONFIGS, Network } from '@agentcash/networks';\n\nimport type { BaseMppError } from './types';\nimport type { Wallets } from '@/wallet';\n\nconst errorType = 'mpp';\n\nexport const mppOk = <T>(value: T) => ok(value);\nexport const mppErr = (surface: string, error: BaseMppError) =>\n err(errorType, surface, error);\n\nconst formatErrMsg = (e: unknown, prefix?: string) => {\n const msg =\n e instanceof Error ? e.message : typeof e === 'string' ? e : String(e);\n return prefix ? `${prefix}: ${msg}` : msg;\n};\n\nexport const sessionRequestFailedErr = (e: unknown, prefix?: string) => ({\n cause: 'mpp_session_request_failed' as const,\n message: formatErrMsg(e, prefix),\n});\n\nexport const sessionCloseFailedErr = (e: unknown, prefix?: string) => ({\n cause: 'mpp_session_close_failed' as const,\n message: formatErrMsg(e, prefix),\n});\n\nexport const mppResultFromPromise = <T>(\n surface: string,\n promise: Promise<T>,\n error: (e: unknown) => BaseMppError\n) => resultFromPromise(errorType, surface, promise, error);\n\nexport const mppResultFromThrowable = <T>(\n surface: string,\n fn: () => T,\n error: (e: unknown) => BaseMppError\n) => resultFromThrowable(errorType, surface, fn, error);\n\nexport const createTempoClient = () =>\n createClient({\n chain: EVM_CONFIGS[Network.TEMPO].chain,\n transport: http(EVM_CONFIGS[Network.TEMPO].rpcUrl),\n });\n\nexport const assertTempoUsdc = (surface: string, tokenAddress: Address) => {\n const expected = EVM_CONFIGS[Network.TEMPO].usdcAddress;\n if (tokenAddress.toLowerCase() === expected.toLowerCase()) {\n return mppOk(true);\n }\n return mppErr(surface, {\n cause: 'unsupported_token',\n message: `Endpoint requires payment in token ${tokenAddress} on Tempo, but agentcash only supports ${expected}. The endpoint may be configured for a different token (e.g. PathUSD vs USDC).`,\n });\n};\n\nexport const safeGetMppChallenge = (surface: string, response: Response) => {\n return mppResultFromThrowable(\n surface,\n () =>\n Challenge.fromResponse(response, {\n methods: [Methods.charge, Methods.session],\n }),\n error => ({\n cause: 'parse_mpp_challenge',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse MPP challenge from response',\n })\n );\n};\n\nexport const safeCreateMppCredential = (\n surface: string,\n wallets: Wallets,\n response: Response\n) => {\n const client = Mppx.create({\n polyfill: false,\n methods: [\n tempoMethod({\n account: wallets.evm,\n getClient: createTempoClient,\n }),\n ],\n });\n\n return mppResultFromPromise(\n surface,\n client.createCredential(response),\n error => ({\n cause: 'create_mpp_credential',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to create MPP credential',\n })\n );\n};\n\nexport const safeGetMppReceipt = (surface: string, response: Response) => {\n return mppResultFromThrowable(\n surface,\n () => Receipt.fromResponse(response),\n error => ({\n cause: 'parse_mpp_receipt',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse MPP receipt from response',\n })\n );\n};\n","import fs from 'fs';\n\nimport { resultFromThrowable } from '@agentcash/neverthrow';\nimport { createJsonChannelStore } from 'mppx/client';\nimport type { ChannelStore, JsonChannelKv } from 'mppx/client';\nimport type { Session } from 'mppx/tempo';\n\nimport { configFile } from '@/shared/fs';\n\nimport type { Hex } from 'viem';\n\nconst SESSIONS_FILE = configFile('sessions.json');\n\n/**\n * On-disk shape: `{ [walletAddressLower]: { [channelStoreKey]: serializedEntry } }`.\n *\n * mppx's {@link createJsonChannelStore} persists each channel as a JSON string\n * keyed by an internal `channelKey` (derived from payee/token/escrow/chainId).\n * We namespace those keys under the lowercased wallet address — see\n * {@link walletKv} for why.\n */\ntype SessionsFile = Record<string, Record<string, string>>;\n\n/**\n * The fields agentcash reads back from a persisted channel to close it out of\n * band. A superset of mppx's (non-exported) `StoredChannel` JSON shape.\n */\nexport interface StoredChannelHint {\n channelId: Hex;\n cumulativeAmount: string;\n descriptor: Session.Precompile.Types.ChannelDescriptor;\n}\n\nfunction readAll(): SessionsFile {\n if (!fs.existsSync(SESSIONS_FILE)) return {};\n const parsed = resultFromThrowable(\n 'sessions_read_failed',\n 'mpp:session-store',\n () => JSON.parse(fs.readFileSync(SESSIONS_FILE, 'utf-8')) as unknown,\n e => ({\n cause: 'sessions_read_failed' as const,\n message: e instanceof Error ? e.message : String(e),\n })\n );\n // A corrupt or unreadable file should never block a payment — start fresh.\n if (parsed.isErr()) return {};\n return parsed.value && typeof parsed.value === 'object'\n ? (parsed.value as SessionsFile)\n : {};\n}\n\nfunction writeAll(all: SessionsFile): void {\n fs.writeFileSync(SESSIONS_FILE, JSON.stringify(all, null, 2));\n}\n\nfunction namespaceFor(walletAddress: string): string {\n return walletAddress.toLowerCase();\n}\n\n/**\n * A file-backed {@link JsonChannelKv} scoped to a single wallet.\n *\n * mppx's channel key (`channelKey`) is derived from payee/token/escrow/chainId\n * and deliberately excludes the payer, so two wallets paying the same payee\n * would collide on one key. Namespacing the KV by wallet keeps a stored channel\n * reusable only by the wallet that opened it — preserving the per-payer\n * isolation the v1 `walletAddress:origin` scope provided.\n */\nfunction walletKv(walletAddress: string): JsonChannelKv {\n const ns = namespaceFor(walletAddress);\n return {\n get(key) {\n return readAll()[ns]?.[key];\n },\n set(key, value) {\n const all = readAll();\n (all[ns] ??= {})[key] = value;\n writeAll(all);\n },\n delete(key) {\n const all = readAll();\n const bucket = all[ns];\n if (bucket && key in bucket) {\n delete bucket[key];\n writeAll(all);\n }\n },\n };\n}\n\n/**\n * Per-wallet {@link ChannelStore} backed by `~/.agentcash/sessions.json`.\n *\n * Lets the v2 session manager reuse an open channel across separate `fetch`\n * invocations and process restarts, and gives `sessions_close` the descriptor\n * it needs to settle a channel out of band — and only ever by the wallet that\n * opened it (see {@link walletKv}).\n */\nexport function createSessionChannelStore(walletAddress: string): ChannelStore {\n return createJsonChannelStore(walletKv(walletAddress));\n}\n\nfunction parseStored(value: string): StoredChannelHint | null {\n const parsed = resultFromThrowable(\n 'sessions_read_failed',\n 'mpp:session-store',\n () => JSON.parse(value) as Partial<StoredChannelHint>,\n e => ({\n cause: 'sessions_read_failed' as const,\n message: e instanceof Error ? e.message : String(e),\n })\n );\n if (parsed.isErr()) return null;\n const obj = parsed.value;\n return obj &&\n typeof obj === 'object' &&\n typeof obj.channelId === 'string' &&\n typeof obj.cumulativeAmount === 'string' &&\n obj.descriptor != null\n ? (obj as StoredChannelHint)\n : null;\n}\n\n/** Finds a stored channel for a wallet by its channel id, if one is persisted. */\nexport function findStoredChannel(\n walletAddress: string,\n channelId: string\n): StoredChannelHint | null {\n const bucket = readAll()[namespaceFor(walletAddress)];\n if (!bucket) return null;\n for (const value of Object.values(bucket)) {\n const parsed = parseStored(value);\n if (parsed?.channelId.toLowerCase() === channelId.toLowerCase()) {\n return parsed;\n }\n }\n return null;\n}\n\n/** Drops a stored channel for a wallet by its channel id (after it is closed). */\nexport function deleteStoredChannel(\n walletAddress: string,\n channelId: string\n): void {\n const all = readAll();\n const bucket = all[namespaceFor(walletAddress)];\n if (!bucket) return;\n for (const [key, value] of Object.entries(bucket)) {\n const parsed = parseStored(value);\n if (parsed?.channelId.toLowerCase() === channelId.toLowerCase()) {\n delete bucket[key];\n writeAll(all);\n return;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,7 +4,7 @@ import { dirname, join } from "path";
|
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
function getVersion() {
|
|
6
6
|
if (true) {
|
|
7
|
-
return "0.16.
|
|
7
|
+
return "0.16.2";
|
|
8
8
|
}
|
|
9
9
|
const __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
const pkg = JSON.parse(
|
|
@@ -23,4 +23,4 @@ export {
|
|
|
23
23
|
MCP_VERSION,
|
|
24
24
|
INSTALL_PACKAGE_SPECIFIER
|
|
25
25
|
};
|
|
26
|
-
//# sourceMappingURL=chunk-
|
|
26
|
+
//# sourceMappingURL=chunk-V264YU5J.js.map
|
|
@@ -5,8 +5,8 @@ import "./chunk-Q5YKPVXL.js";
|
|
|
5
5
|
import "./chunk-H5V6L7NG.js";
|
|
6
6
|
import {
|
|
7
7
|
executeFetch
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-F4YE5YSG.js";
|
|
9
|
+
import "./chunk-H2JGMFEG.js";
|
|
10
10
|
import "./chunk-4TIYIVZF.js";
|
|
11
11
|
import "./chunk-IKPLMFAK.js";
|
|
12
12
|
import "./chunk-LNJIXYCU.js";
|
|
@@ -90,4 +90,4 @@ var fetchCommand = async (input) => {
|
|
|
90
90
|
export {
|
|
91
91
|
fetchCommand
|
|
92
92
|
};
|
|
93
|
-
//# sourceMappingURL=fetch-
|
|
93
|
+
//# sourceMappingURL=fetch-OXPSOIQ3.js.map
|
package/dist/esm/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-27DZCYDB.js";
|
|
8
8
|
import {
|
|
9
9
|
MCP_VERSION
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-V264YU5J.js";
|
|
11
11
|
import {
|
|
12
12
|
paymentNetworks,
|
|
13
13
|
paymentProtocols,
|
|
@@ -120,7 +120,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
120
120
|
DESCRIPTIONS.fetch.epilogue
|
|
121
121
|
),
|
|
122
122
|
async (args) => {
|
|
123
|
-
const { fetchCommand } = await import("./fetch-
|
|
123
|
+
const { fetchCommand } = await import("./fetch-OXPSOIQ3.js");
|
|
124
124
|
await fetchCommand(args);
|
|
125
125
|
}
|
|
126
126
|
).command(
|
|
@@ -132,7 +132,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
132
132
|
DESCRIPTIONS.fetchWithAuth.epilogue
|
|
133
133
|
),
|
|
134
134
|
async (args) => {
|
|
135
|
-
const { fetchCommand } = await import("./fetch-
|
|
135
|
+
const { fetchCommand } = await import("./fetch-OXPSOIQ3.js");
|
|
136
136
|
await fetchCommand(args);
|
|
137
137
|
}
|
|
138
138
|
).command(
|
|
@@ -198,7 +198,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
198
198
|
description: TOOL_PARAMS.search.page
|
|
199
199
|
}),
|
|
200
200
|
async (args) => {
|
|
201
|
-
const { searchCommand } = await import("./search-
|
|
201
|
+
const { searchCommand } = await import("./search-ZFXKWMRP.js");
|
|
202
202
|
await searchCommand(args);
|
|
203
203
|
}
|
|
204
204
|
).command(
|
|
@@ -225,7 +225,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
225
225
|
demandOption: true
|
|
226
226
|
}),
|
|
227
227
|
async (args) => {
|
|
228
|
-
const { registerCommand } = await import("./register-
|
|
228
|
+
const { registerCommand } = await import("./register-35JC4M2E.js");
|
|
229
229
|
await registerCommand(args);
|
|
230
230
|
}
|
|
231
231
|
).command(
|
|
@@ -297,7 +297,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
297
297
|
description: TOOL_PARAMS.closeSession.cumulativeAmountRaw
|
|
298
298
|
}).epilogue(DESCRIPTIONS.closeSession.epilogue),
|
|
299
299
|
async (args) => {
|
|
300
|
-
const { sessionsCloseCommand } = await import("./sessions-
|
|
300
|
+
const { sessionsCloseCommand } = await import("./sessions-RXMJRALZ.js");
|
|
301
301
|
await sessionsCloseCommand({
|
|
302
302
|
...args,
|
|
303
303
|
channelId: args.channelId,
|
|
@@ -316,7 +316,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
316
316
|
description: "The invite code to redeem (optional)"
|
|
317
317
|
}),
|
|
318
318
|
async (args) => {
|
|
319
|
-
const { onboardCommand } = await import("./onboard-
|
|
319
|
+
const { onboardCommand } = await import("./onboard-263VMOOP.js");
|
|
320
320
|
await onboardCommand({ ...args, code: args.code ?? args.invite });
|
|
321
321
|
}
|
|
322
322
|
).command(
|
|
@@ -445,7 +445,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
445
445
|
description: TOOL_PARAMS.reportError.fullReport
|
|
446
446
|
}),
|
|
447
447
|
async (args) => {
|
|
448
|
-
const { reportErrorCommand } = await import("./report-error-
|
|
448
|
+
const { reportErrorCommand } = await import("./report-error-TXNPOHTY.js");
|
|
449
449
|
await reportErrorCommand(args);
|
|
450
450
|
}
|
|
451
451
|
).command(
|
|
@@ -475,7 +475,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
475
475
|
"Start the MCP server (default when no command specified)",
|
|
476
476
|
(yargs2) => yargs2,
|
|
477
477
|
async (args) => {
|
|
478
|
-
const { serverCommand } = await import("./server-
|
|
478
|
+
const { serverCommand } = await import("./server-ECAFH7U2.js");
|
|
479
479
|
await serverCommand(args);
|
|
480
480
|
}
|
|
481
481
|
).command(
|
|
@@ -489,7 +489,7 @@ void yargs(hideBin(process.argv)).scriptName("agentcash").usage("$0 [command] [o
|
|
|
489
489
|
default: isClaudeCode ? "claude-code" /* ClaudeCode */ : void 0
|
|
490
490
|
}),
|
|
491
491
|
async (args) => {
|
|
492
|
-
const { installMcpServer } = await import("./install-
|
|
492
|
+
const { installMcpServer } = await import("./install-RCJYUZA6.js");
|
|
493
493
|
await installMcpServer(args);
|
|
494
494
|
}
|
|
495
495
|
).command(
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-C7B6LEPE.js";
|
|
4
4
|
import {
|
|
5
5
|
addServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3XQN4TFL.js";
|
|
7
7
|
import {
|
|
8
8
|
wait
|
|
9
9
|
} from "./chunk-DZNSJ2BA.js";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
Clients,
|
|
15
15
|
clientMetadata
|
|
16
16
|
} from "./chunk-27DZCYDB.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-V264YU5J.js";
|
|
18
18
|
import "./chunk-ISF2WVEZ.js";
|
|
19
19
|
import {
|
|
20
20
|
getBalance
|
|
@@ -176,4 +176,4 @@ var installMcpServer = async (args) => {
|
|
|
176
176
|
export {
|
|
177
177
|
installMcpServer
|
|
178
178
|
};
|
|
179
|
-
//# sourceMappingURL=install-
|
|
179
|
+
//# sourceMappingURL=install-RCJYUZA6.js.map
|