mppx 0.6.26 → 0.6.28
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 +15 -0
- package/dist/Store.d.ts +32 -9
- package/dist/Store.d.ts.map +1 -1
- package/dist/Store.js +42 -10
- package/dist/Store.js.map +1 -1
- package/dist/cli/cli.js +1 -1
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/utils.js +2 -2
- package/dist/cli/utils.js.map +1 -1
- package/dist/proxy/internal/Headers.d.ts +13 -1
- package/dist/proxy/internal/Headers.d.ts.map +1 -1
- package/dist/proxy/internal/Headers.js +14 -1
- package/dist/proxy/internal/Headers.js.map +1 -1
- package/dist/stripe/server/Charge.d.ts +31 -1
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +88 -11
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/tempo/client/ChannelOps.d.ts.map +1 -1
- package/dist/tempo/client/ChannelOps.js +7 -2
- package/dist/tempo/client/ChannelOps.js.map +1 -1
- package/dist/tempo/client/Charge.d.ts.map +1 -1
- package/dist/tempo/client/Charge.js +6 -4
- package/dist/tempo/client/Charge.js.map +1 -1
- package/dist/tempo/client/Session.js +1 -1
- package/dist/tempo/client/Session.js.map +1 -1
- package/dist/tempo/client/Subscription.js +1 -1
- package/dist/tempo/client/Subscription.js.map +1 -1
- package/dist/tempo/server/Charge.d.ts +6 -0
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +8 -3
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Session.d.ts +6 -0
- package/dist/tempo/server/Session.d.ts.map +1 -1
- package/dist/tempo/server/Session.js +2 -2
- package/dist/tempo/server/Session.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +6 -0
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/Subscription.js +2 -2
- 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/Chain.d.ts.map +1 -1
- package/dist/tempo/session/Chain.js +6 -1
- package/dist/tempo/session/Chain.js.map +1 -1
- package/package.json +3 -3
- package/src/Store.test-d.ts +58 -0
- package/src/Store.test.ts +77 -0
- package/src/Store.ts +155 -74
- package/src/cli/cli.ts +1 -1
- package/src/cli/utils.test.ts +1 -1
- package/src/cli/utils.ts +2 -2
- package/src/proxy/internal/Headers.test.ts +18 -0
- package/src/proxy/internal/Headers.ts +14 -1
- package/src/stripe/server/Charge.test.ts +215 -1
- package/src/stripe/server/Charge.ts +150 -20
- package/src/stripe/server/internal/html.gen.ts +1 -1
- package/src/tempo/client/ChannelOps.ts +6 -2
- package/src/tempo/client/Charge.ts +5 -4
- package/src/tempo/client/Session.ts +1 -1
- package/src/tempo/client/Subscription.ts +1 -1
- package/src/tempo/server/Charge.test.ts +22 -1
- package/src/tempo/server/Charge.ts +17 -3
- package/src/tempo/server/Session.ts +10 -2
- package/src/tempo/server/Subscription.test.ts +1 -1
- package/src/tempo/server/Subscription.ts +8 -2
- package/src/tempo/server/internal/html/main.ts +1 -1
- package/src/tempo/server/internal/html/package.json +1 -1
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/tempo/session/Chain.test.ts +16 -8
- package/src/tempo/session/Chain.ts +6 -1
- package/src/tempo/session/ChannelStore.test.ts +21 -0
- package/src/tempo/subscription/Store.test.ts +55 -0
- package/src/viem/Account.test.ts +1 -1
- package/src/viem/Client.test.ts +1 -1
|
@@ -498,10 +498,12 @@ describe.runIf(isLocalnet)('on-chain', () => {
|
|
|
498
498
|
{ to: currency, data: approveData },
|
|
499
499
|
{ to: escrowContract, data: openData },
|
|
500
500
|
],
|
|
501
|
-
feePayer: true,
|
|
502
501
|
feeToken: currency,
|
|
502
|
+
nonceKey: 'expiring',
|
|
503
|
+
validBefore: Math.floor(Date.now() / 1_000) + 25,
|
|
503
504
|
} as never)
|
|
504
|
-
prepared.gas = prepared.gas
|
|
505
|
+
prepared.gas = (prepared.gas ?? 0n) + 5_000n
|
|
506
|
+
;(prepared as Record<string, unknown>).feePayer = true
|
|
505
507
|
const serializedTransaction = await signTransaction(client, prepared as never)
|
|
506
508
|
|
|
507
509
|
await broadcastOpenTransaction({
|
|
@@ -561,10 +563,12 @@ describe.runIf(isLocalnet)('on-chain', () => {
|
|
|
561
563
|
{ to: escrowContract, data: openData },
|
|
562
564
|
{ to: escrowContract, data: smuggledOpenData },
|
|
563
565
|
],
|
|
564
|
-
feePayer: true,
|
|
565
566
|
feeToken: currency,
|
|
567
|
+
nonceKey: 'expiring',
|
|
568
|
+
validBefore: Math.floor(Date.now() / 1_000) + 25,
|
|
566
569
|
} as never)
|
|
567
|
-
prepared.gas = prepared.gas
|
|
570
|
+
prepared.gas = (prepared.gas ?? 0n) + 5_000n
|
|
571
|
+
;(prepared as Record<string, unknown>).feePayer = true
|
|
568
572
|
|
|
569
573
|
const serializedTransaction = await signTransaction(client, prepared as never)
|
|
570
574
|
|
|
@@ -1006,10 +1010,12 @@ describe.runIf(isLocalnet)('on-chain', () => {
|
|
|
1006
1010
|
{ to: currency, data: approveData },
|
|
1007
1011
|
{ to: escrowContract, data: topUpData },
|
|
1008
1012
|
],
|
|
1009
|
-
feePayer: true,
|
|
1010
1013
|
feeToken: currency,
|
|
1014
|
+
nonceKey: 'expiring',
|
|
1015
|
+
validBefore: Math.floor(Date.now() / 1_000) + 25,
|
|
1011
1016
|
} as never)
|
|
1012
|
-
prepared.gas = prepared.gas
|
|
1017
|
+
prepared.gas = (prepared.gas ?? 0n) + 5_000n
|
|
1018
|
+
;(prepared as Record<string, unknown>).feePayer = true
|
|
1013
1019
|
const serializedTransaction = await signTransaction(client, prepared as never)
|
|
1014
1020
|
|
|
1015
1021
|
await broadcastTopUpTransaction({
|
|
@@ -1069,10 +1075,12 @@ describe.runIf(isLocalnet)('on-chain', () => {
|
|
|
1069
1075
|
{ to: escrowContract, data: topUpData },
|
|
1070
1076
|
{ to: escrowContract, data: smuggledTopUpData },
|
|
1071
1077
|
],
|
|
1072
|
-
feePayer: true,
|
|
1073
1078
|
feeToken: currency,
|
|
1079
|
+
nonceKey: 'expiring',
|
|
1080
|
+
validBefore: Math.floor(Date.now() / 1_000) + 25,
|
|
1074
1081
|
} as never)
|
|
1075
|
-
prepared.gas = prepared.gas
|
|
1082
|
+
prepared.gas = (prepared.gas ?? 0n) + 5_000n
|
|
1083
|
+
;(prepared as Record<string, unknown>).feePayer = true
|
|
1076
1084
|
|
|
1077
1085
|
const serializedTransaction = await signTransaction(client, prepared as never)
|
|
1078
1086
|
|
|
@@ -258,9 +258,14 @@ async function sendFeePayerTx(
|
|
|
258
258
|
const prepared = await prepareTransactionRequest(client, {
|
|
259
259
|
account,
|
|
260
260
|
calls: [{ to, data }],
|
|
261
|
-
feePayer: true,
|
|
262
261
|
...(feeToken ? { feeToken } : {}),
|
|
262
|
+
nonceKey: 'expiring',
|
|
263
|
+
validBefore: Math.floor(Date.now() / 1_000) + 25,
|
|
263
264
|
} as never)
|
|
265
|
+
// Estimate before enabling fee-payer mode so Tempo includes sender
|
|
266
|
+
// signature verification costs in the gas budget.
|
|
267
|
+
prepared.gas = (prepared.gas ?? 0n) + 5_000n
|
|
268
|
+
;(prepared as Record<string, unknown>).feePayer = true
|
|
264
269
|
|
|
265
270
|
const serialized = (await signTransaction(client, {
|
|
266
271
|
...prepared,
|
|
@@ -117,6 +117,27 @@ describe('channelStore', () => {
|
|
|
117
117
|
expect(typeof loaded!.createdAt).toBe('string')
|
|
118
118
|
})
|
|
119
119
|
|
|
120
|
+
test('prefixes backing store keys when configured', async () => {
|
|
121
|
+
const rawStore = Store.memory()
|
|
122
|
+
const cs = ChannelStore.fromStore(Store.from(rawStore, { keyPrefix: 'tenant:' }))
|
|
123
|
+
await cs.updateChannel(channelId, () => makeChannel())
|
|
124
|
+
|
|
125
|
+
expect(await rawStore.get(`tenant:${channelId}`)).not.toBeNull()
|
|
126
|
+
expect(await rawStore.get(channelId)).toBeNull()
|
|
127
|
+
expect((await cs.getChannel(channelId))?.channelId).toBe(channelId)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('isolates prefixed store wrappers', async () => {
|
|
131
|
+
const rawStore = Store.memory()
|
|
132
|
+
const first = ChannelStore.fromStore(Store.from(rawStore, { keyPrefix: 'tenant-a:' }))
|
|
133
|
+
const second = ChannelStore.fromStore(Store.from(rawStore, { keyPrefix: 'tenant-b:' }))
|
|
134
|
+
await first.updateChannel(channelId, () => makeChannel())
|
|
135
|
+
|
|
136
|
+
expect(await second.getChannel(channelId)).toBeNull()
|
|
137
|
+
expect(await rawStore.get(`tenant-a:${channelId}`)).not.toBeNull()
|
|
138
|
+
expect(await rawStore.get(`tenant-b:${channelId}`)).toBeNull()
|
|
139
|
+
})
|
|
140
|
+
|
|
120
141
|
test('treats case-variant channelIds as the same record', async () => {
|
|
121
142
|
const cs = ChannelStore.fromStore(Store.memory())
|
|
122
143
|
await cs.updateChannel(mixedCaseAliasChannelId, () =>
|
|
@@ -26,6 +26,61 @@ function createRecord(overrides: Partial<SubscriptionRecord> = {}): Subscription
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
describe('tempo subscription store', () => {
|
|
29
|
+
test('prefixes all backing store keys when configured', async () => {
|
|
30
|
+
const rawStore = Store.memory()
|
|
31
|
+
const store = fromStore(Store.from(rawStore, { keyPrefix: 'tenant:' }))
|
|
32
|
+
let finishActivation!: () => void
|
|
33
|
+
const pendingActivation = new Promise<void>((resolve) => {
|
|
34
|
+
finishActivation = resolve
|
|
35
|
+
})
|
|
36
|
+
let activationStarted!: () => void
|
|
37
|
+
const activationStartedPromise = new Promise<void>((resolve) => {
|
|
38
|
+
activationStarted = resolve
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const activation = store.activate({
|
|
42
|
+
challengeId: 'challenge-1',
|
|
43
|
+
create: async () => {
|
|
44
|
+
activationStarted()
|
|
45
|
+
await pendingActivation
|
|
46
|
+
return { subscription: createRecord() }
|
|
47
|
+
},
|
|
48
|
+
lookupKey: 'user-1:plan:pro',
|
|
49
|
+
})
|
|
50
|
+
await activationStartedPromise
|
|
51
|
+
|
|
52
|
+
expect(await rawStore.get('tenant:tempo:subscription:credential:challenge-1')).not.toBeNull()
|
|
53
|
+
expect(
|
|
54
|
+
await rawStore.get('tenant:tempo:subscription:activation:user-1:plan:pro'),
|
|
55
|
+
).not.toBeNull()
|
|
56
|
+
expect(await rawStore.get('tempo:subscription:credential:challenge-1')).toBeNull()
|
|
57
|
+
|
|
58
|
+
finishActivation()
|
|
59
|
+
expect((await activation).status).toBe('activated')
|
|
60
|
+
await store.getOrCreateAccessKey('user-1:plan:pro')
|
|
61
|
+
|
|
62
|
+
expect(await rawStore.get(`tenant:tempo:subscription:record:${subscriptionId}`)).not.toBeNull()
|
|
63
|
+
expect(await rawStore.get('tenant:tempo:subscription:key:user-1:plan:pro')).toBe(subscriptionId)
|
|
64
|
+
expect(
|
|
65
|
+
await rawStore.get('tenant:tempo:subscription:access-key:user-1:plan:pro'),
|
|
66
|
+
).not.toBeNull()
|
|
67
|
+
expect(await rawStore.get(`tempo:subscription:record:${subscriptionId}`)).toBeNull()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('combines store prefix with custom key family prefixes', async () => {
|
|
71
|
+
const rawStore = Store.memory()
|
|
72
|
+
const store = fromStore(Store.from(rawStore, { keyPrefix: 'tenant:' }), {
|
|
73
|
+
keyPrefix: 'lookup:',
|
|
74
|
+
recordPrefix: 'record:',
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
await store.put(createRecord())
|
|
78
|
+
|
|
79
|
+
expect(await rawStore.get(`tenant:record:${subscriptionId}`)).not.toBeNull()
|
|
80
|
+
expect(await rawStore.get('tenant:lookup:user-1:plan:pro')).toBe(subscriptionId)
|
|
81
|
+
expect(await rawStore.get(`record:${subscriptionId}`)).toBeNull()
|
|
82
|
+
})
|
|
83
|
+
|
|
29
84
|
test('rejects a replayed activation challenge', async () => {
|
|
30
85
|
const store = fromStore(Store.memory())
|
|
31
86
|
|
package/src/viem/Account.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createClient, http } from 'viem'
|
|
2
2
|
import { privateKeyToAccount } from 'viem/accounts'
|
|
3
|
-
import { mainnet } from 'viem/chains'
|
|
3
|
+
import { tempo as mainnet } from 'viem/tempo/chains'
|
|
4
4
|
import { describe, expect, test } from 'vp/test'
|
|
5
5
|
|
|
6
6
|
import * as Account from './Account.js'
|
package/src/viem/Client.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createClient, custom, defineChain, type Hex } from 'viem'
|
|
2
2
|
import { privateKeyToAccount } from 'viem/accounts'
|
|
3
3
|
import { signTransaction } from 'viem/actions'
|
|
4
|
-
import { tempoLocalnet } from 'viem/chains'
|
|
5
4
|
import { Account as TempoAccount, Transaction } from 'viem/tempo'
|
|
5
|
+
import { tempoLocalnet } from 'viem/tempo/chains'
|
|
6
6
|
import { describe, expect, test } from 'vp/test'
|
|
7
7
|
|
|
8
8
|
import * as Client from './Client.js'
|