mppx 0.6.22 → 0.6.24
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 +13 -0
- package/dist/Credential.d.ts.map +1 -1
- package/dist/Credential.js +1 -1
- package/dist/Credential.js.map +1 -1
- package/dist/client/Mppx.d.ts +6 -2
- package/dist/client/Mppx.d.ts.map +1 -1
- package/dist/client/Mppx.js +8 -2
- package/dist/client/Mppx.js.map +1 -1
- package/dist/client/internal/Fetch.d.ts +4 -0
- package/dist/client/internal/Fetch.d.ts.map +1 -1
- package/dist/client/internal/Fetch.js +9 -3
- package/dist/client/internal/Fetch.js.map +1 -1
- package/dist/internal/AcceptPayment.d.ts +16 -0
- package/dist/internal/AcceptPayment.d.ts.map +1 -1
- package/dist/internal/AcceptPayment.js +31 -8
- package/dist/internal/AcceptPayment.js.map +1 -1
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +6 -5
- package/dist/server/Mppx.js.map +1 -1
- package/dist/tempo/client/SessionManager.d.ts +12 -2
- package/dist/tempo/client/SessionManager.d.ts.map +1 -1
- package/dist/tempo/client/SessionManager.js +8 -1
- package/dist/tempo/client/SessionManager.js.map +1 -1
- package/dist/tempo/server/Subscription.d.ts +7 -0
- package/dist/tempo/server/Subscription.d.ts.map +1 -1
- package/dist/tempo/server/Subscription.js +47 -6
- 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/package.json +1 -1
- package/src/Credential.test.ts +23 -0
- package/src/Credential.ts +2 -1
- package/src/client/Mppx.test-d.ts +13 -0
- package/src/client/Mppx.test.ts +52 -0
- package/src/client/Mppx.ts +22 -4
- package/src/client/internal/Fetch.test-d.ts +11 -0
- package/src/client/internal/Fetch.test.ts +117 -1
- package/src/client/internal/Fetch.ts +24 -2
- package/src/internal/AcceptPayment.test.ts +26 -0
- package/src/internal/AcceptPayment.ts +55 -10
- package/src/server/Mppx.test.ts +24 -0
- package/src/server/Mppx.ts +6 -5
- package/src/tempo/client/SessionManager.test.ts +84 -3
- package/src/tempo/client/SessionManager.ts +35 -5
- package/src/tempo/server/Subscription.ts +62 -3
- package/src/tempo/server/internal/html.gen.ts +1 -1
|
@@ -30,11 +30,11 @@ function makeChallenge(overrides: Record<string, unknown> = {}): Challenge.Chall
|
|
|
30
30
|
})
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function make402Response(
|
|
34
|
-
const
|
|
33
|
+
function make402Response(...challenges: Challenge.Challenge[]): Response {
|
|
34
|
+
const entries = challenges.length ? challenges : [makeChallenge()]
|
|
35
35
|
return new Response(null, {
|
|
36
36
|
status: 402,
|
|
37
|
-
headers: { 'WWW-Authenticate': Challenge.serialize(
|
|
37
|
+
headers: { 'WWW-Authenticate': entries.map(Challenge.serialize).join(', ') },
|
|
38
38
|
})
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -111,6 +111,87 @@ describe('Session', () => {
|
|
|
111
111
|
'no `deposit` or `maxDeposit` configured',
|
|
112
112
|
)
|
|
113
113
|
})
|
|
114
|
+
|
|
115
|
+
test('passes supported challenges through the ordering hook', async () => {
|
|
116
|
+
const first = makeChallenge({ currency: 'pathusd' })
|
|
117
|
+
const second = makeChallenge({ currency: 'usdc' })
|
|
118
|
+
const mockFetch = vi.fn().mockResolvedValue(make402Response(first, second))
|
|
119
|
+
const orderChallenges = vi.fn(
|
|
120
|
+
(candidates: Parameters<NonNullable<sessionManager.Parameters['orderChallenges']>>[0]) =>
|
|
121
|
+
candidates.slice(1, 1),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
const s = sessionManager({
|
|
125
|
+
account: '0x0000000000000000000000000000000000000001',
|
|
126
|
+
fetch: mockFetch as typeof globalThis.fetch,
|
|
127
|
+
orderChallenges,
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
await expect(s.fetch('https://api.example.com/data')).rejects.toThrow(
|
|
131
|
+
'No method found for challenges: tempo.session, tempo.session',
|
|
132
|
+
)
|
|
133
|
+
expect(orderChallenges).toHaveBeenCalledOnce()
|
|
134
|
+
expect(
|
|
135
|
+
orderChallenges.mock.calls[0]?.[0].map(({ challenge, index }) => ({
|
|
136
|
+
currency: challenge.request.currency,
|
|
137
|
+
index,
|
|
138
|
+
})),
|
|
139
|
+
).toEqual([
|
|
140
|
+
{ currency: 'pathusd', index: 0 },
|
|
141
|
+
{ currency: 'usdc', index: 1 },
|
|
142
|
+
])
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('request-local ordering overrides the session manager ordering hook', async () => {
|
|
146
|
+
const mockFetch = vi.fn().mockResolvedValue(make402Response())
|
|
147
|
+
const configuredOrderChallenges = vi.fn(
|
|
148
|
+
(candidates: Parameters<NonNullable<sessionManager.Parameters['orderChallenges']>>[0]) =>
|
|
149
|
+
candidates,
|
|
150
|
+
)
|
|
151
|
+
const requestOrderChallenges = vi.fn(
|
|
152
|
+
(
|
|
153
|
+
_candidates: Parameters<NonNullable<sessionManager.Parameters['orderChallenges']>>[0],
|
|
154
|
+
) => [],
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
const s = sessionManager({
|
|
158
|
+
account: '0x0000000000000000000000000000000000000001',
|
|
159
|
+
fetch: mockFetch as typeof globalThis.fetch,
|
|
160
|
+
orderChallenges: configuredOrderChallenges,
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
await expect(
|
|
164
|
+
s.fetch('https://api.example.com/data', {
|
|
165
|
+
orderChallenges: requestOrderChallenges,
|
|
166
|
+
}),
|
|
167
|
+
).rejects.toThrow('No method found for challenges: tempo.session')
|
|
168
|
+
expect(configuredOrderChallenges).not.toHaveBeenCalled()
|
|
169
|
+
expect(requestOrderChallenges).toHaveBeenCalledOnce()
|
|
170
|
+
})
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
describe('.ws()', () => {
|
|
174
|
+
test('applies challenge ordering to the HTTP probe', async () => {
|
|
175
|
+
const mockFetch = vi.fn().mockResolvedValue(make402Response())
|
|
176
|
+
const orderChallenges = vi.fn(
|
|
177
|
+
(
|
|
178
|
+
_candidates: Parameters<NonNullable<sessionManager.Parameters['orderChallenges']>>[0],
|
|
179
|
+
) => [],
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
const s = sessionManager({
|
|
183
|
+
account: '0x0000000000000000000000000000000000000001',
|
|
184
|
+
fetch: mockFetch as typeof globalThis.fetch,
|
|
185
|
+
maxDeposit: '10',
|
|
186
|
+
orderChallenges,
|
|
187
|
+
webSocket: vi.fn() as never,
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
await expect(s.ws('wss://api.example.com/session')).rejects.toThrow(
|
|
191
|
+
'No payment challenge received from HTTP endpoint for this WebSocket URL.',
|
|
192
|
+
)
|
|
193
|
+
expect(orderChallenges).toHaveBeenCalledOnce()
|
|
194
|
+
})
|
|
114
195
|
})
|
|
115
196
|
|
|
116
197
|
describe('.open()', () => {
|
|
@@ -4,6 +4,7 @@ import { parseUnits, type Address } from 'viem'
|
|
|
4
4
|
import * as Challenge from '../../Challenge.js'
|
|
5
5
|
import * as Fetch from '../../client/internal/Fetch.js'
|
|
6
6
|
import * as PaymentCredential from '../../Credential.js'
|
|
7
|
+
import * as AcceptPayment from '../../internal/AcceptPayment.js'
|
|
7
8
|
import type * as Account from '../../viem/Account.js'
|
|
8
9
|
import type * as Client from '../../viem/Client.js'
|
|
9
10
|
import { deserializeSessionReceipt } from '../session/Receipt.js'
|
|
@@ -28,6 +29,12 @@ type CloseReadyWaiter = {
|
|
|
28
29
|
resolve(receipt: SessionReceipt): void
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
type SessionMethod = ReturnType<typeof sessionPlugin>
|
|
33
|
+
type SessionOrderChallenges = AcceptPayment.OrderChallenges<readonly [SessionMethod]>
|
|
34
|
+
type SessionRequestInit = RequestInit & {
|
|
35
|
+
orderChallenges?: SessionOrderChallenges | undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
const WebSocketReadyState = {
|
|
32
39
|
CONNECTING: 0,
|
|
33
40
|
OPEN: 1,
|
|
@@ -45,10 +52,10 @@ export type SessionManager = {
|
|
|
45
52
|
readonly opened: boolean
|
|
46
53
|
|
|
47
54
|
open(options?: { deposit?: bigint }): Promise<void>
|
|
48
|
-
fetch(input: RequestInfo | URL, init?:
|
|
55
|
+
fetch(input: RequestInfo | URL, init?: SessionRequestInit): Promise<PaymentResponse>
|
|
49
56
|
sse(
|
|
50
57
|
input: RequestInfo | URL,
|
|
51
|
-
init?:
|
|
58
|
+
init?: SessionRequestInit & {
|
|
52
59
|
onReceipt?: ((receipt: SessionReceipt) => void) | undefined
|
|
53
60
|
signal?: AbortSignal | undefined
|
|
54
61
|
},
|
|
@@ -57,6 +64,7 @@ export type SessionManager = {
|
|
|
57
64
|
input: string | URL,
|
|
58
65
|
init?: {
|
|
59
66
|
onReceipt?: ((receipt: SessionReceipt) => void) | undefined
|
|
67
|
+
orderChallenges?: SessionOrderChallenges | undefined
|
|
60
68
|
protocols?: string | string[] | undefined
|
|
61
69
|
signal?: AbortSignal | undefined
|
|
62
70
|
},
|
|
@@ -134,6 +142,7 @@ export function sessionManager(parameters: sessionManager.Parameters): SessionMa
|
|
|
134
142
|
lastChallenge = challenge
|
|
135
143
|
return undefined
|
|
136
144
|
},
|
|
145
|
+
orderChallenges: parameters.orderChallenges,
|
|
137
146
|
})
|
|
138
147
|
|
|
139
148
|
function updateSpentFromReceipt(receipt: SessionReceipt | null | undefined) {
|
|
@@ -252,7 +261,10 @@ export function sessionManager(parameters: sessionManager.Parameters): SessionMa
|
|
|
252
261
|
})
|
|
253
262
|
}
|
|
254
263
|
|
|
255
|
-
async function doFetch(
|
|
264
|
+
async function doFetch(
|
|
265
|
+
input: RequestInfo | URL,
|
|
266
|
+
init?: SessionRequestInit,
|
|
267
|
+
): Promise<PaymentResponse> {
|
|
256
268
|
lastUrl = input
|
|
257
269
|
const response = await wrappedFetch(input, init)
|
|
258
270
|
return toPaymentResponse(response)
|
|
@@ -536,9 +548,17 @@ export function sessionManager(parameters: sessionManager.Parameters): SessionMa
|
|
|
536
548
|
)
|
|
537
549
|
}
|
|
538
550
|
|
|
539
|
-
const
|
|
540
|
-
(
|
|
551
|
+
const candidates = AcceptPayment.selectChallengeCandidates(
|
|
552
|
+
Challenge.fromResponseList(probe),
|
|
553
|
+
[method] as const,
|
|
554
|
+
AcceptPayment.resolve([method] as const).entries,
|
|
541
555
|
)
|
|
556
|
+
const challenge = (
|
|
557
|
+
await resolveSessionChallengeOrder(
|
|
558
|
+
candidates,
|
|
559
|
+
init?.orderChallenges ?? parameters.orderChallenges,
|
|
560
|
+
)
|
|
561
|
+
)[0]?.challenge
|
|
542
562
|
if (!challenge) {
|
|
543
563
|
throw new Error(
|
|
544
564
|
'No payment challenge received from HTTP endpoint for this WebSocket URL. The server may not require payment or did not advertise a challenge.',
|
|
@@ -844,7 +864,17 @@ export declare namespace sessionManager {
|
|
|
844
864
|
fetch?: typeof globalThis.fetch | undefined
|
|
845
865
|
/** Maximum deposit in human-readable units (e.g. `'10'` for 10 tokens). Converted to raw units via `decimals`. */
|
|
846
866
|
maxDeposit?: string | undefined
|
|
867
|
+
/** Filters and sorts supported session challenges before credential creation. */
|
|
868
|
+
orderChallenges?: SessionOrderChallenges | undefined
|
|
847
869
|
/** Optional websocket constructor for runtimes without a global WebSocket. */
|
|
848
870
|
webSocket?: WebSocketConstructor | undefined
|
|
849
871
|
}
|
|
850
872
|
}
|
|
873
|
+
|
|
874
|
+
async function resolveSessionChallengeOrder(
|
|
875
|
+
candidates: readonly AcceptPayment.ChallengeCandidate<SessionMethod>[],
|
|
876
|
+
override: SessionOrderChallenges | undefined,
|
|
877
|
+
): Promise<readonly AcceptPayment.ChallengeCandidate<SessionMethod>[]> {
|
|
878
|
+
const orderChallenges = override
|
|
879
|
+
return orderChallenges ? orderChallenges(candidates) : candidates
|
|
880
|
+
}
|
|
@@ -3,6 +3,7 @@ import { KeyAuthorization } from 'ox/tempo'
|
|
|
3
3
|
import { encodeFunctionData, isAddressEqual, type Address, type Client as ViemClient } from 'viem'
|
|
4
4
|
import {
|
|
5
5
|
call as viem_call,
|
|
6
|
+
prepareTransactionRequest,
|
|
6
7
|
sendRawTransaction,
|
|
7
8
|
sendRawTransactionSync,
|
|
8
9
|
signTransaction,
|
|
@@ -19,6 +20,7 @@ import * as ClientResolver from '../../viem/Client.js'
|
|
|
19
20
|
import * as Attribution from '../Attribution.js'
|
|
20
21
|
import * as Account from '../internal/account.js'
|
|
21
22
|
import * as defaults from '../internal/defaults.js'
|
|
23
|
+
import * as FeePayer from '../internal/fee-payer.js'
|
|
22
24
|
import * as Proof from '../internal/proof.js'
|
|
23
25
|
import type * as types from '../internal/types.js'
|
|
24
26
|
import * as Methods from '../Methods.js'
|
|
@@ -72,7 +74,7 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
72
74
|
activationTimeoutMs: parameters.activationTimeoutMs,
|
|
73
75
|
renewalTimeoutMs: parameters.renewalTimeoutMs,
|
|
74
76
|
})
|
|
75
|
-
const { recipient } = Account.resolve(parameters)
|
|
77
|
+
const { feePayer, recipient } = Account.resolve(parameters)
|
|
76
78
|
const getClient = ClientResolver.getResolver({
|
|
77
79
|
chain: tempo_chain,
|
|
78
80
|
getClient: parameters.getClient,
|
|
@@ -104,6 +106,8 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
104
106
|
const periodIndex = getPeriodIndex(subscription)
|
|
105
107
|
if (periodIndex > subscription.lastChargedPeriod) {
|
|
106
108
|
const renew = resolveRenewalHandler({
|
|
109
|
+
feePayer,
|
|
110
|
+
feePayerPolicy: parameters.feePayerPolicy,
|
|
107
111
|
getClient,
|
|
108
112
|
parameters,
|
|
109
113
|
store,
|
|
@@ -235,6 +239,8 @@ export function subscription<const parameters extends subscription.Parameters>(
|
|
|
235
239
|
accessKey,
|
|
236
240
|
auto: {
|
|
237
241
|
challengeId: credential.challenge.id,
|
|
242
|
+
feePayer,
|
|
243
|
+
feePayerPolicy: parameters.feePayerPolicy,
|
|
238
244
|
getClient,
|
|
239
245
|
keyAuthorization: (credential.payload as SubscriptionCredentialPayload).signature,
|
|
240
246
|
realm: credential.challenge.realm,
|
|
@@ -346,6 +352,8 @@ async function activateSubscription(parameters: {
|
|
|
346
352
|
accessKey: SubscriptionAccessKey
|
|
347
353
|
auto: {
|
|
348
354
|
challengeId: string
|
|
355
|
+
feePayer?: ReturnType<typeof Account.resolve>['feePayer'] | undefined
|
|
356
|
+
feePayerPolicy?: Partial<FeePayer.Policy> | undefined
|
|
349
357
|
getClient: (parameters: { chainId?: number | undefined }) => MaybePromise<ViemClient>
|
|
350
358
|
keyAuthorization: `0x${string}`
|
|
351
359
|
realm: string
|
|
@@ -391,6 +399,8 @@ async function activateSubscription(parameters: {
|
|
|
391
399
|
// billing authority needed for request-path and background renewals.
|
|
392
400
|
const reference = await submitSubscriptionPayment({
|
|
393
401
|
accessKey,
|
|
402
|
+
feePayer: auto.feePayer,
|
|
403
|
+
feePayerPolicy: auto.feePayerPolicy,
|
|
394
404
|
getClient: auto.getClient,
|
|
395
405
|
keyAuthorization: auto.keyAuthorization,
|
|
396
406
|
lookupKey: resolved.key,
|
|
@@ -689,6 +699,8 @@ function subscriptionBinding(request: SubscriptionRequest) {
|
|
|
689
699
|
}
|
|
690
700
|
|
|
691
701
|
function resolveRenewalHandler(parameters: {
|
|
702
|
+
feePayer?: ReturnType<typeof Account.resolve>['feePayer'] | undefined
|
|
703
|
+
feePayerPolicy?: Partial<FeePayer.Policy> | undefined
|
|
692
704
|
getClient: (parameters: { chainId?: number | undefined }) => MaybePromise<ViemClient>
|
|
693
705
|
parameters: {
|
|
694
706
|
renew?:
|
|
@@ -710,6 +722,8 @@ function resolveRenewalHandler(parameters: {
|
|
|
710
722
|
}) => Promise<subscription.RenewalResult>)
|
|
711
723
|
| undefined {
|
|
712
724
|
const {
|
|
725
|
+
feePayer,
|
|
726
|
+
feePayerPolicy,
|
|
713
727
|
getClient,
|
|
714
728
|
parameters: subscriptionParameters,
|
|
715
729
|
store,
|
|
@@ -721,6 +735,8 @@ function resolveRenewalHandler(parameters: {
|
|
|
721
735
|
return async ({ inFlightReference, periodIndex, subscription }) => {
|
|
722
736
|
const reference = await submitSubscriptionPayment({
|
|
723
737
|
accessKey: subscription.accessKey!,
|
|
738
|
+
feePayer,
|
|
739
|
+
feePayerPolicy,
|
|
724
740
|
getClient,
|
|
725
741
|
lookupKey: subscription.lookupKey,
|
|
726
742
|
request: subscription,
|
|
@@ -744,6 +760,8 @@ function resolveRenewalHandler(parameters: {
|
|
|
744
760
|
|
|
745
761
|
async function submitSubscriptionPayment(parameters: {
|
|
746
762
|
accessKey: SubscriptionAccessKey
|
|
763
|
+
feePayer?: ReturnType<typeof Account.resolve>['feePayer'] | undefined
|
|
764
|
+
feePayerPolicy?: Partial<FeePayer.Policy> | undefined
|
|
747
765
|
getClient: (parameters: { chainId?: number | undefined }) => MaybePromise<ViemClient>
|
|
748
766
|
keyAuthorization?: `0x${string}` | undefined
|
|
749
767
|
lookupKey: string
|
|
@@ -757,6 +775,8 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
757
775
|
}) {
|
|
758
776
|
const {
|
|
759
777
|
accessKey,
|
|
778
|
+
feePayer,
|
|
779
|
+
feePayerPolicy,
|
|
760
780
|
getClient,
|
|
761
781
|
keyAuthorization,
|
|
762
782
|
lookupKey,
|
|
@@ -786,7 +806,7 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
786
806
|
challengeId: settlementReference,
|
|
787
807
|
serverId: lookupKey,
|
|
788
808
|
})
|
|
789
|
-
const
|
|
809
|
+
const baseTransaction = {
|
|
790
810
|
account,
|
|
791
811
|
calls: [
|
|
792
812
|
{
|
|
@@ -802,7 +822,39 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
802
822
|
...(keyAuthorization
|
|
803
823
|
? { keyAuthorization: KeyAuthorization.deserialize(keyAuthorization) }
|
|
804
824
|
: {}),
|
|
805
|
-
}
|
|
825
|
+
}
|
|
826
|
+
const serializedTransaction = await (async () => {
|
|
827
|
+
if (!feePayer) return await signTransaction(client, baseTransaction as never)
|
|
828
|
+
// For sponsored payments, prepare the tx via `prepareTransactionRequest`
|
|
829
|
+
// (without `feePayer: true`) so viem returns the chain's full
|
|
830
|
+
// proof-inclusive gas estimate. With `feePayer: true` viem sets a
|
|
831
|
+
// dummy sig + null feePayerSignature, dropping signature and key
|
|
832
|
+
// authorization verification costs — see chainConfig.js FIXME. We add
|
|
833
|
+
// a small buffer for fee-payer overhead, then flip `feePayer = true`
|
|
834
|
+
// and re-sign with the fee-payer-sponsored envelope.
|
|
835
|
+
const prepared = await prepareTransactionRequest(client, {
|
|
836
|
+
...baseTransaction,
|
|
837
|
+
nonceKey: 'expiring',
|
|
838
|
+
} as never)
|
|
839
|
+
prepared.gas = (prepared.gas ?? 0n) + 5_000n
|
|
840
|
+
;(prepared as Record<string, unknown>).feePayer = true
|
|
841
|
+
const userSerialized = await signTransaction(client, prepared as never)
|
|
842
|
+
const userTransaction = Transaction.deserialize(
|
|
843
|
+
userSerialized as Transaction.TransactionSerializedTempo,
|
|
844
|
+
)
|
|
845
|
+
const sponsored = FeePayer.prepareSponsoredTransaction({
|
|
846
|
+
account: feePayer,
|
|
847
|
+
chainId: chainId ?? client.chain!.id,
|
|
848
|
+
details: {
|
|
849
|
+
amount: String(request.amount),
|
|
850
|
+
currency: String(request.currency),
|
|
851
|
+
recipient: String(request.recipient),
|
|
852
|
+
},
|
|
853
|
+
...(feePayerPolicy ? { policy: feePayerPolicy } : {}),
|
|
854
|
+
transaction: userTransaction as never,
|
|
855
|
+
})
|
|
856
|
+
return await signTransaction(client, sponsored as never)
|
|
857
|
+
})()
|
|
806
858
|
const transaction = Transaction.deserialize(
|
|
807
859
|
serializedTransaction as Transaction.TransactionSerializedTempo,
|
|
808
860
|
)
|
|
@@ -810,6 +862,7 @@ async function submitSubscriptionPayment(parameters: {
|
|
|
810
862
|
...transaction,
|
|
811
863
|
account: transaction.from,
|
|
812
864
|
calls: transaction.calls,
|
|
865
|
+
feePayerSignature: undefined,
|
|
813
866
|
} as never)
|
|
814
867
|
|
|
815
868
|
if (!waitForConfirmation) {
|
|
@@ -950,6 +1003,12 @@ export declare namespace subscription {
|
|
|
950
1003
|
* Keeps concurrent renewal safe while allowing recovery from abandoned attempts.
|
|
951
1004
|
*/
|
|
952
1005
|
renewalTimeoutMs?: number | undefined
|
|
1006
|
+
/**
|
|
1007
|
+
* Override the fee-payer policy for sponsored subscription payments.
|
|
1008
|
+
* Useful when the access key + key authorization tx requires more gas
|
|
1009
|
+
* than the default policy allows.
|
|
1010
|
+
*/
|
|
1011
|
+
feePayerPolicy?: Partial<FeePayer.Policy> | undefined
|
|
953
1012
|
activate?:
|
|
954
1013
|
| ((parameters: {
|
|
955
1014
|
/** Custom activation must verify this access key matches the resolved subscription. */
|