mppx 0.7.0 → 0.8.1
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/CHANGELOG.md +41 -0
- package/README.md +20 -11
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +18 -6
- package/dist/Challenge.js.map +1 -1
- package/dist/Mcp.d.ts +3 -0
- package/dist/Mcp.d.ts.map +1 -1
- package/dist/Mcp.js +2 -0
- package/dist/Mcp.js.map +1 -1
- package/dist/PaymentRequest.d.ts +10 -10
- package/dist/PaymentRequest.js +8 -8
- package/dist/cli/internal.d.ts +1 -0
- package/dist/cli/internal.d.ts.map +1 -1
- package/dist/cli/internal.js +1 -15
- package/dist/cli/internal.js.map +1 -1
- package/dist/client/Mppx.js +2 -2
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/Transport.d.ts +11 -16
- package/dist/client/Transport.d.ts.map +1 -1
- package/dist/client/Transport.js +55 -75
- package/dist/client/Transport.js.map +1 -1
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +46 -7
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/client/internal/protocols/Mcp.d.ts +7 -0
- package/dist/client/internal/protocols/Mcp.d.ts.map +1 -0
- package/dist/client/internal/protocols/Mcp.js +159 -0
- package/dist/client/internal/protocols/Mcp.js.map +1 -0
- package/dist/client/internal/protocols/Mpp.d.ts +4 -0
- package/dist/client/internal/protocols/Mpp.d.ts.map +1 -0
- package/dist/client/internal/protocols/Mpp.js +18 -0
- package/dist/client/internal/protocols/Mpp.js.map +1 -0
- package/dist/client/internal/protocols/Protocol.d.ts +10 -0
- package/dist/client/internal/protocols/Protocol.d.ts.map +1 -0
- package/dist/client/internal/protocols/Protocol.js +2 -0
- package/dist/client/internal/protocols/Protocol.js.map +1 -0
- package/dist/client/internal/protocols/Shared.d.ts +5 -0
- package/dist/client/internal/protocols/Shared.d.ts.map +1 -0
- package/dist/client/internal/protocols/Shared.js +20 -0
- package/dist/client/internal/protocols/Shared.js.map +1 -0
- package/dist/client/internal/protocols/X402.d.ts +8 -0
- package/dist/client/internal/protocols/X402.d.ts.map +1 -0
- package/dist/client/internal/protocols/X402.js +39 -0
- package/dist/client/internal/protocols/X402.js.map +1 -0
- package/dist/evm/client/index.d.ts +1 -0
- package/dist/evm/client/index.d.ts.map +1 -1
- package/dist/evm/client/index.js +1 -0
- package/dist/evm/client/index.js.map +1 -1
- package/dist/evm/index.d.ts +2 -0
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +2 -0
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/server/index.d.ts +1 -0
- package/dist/evm/server/index.d.ts.map +1 -1
- package/dist/evm/server/index.js +1 -0
- package/dist/evm/server/index.js.map +1 -1
- package/dist/mcp/client/McpClient.d.ts +101 -0
- package/dist/mcp/client/McpClient.d.ts.map +1 -0
- package/dist/mcp/client/McpClient.js +162 -0
- package/dist/mcp/client/McpClient.js.map +1 -0
- package/dist/mcp/client/index.d.ts.map +1 -0
- package/dist/mcp/client/index.js.map +1 -0
- package/dist/mcp/server/Transport.d.ts.map +1 -0
- package/dist/mcp/server/Transport.js.map +1 -0
- package/dist/mcp/server/index.d.ts.map +1 -0
- package/dist/mcp/server/index.js.map +1 -0
- package/dist/server/Mppx.d.ts +1 -1
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +9 -0
- package/dist/server/Mppx.js.map +1 -1
- package/dist/server/Transport.d.ts +1 -1
- package/dist/server/Transport.d.ts.map +1 -1
- package/dist/server/Transport.js +1 -1
- package/dist/server/Transport.js.map +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/Proof.d.ts +85 -1
- package/dist/tempo/Proof.d.ts.map +1 -1
- package/dist/tempo/Proof.js +35 -0
- package/dist/tempo/Proof.js.map +1 -1
- package/dist/tempo/client/Charge.d.ts +13 -1
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +38 -25
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Methods.d.ts +5 -3
- package/dist/tempo/client/Methods.d.ts.map +1 -1
- package/dist/tempo/client/Methods.js +4 -2
- package/dist/tempo/client/Methods.js.map +1 -1
- package/dist/tempo/client/ResolveAccount.d.ts +40 -0
- package/dist/tempo/client/ResolveAccount.d.ts.map +1 -0
- package/dist/tempo/client/ResolveAccount.js +2 -0
- package/dist/tempo/client/ResolveAccount.js.map +1 -0
- package/dist/tempo/internal/fee-payer.d.ts +26 -1
- package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
- package/dist/tempo/internal/fee-payer.js +83 -30
- package/dist/tempo/internal/fee-payer.js.map +1 -1
- package/dist/tempo/internal/proof.d.ts +71 -5
- package/dist/tempo/internal/proof.d.ts.map +1 -1
- package/dist/tempo/internal/proof.js +42 -6
- package/dist/tempo/internal/proof.js.map +1 -1
- package/dist/tempo/legacy/client/SessionManager.d.ts.map +1 -1
- package/dist/tempo/legacy/client/SessionManager.js +10 -3
- package/dist/tempo/legacy/client/SessionManager.js.map +1 -1
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +46 -18
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Methods.d.ts +4 -2
- package/dist/tempo/server/Methods.d.ts.map +1 -1
- package/dist/tempo/server/Methods.js +4 -2
- package/dist/tempo/server/Methods.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +10 -0
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/Subscription.js +135 -23
- package/dist/tempo/server/Subscription.js.map +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/session/client/ChannelOps.d.ts +2 -3
- package/dist/tempo/session/client/ChannelOps.d.ts.map +1 -1
- package/dist/tempo/session/client/ChannelOps.js +7 -10
- package/dist/tempo/session/client/ChannelOps.js.map +1 -1
- package/dist/tempo/session/client/ChannelStore.d.ts +51 -0
- package/dist/tempo/session/client/ChannelStore.d.ts.map +1 -0
- package/dist/tempo/session/client/ChannelStore.js +63 -0
- package/dist/tempo/session/client/ChannelStore.js.map +1 -0
- package/dist/tempo/session/client/CredentialState.d.ts +7 -24
- package/dist/tempo/session/client/CredentialState.d.ts.map +1 -1
- package/dist/tempo/session/client/CredentialState.js +51 -49
- package/dist/tempo/session/client/CredentialState.js.map +1 -1
- package/dist/tempo/session/client/Session.d.ts +8 -2
- package/dist/tempo/session/client/Session.d.ts.map +1 -1
- package/dist/tempo/session/client/Session.js +22 -8
- package/dist/tempo/session/client/Session.js.map +1 -1
- package/dist/tempo/session/client/SessionManager.d.ts +4 -40
- package/dist/tempo/session/client/SessionManager.d.ts.map +1 -1
- package/dist/tempo/session/client/SessionManager.js +124 -174
- package/dist/tempo/session/client/SessionManager.js.map +1 -1
- package/dist/tempo/session/client/index.d.ts +3 -4
- package/dist/tempo/session/client/index.d.ts.map +1 -1
- package/dist/tempo/session/client/index.js +1 -0
- package/dist/tempo/session/client/index.js.map +1 -1
- package/dist/tempo/session/precompile/Voucher.d.ts +3 -3
- package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -1
- package/dist/tempo/session/precompile/Voucher.js +24 -25
- package/dist/tempo/session/precompile/Voucher.js.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.d.ts +6 -0
- package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.js +13 -0
- package/dist/tempo/session/server/CredentialVerification.js.map +1 -1
- package/dist/tempo/session/server/Settlement.d.ts.map +1 -1
- package/dist/tempo/session/server/Settlement.js +4 -2
- package/dist/tempo/session/server/Settlement.js.map +1 -1
- package/dist/tempo/session/server/Sse.d.ts.map +1 -1
- package/dist/tempo/session/server/Sse.js.map +1 -1
- package/dist/tempo/session/server/Ws.d.ts.map +1 -1
- package/dist/tempo/session/server/Ws.js.map +1 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts +712 -1
- package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/subscription/Store.d.ts +2 -0
- package/dist/tempo/subscription/Store.d.ts.map +1 -1
- package/dist/tempo/subscription/Store.js +16 -1
- package/dist/tempo/subscription/Store.js.map +1 -1
- package/dist/x402/index.d.ts +1 -0
- package/dist/x402/index.d.ts.map +1 -1
- package/dist/x402/index.js +1 -0
- package/dist/x402/index.js.map +1 -1
- package/package.json +21 -10
- package/src/Challenge.test.ts +40 -0
- package/src/Challenge.ts +19 -6
- package/src/Mcp.ts +4 -0
- package/src/PaymentRequest.ts +10 -10
- package/src/cli/cli.test.ts +15 -15
- package/src/cli/config.test.ts +13 -7
- package/src/cli/internal.ts +1 -16
- package/src/client/Mppx.test-d.ts +21 -1
- package/src/client/Mppx.test.ts +1 -1
- package/src/client/Mppx.ts +2 -2
- package/src/client/Transport.test.ts +225 -178
- package/src/client/Transport.ts +77 -83
- package/src/client/index.ts +14 -0
- package/src/client/internal/Fetch.test.ts +207 -2
- package/src/client/internal/Fetch.ts +52 -6
- package/src/client/internal/protocols/Mcp.test.ts +220 -0
- package/src/client/internal/protocols/Mcp.ts +162 -0
- package/src/client/internal/protocols/Mpp.ts +21 -0
- package/src/client/internal/protocols/Protocol.ts +10 -0
- package/src/client/internal/protocols/Shared.ts +25 -0
- package/src/client/internal/protocols/X402.ts +42 -0
- package/src/discovery/OpenApi.test.ts +1 -1
- package/src/evm/PublicInterface.test-d.ts +1 -1
- package/src/evm/client/index.ts +1 -0
- package/src/evm/index.ts +2 -0
- package/src/evm/server/Charge.test.ts +1 -1
- package/src/evm/server/index.ts +1 -0
- package/src/{mcp-sdk → mcp}/client/McpClient.integration.test.ts +10 -4
- package/src/{mcp-sdk → mcp}/client/McpClient.test-d.ts +45 -18
- package/src/{mcp-sdk → mcp}/client/McpClient.test.ts +211 -5
- package/src/mcp/client/McpClient.ts +307 -0
- package/src/{mcp-sdk → mcp}/client/McpClient.unit.test.ts +9 -5
- package/src/middlewares/elysia.test.ts +1 -1
- package/src/middlewares/express.test.ts +1 -1
- package/src/middlewares/hono.test.ts +1 -1
- package/src/middlewares/internal/mppx.test.ts +1 -1
- package/src/middlewares/nextjs.test.ts +1 -1
- package/src/proxy/Proxy.test.ts +1 -1
- package/src/proxy/services/anthropic.test.ts +1 -1
- package/src/proxy/services/openai.test.ts +1 -1
- package/src/proxy/services/stripe.test.ts +1 -1
- package/src/server/Mppx.authorize.test.ts +1 -1
- package/src/server/Mppx.test-d.ts +1 -1
- package/src/server/Mppx.test.ts +20 -2
- package/src/server/Mppx.ts +14 -1
- package/src/server/Transport.test.ts +6 -6
- package/src/server/Transport.ts +1 -1
- package/src/stripe/Charge.integration.test.ts +1 -1
- package/src/stripe/client/Charge.test.ts +1 -1
- package/src/stripe/server/Charge.test.ts +1 -1
- package/src/stripe/server/internal/html/package.json +1 -1
- package/src/stripe/server/internal/html.gen.ts +1 -1
- package/src/tempo/Proof.conformance.test.ts +146 -0
- package/src/tempo/Proof.test-d.ts +15 -0
- package/src/tempo/Proof.ts +52 -1
- package/src/tempo/Subscription.integration.test.ts +1 -1
- package/src/tempo/client/Charge.test.ts +173 -0
- package/src/tempo/client/Charge.ts +65 -36
- package/src/tempo/client/Methods.ts +4 -2
- package/src/tempo/client/ResolveAccount.ts +46 -0
- package/src/tempo/internal/fee-payer.test.ts +89 -10
- package/src/tempo/internal/fee-payer.ts +128 -41
- package/src/tempo/internal/proof.test.ts +12 -4
- package/src/tempo/internal/proof.ts +55 -6
- package/src/tempo/legacy/client/SessionManager.ts +11 -3
- package/src/tempo/legacy/server/Session.test.ts +91 -26
- package/src/tempo/server/Charge.test.ts +388 -17
- package/src/tempo/server/Charge.ts +50 -24
- package/src/tempo/server/Methods.ts +4 -2
- package/src/tempo/server/Subscription.test.ts +465 -3
- package/src/tempo/server/Subscription.ts +174 -19
- package/src/tempo/server/internal/html/package.json +2 -2
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/tempo/session/client/ChannelOps.ts +5 -19
- package/src/tempo/session/client/ChannelStore.ts +111 -0
- package/src/tempo/session/client/CredentialState.test.ts +206 -62
- package/src/tempo/session/client/CredentialState.ts +58 -73
- package/src/tempo/session/client/Session.test.ts +41 -1
- package/src/tempo/session/client/Session.ts +36 -10
- package/src/tempo/session/client/SessionManager.test.ts +154 -65
- package/src/tempo/session/client/SessionManager.ts +141 -235
- package/src/tempo/session/client/index.ts +8 -5
- package/src/tempo/session/precompile/Voucher.test.ts +45 -7
- package/src/tempo/session/precompile/Voucher.ts +27 -25
- package/src/tempo/session/server/CredentialVerification.test.ts +36 -0
- package/src/tempo/session/server/CredentialVerification.ts +18 -0
- package/src/tempo/session/server/Session.test.ts +4 -4
- package/src/tempo/session/server/Settlement.test.ts +88 -1
- package/src/tempo/session/server/Settlement.ts +2 -1
- package/src/tempo/session/server/Sse.ts +0 -2
- package/src/tempo/session/server/Ws.ts +0 -4
- package/src/tempo/subscription/Store.ts +27 -9
- package/src/x402/Exact.e2e.test.ts +1 -1
- package/src/x402/PublicInterface.test-d.ts +1 -1
- package/src/x402/index.ts +1 -0
- package/dist/mcp-sdk/client/McpClient.d.ts +0 -85
- package/dist/mcp-sdk/client/McpClient.d.ts.map +0 -1
- package/dist/mcp-sdk/client/McpClient.js +0 -118
- package/dist/mcp-sdk/client/McpClient.js.map +0 -1
- package/dist/mcp-sdk/client/index.d.ts.map +0 -1
- package/dist/mcp-sdk/client/index.js.map +0 -1
- package/dist/mcp-sdk/server/Transport.d.ts.map +0 -1
- package/dist/mcp-sdk/server/Transport.js.map +0 -1
- package/dist/mcp-sdk/server/index.d.ts.map +0 -1
- package/dist/mcp-sdk/server/index.js.map +0 -1
- package/src/mcp-sdk/client/McpClient.ts +0 -228
- /package/dist/{mcp-sdk → mcp}/client/index.d.ts +0 -0
- /package/dist/{mcp-sdk → mcp}/client/index.js +0 -0
- /package/dist/{mcp-sdk → mcp}/server/Transport.d.ts +0 -0
- /package/dist/{mcp-sdk → mcp}/server/Transport.js +0 -0
- /package/dist/{mcp-sdk → mcp}/server/index.d.ts +0 -0
- /package/dist/{mcp-sdk → mcp}/server/index.js +0 -0
- /package/src/{mcp-sdk → mcp}/client/index.ts +0 -0
- /package/src/{mcp-sdk → mcp}/server/Transport.test.ts +0 -0
- /package/src/{mcp-sdk → mcp}/server/Transport.ts +0 -0
- /package/src/{mcp-sdk → mcp}/server/index.ts +0 -0
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Base64 } from 'ox'
|
|
2
2
|
import { KeyAuthorization } from 'ox/tempo'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
encodeFunctionData,
|
|
5
|
+
isAddressEqual,
|
|
6
|
+
parseEventLogs,
|
|
7
|
+
type Address,
|
|
8
|
+
type Client as ViemClient,
|
|
9
|
+
type TransactionReceipt,
|
|
10
|
+
} from 'viem'
|
|
4
11
|
import {
|
|
5
12
|
call as viem_call,
|
|
6
13
|
prepareTransactionRequest,
|
|
@@ -113,6 +120,8 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
113
120
|
},
|
|
114
121
|
|
|
115
122
|
async authorize({ input, request }) {
|
|
123
|
+
if (parameters.requireCredential) return undefined
|
|
124
|
+
|
|
116
125
|
const resolved = await parameters.resolve({ input, request })
|
|
117
126
|
if (!resolved) return undefined
|
|
118
127
|
|
|
@@ -182,8 +191,8 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
182
191
|
const input = requestFromCaptured(capturedRequest)
|
|
183
192
|
const resolved = await parameters.resolve({ input, request: parsedRequest })
|
|
184
193
|
const existing = resolved ? await store.getByKey(resolved.key) : null
|
|
185
|
-
const accessKey =
|
|
186
|
-
resolved
|
|
194
|
+
const accessKey = !credential
|
|
195
|
+
? resolved
|
|
187
196
|
? await resolveChallengeAccessKey({
|
|
188
197
|
existing,
|
|
189
198
|
input,
|
|
@@ -192,7 +201,10 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
192
201
|
resolved,
|
|
193
202
|
store,
|
|
194
203
|
})
|
|
195
|
-
:
|
|
204
|
+
: parameters.requireCredential && !parameters.activate
|
|
205
|
+
? await createUnboundChallengeAccessKey({ store })
|
|
206
|
+
: undefined
|
|
207
|
+
: (credentialRequest?.methodDetails?.accessKey ?? parsedRequest.methodDetails?.accessKey)
|
|
196
208
|
if (!accessKey) {
|
|
197
209
|
throw new VerificationFailedError({ reason: 'subscription accessKey is missing' })
|
|
198
210
|
}
|
|
@@ -218,16 +230,17 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
218
230
|
challengeExpires: credential.challenge.expires,
|
|
219
231
|
request: parsedRequest,
|
|
220
232
|
})
|
|
221
|
-
const resolved = await parameters.resolve({ input, request: parsedRequest })
|
|
222
|
-
|
|
223
|
-
if (!resolved) {
|
|
224
|
-
throw new VerificationFailedError({ reason: 'subscription could not be resolved' })
|
|
225
|
-
}
|
|
226
233
|
const challengeRequest = credential.challenge.request as SubscriptionRequest
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
234
|
+
let resolved: subscription.ResolvedSubscription | null = null
|
|
235
|
+
let accessKey =
|
|
236
|
+
challengeRequest.methodDetails?.accessKey ?? parsedRequest.methodDetails?.accessKey
|
|
237
|
+
if (!accessKey) {
|
|
238
|
+
resolved = await parameters.resolve({ input, request: parsedRequest })
|
|
239
|
+
if (!resolved) {
|
|
240
|
+
throw new VerificationFailedError({ reason: 'subscription could not be resolved' })
|
|
241
|
+
}
|
|
242
|
+
accessKey = await resolveAccessKey({ input, parameters, request: parsedRequest, resolved })
|
|
243
|
+
}
|
|
231
244
|
if (!accessKey) {
|
|
232
245
|
throw new VerificationFailedError({ reason: 'subscription accessKey is missing' })
|
|
233
246
|
}
|
|
@@ -247,10 +260,20 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
247
260
|
reason: 'credential source does not match signature',
|
|
248
261
|
})
|
|
249
262
|
}
|
|
263
|
+
resolved =
|
|
264
|
+
(await parameters.resolve({ input, request: parsedRequest, source: verified.source })) ??
|
|
265
|
+
resolved
|
|
266
|
+
|
|
267
|
+
if (!resolved) {
|
|
268
|
+
throw new VerificationFailedError({ reason: 'subscription could not be resolved' })
|
|
269
|
+
}
|
|
250
270
|
|
|
251
271
|
const activation = await store.activate({
|
|
252
272
|
challengeId: credential.challenge.id,
|
|
253
|
-
isReusable: (subscription) =>
|
|
273
|
+
isReusable: (subscription) =>
|
|
274
|
+
parameters.requireCredential
|
|
275
|
+
? isActiveSubscriptionForRequest(subscription, parsedRequest)
|
|
276
|
+
: isReusableSubscription(subscription, parsedRequest),
|
|
254
277
|
lookupKey: resolved.key,
|
|
255
278
|
async create() {
|
|
256
279
|
const activation = withSubscriptionAccessKey(
|
|
@@ -299,7 +322,50 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
299
322
|
throw new VerificationFailedError({ reason: 'subscription activation claim mismatch' })
|
|
300
323
|
}
|
|
301
324
|
if (activation.status === 'existing') {
|
|
302
|
-
|
|
325
|
+
const subscription = activation.subscription
|
|
326
|
+
assertSubscriptionPayer(subscription, verified.source, {
|
|
327
|
+
required: parameters.requireCredential,
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
const periodIndex = getPeriodIndex(subscription)
|
|
331
|
+
if (periodIndex > subscription.lastChargedPeriod) {
|
|
332
|
+
const renew = resolveRenewalHandler({
|
|
333
|
+
feePayer,
|
|
334
|
+
feePayerPolicy,
|
|
335
|
+
getClient,
|
|
336
|
+
parameters,
|
|
337
|
+
store,
|
|
338
|
+
subscription,
|
|
339
|
+
waitForConfirmation,
|
|
340
|
+
})
|
|
341
|
+
if (!renew) {
|
|
342
|
+
throw new VerificationFailedError({ reason: 'subscription renewal is required' })
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const renewal = await settleRenewal({
|
|
346
|
+
expectedLookupKey: resolved.key,
|
|
347
|
+
periodIndex,
|
|
348
|
+
renew,
|
|
349
|
+
request: parsedRequest,
|
|
350
|
+
store,
|
|
351
|
+
subscription,
|
|
352
|
+
})
|
|
353
|
+
if (!renewal) {
|
|
354
|
+
throw new VerificationFailedError({ reason: 'subscription renewal failed' })
|
|
355
|
+
}
|
|
356
|
+
if (renewal.status === 'charged' || renewal.status === 'inFlight') {
|
|
357
|
+
return renewal.receipt
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
await parameters.hooks?.renewed?.({
|
|
361
|
+
periodIndex,
|
|
362
|
+
receipt: renewal.result.receipt,
|
|
363
|
+
subscription: renewal.result.subscription,
|
|
364
|
+
})
|
|
365
|
+
return renewal.result.receipt
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return SubscriptionReceipt.fromRecord(subscription)
|
|
303
369
|
}
|
|
304
370
|
|
|
305
371
|
await parameters.hooks?.activated?.({
|
|
@@ -380,6 +446,18 @@ async function resolveChallengeAccessKey(parameters: {
|
|
|
380
446
|
)
|
|
381
447
|
}
|
|
382
448
|
|
|
449
|
+
async function createUnboundChallengeAccessKey(parameters: {
|
|
450
|
+
store: SubscriptionStore.SubscriptionStore
|
|
451
|
+
}) {
|
|
452
|
+
const accessKey = await parameters.store.getOrCreateAccessKey(
|
|
453
|
+
`challenge:${createSubscriptionId()}`,
|
|
454
|
+
)
|
|
455
|
+
return {
|
|
456
|
+
accessKeyAddress: accessKey.accessKeyAddress,
|
|
457
|
+
keyType: accessKey.keyType,
|
|
458
|
+
} satisfies SubscriptionAccessKey
|
|
459
|
+
}
|
|
460
|
+
|
|
383
461
|
async function activateSubscription(parameters: {
|
|
384
462
|
accessKey: SubscriptionAccessKey
|
|
385
463
|
auto: {
|
|
@@ -567,14 +645,20 @@ function isActive(subscription: SubscriptionRecord): boolean {
|
|
|
567
645
|
return new Date(subscription.subscriptionExpires).getTime() > Date.now()
|
|
568
646
|
}
|
|
569
647
|
|
|
648
|
+
function isActiveSubscriptionForRequest(
|
|
649
|
+
subscription: SubscriptionRecord,
|
|
650
|
+
request: SubscriptionRequest,
|
|
651
|
+
): boolean {
|
|
652
|
+
return isActive(subscription) && subscriptionMatchesRequest(subscription, request)
|
|
653
|
+
}
|
|
654
|
+
|
|
570
655
|
function isReusableSubscription(
|
|
571
656
|
subscription: SubscriptionRecord,
|
|
572
657
|
request: SubscriptionRequest,
|
|
573
658
|
): boolean {
|
|
574
659
|
return (
|
|
575
|
-
|
|
576
|
-
getPeriodIndex(subscription) <= subscription.lastChargedPeriod
|
|
577
|
-
subscriptionMatchesRequest(subscription, request)
|
|
660
|
+
isActiveSubscriptionForRequest(subscription, request) &&
|
|
661
|
+
getPeriodIndex(subscription) <= subscription.lastChargedPeriod
|
|
578
662
|
)
|
|
579
663
|
}
|
|
580
664
|
|
|
@@ -589,6 +673,25 @@ function subscriptionMatchesRequest(
|
|
|
589
673
|
)
|
|
590
674
|
}
|
|
591
675
|
|
|
676
|
+
function assertSubscriptionPayer(
|
|
677
|
+
subscription: SubscriptionRecord,
|
|
678
|
+
source: { address: Address; chainId: number },
|
|
679
|
+
options?: { required?: boolean | undefined },
|
|
680
|
+
) {
|
|
681
|
+
if (!subscription.payer) {
|
|
682
|
+
if (options?.required) {
|
|
683
|
+
throw new VerificationFailedError({ reason: 'subscription payer is missing' })
|
|
684
|
+
}
|
|
685
|
+
return
|
|
686
|
+
}
|
|
687
|
+
if (
|
|
688
|
+
subscription.payer.chainId !== source.chainId ||
|
|
689
|
+
!isAddressEqual(subscription.payer.address, source.address)
|
|
690
|
+
) {
|
|
691
|
+
throw new VerificationFailedError({ reason: 'subscription payer mismatch' })
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
592
695
|
function comparableSubscriptionBinding(value: SubscriptionRecord | SubscriptionRequest) {
|
|
593
696
|
const chainId =
|
|
594
697
|
'chainId' in value ? value.chainId : (value as SubscriptionRequest).methodDetails?.chainId
|
|
@@ -804,7 +907,9 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
804
907
|
store,
|
|
805
908
|
waitForConfirmation,
|
|
806
909
|
} = parameters
|
|
807
|
-
const stored =
|
|
910
|
+
const stored =
|
|
911
|
+
(await store.getAccessKey(lookupKey)) ??
|
|
912
|
+
(await store.getAccessKeyByAddress(accessKey.accessKeyAddress))
|
|
808
913
|
if (!stored) {
|
|
809
914
|
throw new VerificationFailedError({ reason: 'subscription access key is missing' })
|
|
810
915
|
}
|
|
@@ -884,6 +989,8 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
884
989
|
} as never)
|
|
885
990
|
|
|
886
991
|
if (!waitForConfirmation) {
|
|
992
|
+
// Optimistic mode has no receipt to inspect, so it cannot detect a T6
|
|
993
|
+
// (TIP-1028) held transfer. Use `waitForConfirmation: true` for T6-safe proof.
|
|
887
994
|
return sendRawTransaction(client, {
|
|
888
995
|
serializedTransaction: serializedTransaction as Transaction.TransactionSerializedTempo,
|
|
889
996
|
})
|
|
@@ -897,9 +1004,50 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
897
1004
|
reason: `subscription transaction reverted: ${receipt.transactionHash}`,
|
|
898
1005
|
})
|
|
899
1006
|
}
|
|
1007
|
+
assertSubscriptionTransfer(receipt, {
|
|
1008
|
+
amount: BigInt(request.amount),
|
|
1009
|
+
currency: request.currency as Address,
|
|
1010
|
+
memo,
|
|
1011
|
+
recipient: request.recipient as Address,
|
|
1012
|
+
})
|
|
900
1013
|
return receipt.transactionHash
|
|
901
1014
|
}
|
|
902
1015
|
|
|
1016
|
+
/**
|
|
1017
|
+
* Asserts a confirmed subscription payment credited the recipient.
|
|
1018
|
+
*
|
|
1019
|
+
* Transaction success alone is not proof: under Tempo T6 (TIP-1028) a recipient
|
|
1020
|
+
* receive policy can hold the funds in `ReceivePolicyGuard` while the tx still
|
|
1021
|
+
* succeeds. Settlement always emits one `transferWithMemo(recipient, amount,
|
|
1022
|
+
* memo)`, so this requires a matching `TransferWithMemo` log on the expected
|
|
1023
|
+
* token. A held transfer fails because its `to` is the guard, and the memo
|
|
1024
|
+
* binding excludes unrelated transfer effects in the same receipt.
|
|
1025
|
+
*/
|
|
1026
|
+
function assertSubscriptionTransfer(
|
|
1027
|
+
receipt: TransactionReceipt,
|
|
1028
|
+
parameters: { amount: bigint; currency: Address; memo: `0x${string}`; recipient: Address },
|
|
1029
|
+
): void {
|
|
1030
|
+
const { amount, currency, memo, recipient } = parameters
|
|
1031
|
+
const credited = parseEventLogs({
|
|
1032
|
+
abi: Abis.tip20,
|
|
1033
|
+
eventName: 'TransferWithMemo',
|
|
1034
|
+
logs: receipt.logs,
|
|
1035
|
+
}).some(
|
|
1036
|
+
(log) =>
|
|
1037
|
+
isAddressEqual(log.address, currency) &&
|
|
1038
|
+
isAddressEqual(log.args.to, recipient) &&
|
|
1039
|
+
log.args.amount === amount &&
|
|
1040
|
+
log.args.memo.toLowerCase() === memo.toLowerCase(),
|
|
1041
|
+
)
|
|
1042
|
+
if (!credited) {
|
|
1043
|
+
throw new VerificationFailedError({
|
|
1044
|
+
reason:
|
|
1045
|
+
`subscription transfer was not credited to the recipient ` +
|
|
1046
|
+
`(funds may have been held by a receive policy): ${receipt.transactionHash}`,
|
|
1047
|
+
})
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
903
1051
|
function createSubscriptionId() {
|
|
904
1052
|
const bytes = new Uint8Array(18)
|
|
905
1053
|
globalThis.crypto.getRandomValues(bytes)
|
|
@@ -1054,6 +1202,11 @@ export declare namespace subscription {
|
|
|
1054
1202
|
* Keeps concurrent renewal safe while allowing recovery from abandoned attempts.
|
|
1055
1203
|
*/
|
|
1056
1204
|
renewalTimeoutMs?: number | undefined
|
|
1205
|
+
/**
|
|
1206
|
+
* Requires a fresh subscription Credential even when a subscription is active.
|
|
1207
|
+
* This binds access reuse to the stored payer instead of trusting request metadata alone.
|
|
1208
|
+
*/
|
|
1209
|
+
requireCredential?: boolean | undefined
|
|
1057
1210
|
/**
|
|
1058
1211
|
* Override the fee-payer policy for sponsored subscription payments.
|
|
1059
1212
|
* Useful when the access key + key authorization tx requires more gas
|
|
@@ -1101,6 +1254,8 @@ export declare namespace subscription {
|
|
|
1101
1254
|
resolve: (parameters: {
|
|
1102
1255
|
input: Request
|
|
1103
1256
|
request: SubscriptionRequest
|
|
1257
|
+
/** Verified payer identity recovered from a signed subscription credential. */
|
|
1258
|
+
source?: { address: Address; chainId: number } | undefined
|
|
1104
1259
|
}) => MaybePromise<ResolvedSubscription | null>
|
|
1105
1260
|
renew?: (parameters: {
|
|
1106
1261
|
/** Stable idempotency/reconciliation reference persisted before the renewal hook runs. */
|