mppx 0.3.8 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/Challenge.d.ts.map +1 -1
- package/dist/Challenge.js +2 -0
- package/dist/Challenge.js.map +1 -1
- package/dist/Errors.d.ts +0 -2
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js +1 -3
- package/dist/Errors.js.map +1 -1
- package/dist/internal/constantTimeEqual.d.ts.map +1 -1
- package/dist/internal/constantTimeEqual.js +4 -6
- package/dist/internal/constantTimeEqual.js.map +1 -1
- package/dist/internal/env.d.ts +2 -2
- package/dist/internal/env.d.ts.map +1 -1
- package/dist/internal/env.js +1 -2
- package/dist/internal/env.js.map +1 -1
- package/dist/middlewares/internal/mppx.d.ts.map +1 -1
- package/dist/middlewares/internal/mppx.js +6 -2
- package/dist/middlewares/internal/mppx.js.map +1 -1
- package/dist/server/Mppx.d.ts +13 -3
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +46 -3
- package/dist/server/Mppx.js.map +1 -1
- package/dist/tempo/internal/simulate.d.ts +21 -0
- package/dist/tempo/internal/simulate.d.ts.map +1 -0
- package/dist/tempo/internal/simulate.js +31 -0
- package/dist/tempo/internal/simulate.js.map +1 -0
- package/dist/tempo/server/Charge.d.ts +12 -0
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +28 -6
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Session.d.ts +18 -1
- package/dist/tempo/server/Session.d.ts.map +1 -1
- package/dist/tempo/server/Session.js +66 -46
- package/dist/tempo/server/Session.js.map +1 -1
- package/dist/tempo/session/Chain.d.ts +5 -2
- package/dist/tempo/session/Chain.d.ts.map +1 -1
- package/dist/tempo/session/Chain.js +78 -10
- package/dist/tempo/session/Chain.js.map +1 -1
- package/package.json +1 -1
- package/src/Challenge.ts +2 -0
- package/src/Errors.test.ts +43 -18
- package/src/Errors.ts +1 -4
- package/src/client/Mppx.test.ts +1 -0
- package/src/internal/constantTimeEqual.ts +5 -4
- package/src/internal/env.test.ts +2 -2
- package/src/internal/env.ts +4 -5
- package/src/middlewares/express.test.ts +5 -0
- package/src/middlewares/hono.test.ts +5 -0
- package/src/middlewares/internal/mppx.ts +5 -2
- package/src/middlewares/nextjs.test.ts +5 -0
- package/src/proxy/Proxy.test.ts +3 -0
- package/src/proxy/services/openai.test.ts +3 -0
- package/src/server/Mppx.test.ts +93 -2
- package/src/server/Mppx.ts +81 -6
- package/src/tempo/internal/simulate.ts +49 -0
- package/src/tempo/server/Charge.test.ts +62 -0
- package/src/tempo/server/Charge.ts +44 -6
- package/src/tempo/server/Session.test.ts +51 -2
- package/src/tempo/server/Session.ts +97 -38
- package/src/tempo/session/Chain.test.ts +190 -0
- package/src/tempo/session/Chain.ts +109 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Address, encodeFunctionData, erc20Abi, type Hex } from 'viem'
|
|
2
|
+
import { waitForTransactionReceipt } from 'viem/actions'
|
|
2
3
|
import { Addresses, Transaction } from 'viem/tempo'
|
|
3
4
|
import { beforeAll, describe, expect, test } from 'vitest'
|
|
4
5
|
import {
|
|
@@ -346,6 +347,38 @@ describe('on-chain', () => {
|
|
|
346
347
|
expect(result.txHash).toBeUndefined()
|
|
347
348
|
expect(result.onChain.deposit).toBe(deposit)
|
|
348
349
|
})
|
|
350
|
+
|
|
351
|
+
test('waitForConfirmation: false returns derived on-chain state', async () => {
|
|
352
|
+
const salt = nextSalt()
|
|
353
|
+
const deposit = 10_000_000n
|
|
354
|
+
|
|
355
|
+
const { channelId, serializedTransaction } = await signOpenChannel({
|
|
356
|
+
escrow: escrowContract,
|
|
357
|
+
payer,
|
|
358
|
+
payee: recipient,
|
|
359
|
+
token: currency,
|
|
360
|
+
deposit,
|
|
361
|
+
salt,
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
const result = await broadcastOpenTransaction({
|
|
365
|
+
client,
|
|
366
|
+
serializedTransaction,
|
|
367
|
+
escrowContract,
|
|
368
|
+
channelId,
|
|
369
|
+
recipient,
|
|
370
|
+
currency,
|
|
371
|
+
waitForConfirmation: false,
|
|
372
|
+
})
|
|
373
|
+
|
|
374
|
+
expect(result.txHash).toBeDefined()
|
|
375
|
+
expect(result.onChain.payer.toLowerCase()).toBe(payer.address.toLowerCase())
|
|
376
|
+
expect(result.onChain.payee.toLowerCase()).toBe(recipient.toLowerCase())
|
|
377
|
+
expect(result.onChain.token.toLowerCase()).toBe(currency.toLowerCase())
|
|
378
|
+
expect(result.onChain.deposit).toBe(deposit)
|
|
379
|
+
expect(result.onChain.settled).toBe(0n)
|
|
380
|
+
expect(result.onChain.finalized).toBe(false)
|
|
381
|
+
})
|
|
349
382
|
})
|
|
350
383
|
|
|
351
384
|
describe('broadcastTopUpTransaction', () => {
|
|
@@ -380,6 +413,7 @@ describe('on-chain', () => {
|
|
|
380
413
|
serializedTransaction,
|
|
381
414
|
escrowContract,
|
|
382
415
|
channelId: wrongChannelId,
|
|
416
|
+
currency: asset,
|
|
383
417
|
declaredDeposit: topUpAmount,
|
|
384
418
|
previousDeposit: deposit,
|
|
385
419
|
}),
|
|
@@ -414,6 +448,7 @@ describe('on-chain', () => {
|
|
|
414
448
|
serializedTransaction,
|
|
415
449
|
escrowContract,
|
|
416
450
|
channelId,
|
|
451
|
+
currency: asset,
|
|
417
452
|
declaredDeposit: 9_999_999n,
|
|
418
453
|
previousDeposit: deposit,
|
|
419
454
|
}),
|
|
@@ -447,6 +482,7 @@ describe('on-chain', () => {
|
|
|
447
482
|
serializedTransaction,
|
|
448
483
|
escrowContract,
|
|
449
484
|
channelId,
|
|
485
|
+
currency: asset,
|
|
450
486
|
declaredDeposit: topUpAmount,
|
|
451
487
|
previousDeposit: deposit,
|
|
452
488
|
})
|
|
@@ -501,6 +537,7 @@ describe('on-chain', () => {
|
|
|
501
537
|
serializedTransaction: tampered,
|
|
502
538
|
escrowContract,
|
|
503
539
|
channelId,
|
|
540
|
+
currency: asset,
|
|
504
541
|
declaredDeposit: topUpAmount,
|
|
505
542
|
previousDeposit: deposit,
|
|
506
543
|
feePayer: accounts[0],
|
|
@@ -508,4 +545,157 @@ describe('on-chain', () => {
|
|
|
508
545
|
).rejects.toThrow('fee-sponsored topUp transaction contains an unauthorized call')
|
|
509
546
|
})
|
|
510
547
|
})
|
|
548
|
+
|
|
549
|
+
describe('settleOnChain', () => {
|
|
550
|
+
test('settles a channel', async () => {
|
|
551
|
+
const salt = nextSalt()
|
|
552
|
+
const deposit = 10_000_000n
|
|
553
|
+
const settleAmount = 5_000_000n
|
|
554
|
+
|
|
555
|
+
const { channelId } = await openChannel({
|
|
556
|
+
escrow: escrowContract,
|
|
557
|
+
payer,
|
|
558
|
+
payee: recipient,
|
|
559
|
+
token: currency,
|
|
560
|
+
deposit,
|
|
561
|
+
salt,
|
|
562
|
+
})
|
|
563
|
+
|
|
564
|
+
const signature = await signVoucher(
|
|
565
|
+
client,
|
|
566
|
+
payer,
|
|
567
|
+
{ channelId, cumulativeAmount: settleAmount },
|
|
568
|
+
escrowContract,
|
|
569
|
+
chain.id,
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
const txHash = await settleOnChain(client, escrowContract, {
|
|
573
|
+
channelId,
|
|
574
|
+
cumulativeAmount: settleAmount,
|
|
575
|
+
signature,
|
|
576
|
+
})
|
|
577
|
+
|
|
578
|
+
expect(txHash).toBeDefined()
|
|
579
|
+
await waitForTransactionReceipt(client, { hash: txHash })
|
|
580
|
+
const channel = await getOnChainChannel(client, escrowContract, channelId)
|
|
581
|
+
expect(channel.settled).toBe(settleAmount)
|
|
582
|
+
expect(channel.finalized).toBe(false)
|
|
583
|
+
})
|
|
584
|
+
|
|
585
|
+
test('settles a channel with fee payer', async () => {
|
|
586
|
+
const salt = nextSalt()
|
|
587
|
+
const deposit = 10_000_000n
|
|
588
|
+
const settleAmount = 5_000_000n
|
|
589
|
+
|
|
590
|
+
const { channelId } = await openChannel({
|
|
591
|
+
escrow: escrowContract,
|
|
592
|
+
payer,
|
|
593
|
+
payee: recipient,
|
|
594
|
+
token: currency,
|
|
595
|
+
deposit,
|
|
596
|
+
salt,
|
|
597
|
+
})
|
|
598
|
+
|
|
599
|
+
const signature = await signVoucher(
|
|
600
|
+
client,
|
|
601
|
+
payer,
|
|
602
|
+
{ channelId, cumulativeAmount: settleAmount },
|
|
603
|
+
escrowContract,
|
|
604
|
+
chain.id,
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
const txHash = await settleOnChain(
|
|
608
|
+
client,
|
|
609
|
+
escrowContract,
|
|
610
|
+
{
|
|
611
|
+
channelId,
|
|
612
|
+
cumulativeAmount: settleAmount,
|
|
613
|
+
signature,
|
|
614
|
+
},
|
|
615
|
+
accounts[0],
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
expect(txHash).toBeDefined()
|
|
619
|
+
await waitForTransactionReceipt(client, { hash: txHash })
|
|
620
|
+
const channel = await getOnChainChannel(client, escrowContract, channelId)
|
|
621
|
+
expect(channel.settled).toBe(settleAmount)
|
|
622
|
+
expect(channel.finalized).toBe(false)
|
|
623
|
+
})
|
|
624
|
+
})
|
|
625
|
+
|
|
626
|
+
describe('closeOnChain', () => {
|
|
627
|
+
test('closes a channel', async () => {
|
|
628
|
+
const salt = nextSalt()
|
|
629
|
+
const deposit = 10_000_000n
|
|
630
|
+
const closeAmount = 5_000_000n
|
|
631
|
+
|
|
632
|
+
const { channelId } = await openChannel({
|
|
633
|
+
escrow: escrowContract,
|
|
634
|
+
payer,
|
|
635
|
+
payee: recipient,
|
|
636
|
+
token: currency,
|
|
637
|
+
deposit,
|
|
638
|
+
salt,
|
|
639
|
+
})
|
|
640
|
+
|
|
641
|
+
const signature = await signVoucher(
|
|
642
|
+
client,
|
|
643
|
+
payer,
|
|
644
|
+
{ channelId, cumulativeAmount: closeAmount },
|
|
645
|
+
escrowContract,
|
|
646
|
+
chain.id,
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
const txHash = await closeOnChain(client, escrowContract, {
|
|
650
|
+
channelId,
|
|
651
|
+
cumulativeAmount: closeAmount,
|
|
652
|
+
signature,
|
|
653
|
+
})
|
|
654
|
+
|
|
655
|
+
expect(txHash).toBeDefined()
|
|
656
|
+
await waitForTransactionReceipt(client, { hash: txHash })
|
|
657
|
+
const channel = await getOnChainChannel(client, escrowContract, channelId)
|
|
658
|
+
expect(channel.finalized).toBe(true)
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
test('closes a channel with fee payer', async () => {
|
|
662
|
+
const salt = nextSalt()
|
|
663
|
+
const deposit = 10_000_000n
|
|
664
|
+
const closeAmount = 5_000_000n
|
|
665
|
+
|
|
666
|
+
const { channelId } = await openChannel({
|
|
667
|
+
escrow: escrowContract,
|
|
668
|
+
payer,
|
|
669
|
+
payee: recipient,
|
|
670
|
+
token: currency,
|
|
671
|
+
deposit,
|
|
672
|
+
salt,
|
|
673
|
+
})
|
|
674
|
+
|
|
675
|
+
const signature = await signVoucher(
|
|
676
|
+
client,
|
|
677
|
+
payer,
|
|
678
|
+
{ channelId, cumulativeAmount: closeAmount },
|
|
679
|
+
escrowContract,
|
|
680
|
+
chain.id,
|
|
681
|
+
)
|
|
682
|
+
|
|
683
|
+
const txHash = await closeOnChain(
|
|
684
|
+
client,
|
|
685
|
+
escrowContract,
|
|
686
|
+
{
|
|
687
|
+
channelId,
|
|
688
|
+
cumulativeAmount: closeAmount,
|
|
689
|
+
signature,
|
|
690
|
+
},
|
|
691
|
+
undefined,
|
|
692
|
+
accounts[0],
|
|
693
|
+
)
|
|
694
|
+
|
|
695
|
+
expect(txHash).toBeDefined()
|
|
696
|
+
await waitForTransactionReceipt(client, { hash: txHash })
|
|
697
|
+
const channel = await getOnChainChannel(client, escrowContract, channelId)
|
|
698
|
+
expect(channel.finalized).toBe(true)
|
|
699
|
+
})
|
|
700
|
+
})
|
|
511
701
|
}) // end describe('on-chain')
|
|
@@ -3,15 +3,26 @@ import {
|
|
|
3
3
|
type Address,
|
|
4
4
|
type Client,
|
|
5
5
|
decodeFunctionData,
|
|
6
|
+
encodeFunctionData,
|
|
6
7
|
getAbiItem,
|
|
8
|
+
getAddress,
|
|
7
9
|
type Hex,
|
|
8
10
|
isAddressEqual,
|
|
9
11
|
type ReadContractReturnType,
|
|
10
12
|
toFunctionSelector,
|
|
11
13
|
} from 'viem'
|
|
12
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
prepareTransactionRequest,
|
|
16
|
+
readContract,
|
|
17
|
+
sendRawTransaction,
|
|
18
|
+
sendRawTransactionSync,
|
|
19
|
+
signTransaction,
|
|
20
|
+
writeContract,
|
|
21
|
+
} from 'viem/actions'
|
|
13
22
|
import { Transaction } from 'viem/tempo'
|
|
14
23
|
import { BadRequestError, ChannelClosedError, VerificationFailedError } from '../../Errors.js'
|
|
24
|
+
import * as defaults from '../internal/defaults.js'
|
|
25
|
+
import { simulateTransaction } from '../internal/simulate.js'
|
|
15
26
|
import { escrowAbi } from './escrow.abi.js'
|
|
16
27
|
import type { SignedVoucher } from './Types.js'
|
|
17
28
|
|
|
@@ -75,15 +86,21 @@ export async function settleOnChain(
|
|
|
75
86
|
client: Client,
|
|
76
87
|
escrowContract: Address,
|
|
77
88
|
voucher: SignedVoucher,
|
|
89
|
+
feePayer?: Account | undefined,
|
|
78
90
|
): Promise<Hex> {
|
|
79
91
|
assertUint128(voucher.cumulativeAmount)
|
|
92
|
+
const args = [voucher.channelId, voucher.cumulativeAmount, voucher.signature] as const
|
|
93
|
+
if (feePayer) {
|
|
94
|
+
const data = encodeFunctionData({ abi: escrowAbi, functionName: 'settle', args })
|
|
95
|
+
return sendFeePayerTx(client, feePayer, escrowContract, data, 'settle')
|
|
96
|
+
}
|
|
80
97
|
return writeContract(client, {
|
|
81
98
|
account: client.account!,
|
|
82
99
|
chain: client.chain,
|
|
83
100
|
address: escrowContract,
|
|
84
101
|
abi: escrowAbi,
|
|
85
102
|
functionName: 'settle',
|
|
86
|
-
args
|
|
103
|
+
args,
|
|
87
104
|
})
|
|
88
105
|
}
|
|
89
106
|
|
|
@@ -95,6 +112,7 @@ export async function closeOnChain(
|
|
|
95
112
|
escrowContract: Address,
|
|
96
113
|
voucher: SignedVoucher,
|
|
97
114
|
account?: Account,
|
|
115
|
+
feePayer?: Account | undefined,
|
|
98
116
|
): Promise<Hex> {
|
|
99
117
|
assertUint128(voucher.cumulativeAmount)
|
|
100
118
|
const resolved = account ?? client.account
|
|
@@ -102,14 +120,67 @@ export async function closeOnChain(
|
|
|
102
120
|
throw new Error(
|
|
103
121
|
'Cannot close channel: no account available. Provide an `account` in the session config or a `getClient` that returns an account-bearing client.',
|
|
104
122
|
)
|
|
123
|
+
const args = [voucher.channelId, voucher.cumulativeAmount, voucher.signature] as const
|
|
124
|
+
if (feePayer) {
|
|
125
|
+
const data = encodeFunctionData({ abi: escrowAbi, functionName: 'close', args })
|
|
126
|
+
return sendFeePayerTx(client, feePayer, escrowContract, data, 'close')
|
|
127
|
+
}
|
|
105
128
|
return writeContract(client, {
|
|
106
129
|
account: resolved,
|
|
107
130
|
chain: client.chain,
|
|
108
131
|
address: escrowContract,
|
|
109
132
|
abi: escrowAbi,
|
|
110
133
|
functionName: 'close',
|
|
111
|
-
args
|
|
134
|
+
args,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Build, sign, and broadcast a fee-sponsored type-0x76 transaction.
|
|
140
|
+
*
|
|
141
|
+
* Follows the same signTransaction + sendRawTransactionSync pattern used
|
|
142
|
+
* by broadcastOpenTransaction / broadcastTopUpTransaction, but originates
|
|
143
|
+
* the transaction server-side (estimating gas and fees first).
|
|
144
|
+
*/
|
|
145
|
+
async function sendFeePayerTx(
|
|
146
|
+
client: Client,
|
|
147
|
+
feePayer: Account,
|
|
148
|
+
to: Address,
|
|
149
|
+
data: Hex,
|
|
150
|
+
label: string,
|
|
151
|
+
): Promise<Hex> {
|
|
152
|
+
// Resolve the fee token for this chain so the tx pays gas in the correct
|
|
153
|
+
// token. `feePayer: true` tells the prepare hook to use expiring nonces but
|
|
154
|
+
// does NOT set feeToken automatically, so we must provide it explicitly.
|
|
155
|
+
const chainId = client.chain?.id
|
|
156
|
+
const feeToken = chainId
|
|
157
|
+
? defaults.currency[chainId as keyof typeof defaults.currency]
|
|
158
|
+
: undefined
|
|
159
|
+
|
|
160
|
+
const prepared = await prepareTransactionRequest(client, {
|
|
161
|
+
account: feePayer,
|
|
162
|
+
calls: [{ to, data }],
|
|
163
|
+
feePayer: true,
|
|
164
|
+
...(feeToken ? { feeToken } : {}),
|
|
165
|
+
} as never)
|
|
166
|
+
|
|
167
|
+
const serialized = (await signTransaction(client, {
|
|
168
|
+
...prepared,
|
|
169
|
+
account: feePayer,
|
|
170
|
+
feePayer,
|
|
171
|
+
} as never)) as Hex
|
|
172
|
+
|
|
173
|
+
const receipt = await sendRawTransactionSync(client, {
|
|
174
|
+
serializedTransaction: serialized as Transaction.TransactionSerializedTempo,
|
|
112
175
|
})
|
|
176
|
+
|
|
177
|
+
if (receipt.status !== 'success') {
|
|
178
|
+
throw new VerificationFailedError({
|
|
179
|
+
reason: `${label} transaction reverted: ${receipt.transactionHash}`,
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return receipt.transactionHash
|
|
113
184
|
}
|
|
114
185
|
|
|
115
186
|
const escrowOpenSelector = /*#__PURE__*/ toFunctionSelector(
|
|
@@ -137,6 +208,8 @@ export async function broadcastOpenTransaction(parameters: {
|
|
|
137
208
|
recipient: Address
|
|
138
209
|
currency: Address
|
|
139
210
|
feePayer?: Account | undefined
|
|
211
|
+
/** When false, simulates instead of waiting for confirmation and returns derived on-chain state. @default true */
|
|
212
|
+
waitForConfirmation?: boolean | undefined
|
|
140
213
|
}): Promise<BroadcastResult> {
|
|
141
214
|
const {
|
|
142
215
|
client,
|
|
@@ -146,6 +219,7 @@ export async function broadcastOpenTransaction(parameters: {
|
|
|
146
219
|
recipient,
|
|
147
220
|
currency,
|
|
148
221
|
feePayer,
|
|
222
|
+
waitForConfirmation = true,
|
|
149
223
|
} = parameters
|
|
150
224
|
|
|
151
225
|
const transaction = Transaction.deserialize(
|
|
@@ -184,7 +258,13 @@ export async function broadcastOpenTransaction(parameters: {
|
|
|
184
258
|
}
|
|
185
259
|
|
|
186
260
|
const { args: openArgs } = decodeFunctionData({ abi: escrowAbi, data: openCall.data! })
|
|
187
|
-
const [payee, token] = openArgs as readonly [
|
|
261
|
+
const [payee, token, deposit, , authorizedSigner] = openArgs as readonly [
|
|
262
|
+
Address,
|
|
263
|
+
Address,
|
|
264
|
+
bigint,
|
|
265
|
+
Hex,
|
|
266
|
+
Address,
|
|
267
|
+
]
|
|
188
268
|
|
|
189
269
|
if (!isAddressEqual(payee, recipient)) {
|
|
190
270
|
throw new VerificationFailedError({
|
|
@@ -208,6 +288,28 @@ export async function broadcastOpenTransaction(parameters: {
|
|
|
208
288
|
return serializedTransaction
|
|
209
289
|
})()
|
|
210
290
|
|
|
291
|
+
if (!waitForConfirmation) {
|
|
292
|
+
const from = getAddress(transaction.from as Address)
|
|
293
|
+
await simulateTransaction(client, { ...transaction, from, calls })
|
|
294
|
+
const txHash = await sendRawTransaction(client, {
|
|
295
|
+
serializedTransaction: serializedTransaction_final as Transaction.TransactionSerializedTempo,
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
txHash,
|
|
300
|
+
onChain: {
|
|
301
|
+
payer: from,
|
|
302
|
+
payee,
|
|
303
|
+
token,
|
|
304
|
+
authorizedSigner,
|
|
305
|
+
deposit,
|
|
306
|
+
settled: 0n,
|
|
307
|
+
closeRequestedAt: 0n,
|
|
308
|
+
finalized: false,
|
|
309
|
+
} as OnChainChannel,
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
211
313
|
let txHash: Hex | undefined
|
|
212
314
|
try {
|
|
213
315
|
const receipt = await sendRawTransactionSync(client, {
|
|
@@ -239,6 +341,7 @@ export async function broadcastTopUpTransaction(parameters: {
|
|
|
239
341
|
serializedTransaction: Hex
|
|
240
342
|
escrowContract: Address
|
|
241
343
|
channelId: Hex
|
|
344
|
+
currency: Address
|
|
242
345
|
declaredDeposit: bigint
|
|
243
346
|
previousDeposit: bigint
|
|
244
347
|
feePayer?: Account | undefined
|
|
@@ -248,6 +351,7 @@ export async function broadcastTopUpTransaction(parameters: {
|
|
|
248
351
|
serializedTransaction,
|
|
249
352
|
escrowContract,
|
|
250
353
|
channelId,
|
|
354
|
+
currency,
|
|
251
355
|
declaredDeposit,
|
|
252
356
|
previousDeposit,
|
|
253
357
|
feePayer,
|
|
@@ -279,7 +383,7 @@ export async function broadcastTopUpTransaction(parameters: {
|
|
|
279
383
|
const selector = call.data.slice(0, 10)
|
|
280
384
|
const isEscrowTopUp =
|
|
281
385
|
isAddressEqual(call.to, escrowContract) && selector === escrowTopUpSelector
|
|
282
|
-
const isTokenApprove = selector === erc20ApproveSelector
|
|
386
|
+
const isTokenApprove = isAddressEqual(call.to, currency) && selector === erc20ApproveSelector
|
|
283
387
|
if (!isEscrowTopUp && !isTokenApprove) {
|
|
284
388
|
throw new BadRequestError({
|
|
285
389
|
reason: 'fee-sponsored topUp transaction contains an unauthorized call',
|