viem 2.49.2 → 2.50.3
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 +62 -0
- package/_cjs/actions/ens/getEnsAddress.js +21 -6
- package/_cjs/actions/ens/getEnsAddress.js.map +1 -1
- package/_cjs/actions/public/call.js +76 -41
- package/_cjs/actions/public/call.js.map +1 -1
- package/_cjs/actions/public/getBalance.js +11 -4
- package/_cjs/actions/public/getBalance.js.map +1 -1
- package/_cjs/actions/public/getCode.js +12 -5
- package/_cjs/actions/public/getCode.js.map +1 -1
- package/_cjs/actions/public/getProof.js +9 -5
- package/_cjs/actions/public/getProof.js.map +1 -1
- package/_cjs/actions/public/getStorageAt.js +9 -4
- package/_cjs/actions/public/getStorageAt.js.map +1 -1
- package/_cjs/actions/public/getTransactionCount.js +10 -7
- package/_cjs/actions/public/getTransactionCount.js.map +1 -1
- package/_cjs/actions/public/multicall.js +3 -1
- package/_cjs/actions/public/multicall.js.map +1 -1
- package/_cjs/actions/public/readContract.js.map +1 -1
- package/_cjs/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_cjs/actions/wallet/sendTransaction.js +14 -0
- package/_cjs/actions/wallet/sendTransaction.js.map +1 -1
- package/_cjs/actions/wallet/sendTransactionSync.js +15 -0
- package/_cjs/actions/wallet/sendTransactionSync.js.map +1 -1
- package/_cjs/chains/definitions/arc.js +19 -0
- package/_cjs/chains/definitions/arc.js.map +1 -0
- package/_cjs/chains/definitions/mizuhikiTestnetAwaji.js +29 -0
- package/_cjs/chains/definitions/mizuhikiTestnetAwaji.js.map +1 -0
- package/_cjs/chains/definitions/morphHolesky.js +1 -1
- package/_cjs/chains/definitions/morphHolesky.js.map +1 -1
- package/_cjs/chains/definitions/sentrix.js +29 -0
- package/_cjs/chains/definitions/sentrix.js.map +1 -0
- package/_cjs/chains/definitions/sentrixTestnet.js +30 -0
- package/_cjs/chains/definitions/sentrixTestnet.js.map +1 -0
- package/_cjs/chains/definitions/sova.js +1 -1
- package/_cjs/chains/definitions/sova.js.map +1 -1
- package/_cjs/chains/index.js +23 -15
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/constants/solidity.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/index.js +5 -3
- package/_cjs/index.js.map +1 -1
- package/_cjs/tempo/Chain.js +19 -0
- package/_cjs/tempo/Chain.js.map +1 -0
- package/_cjs/tempo/Decorator.js +1 -0
- package/_cjs/tempo/Decorator.js.map +1 -1
- package/_cjs/tempo/Formatters.js +1 -1
- package/_cjs/tempo/Formatters.js.map +1 -1
- package/_cjs/tempo/Transaction.js +5 -2
- package/_cjs/tempo/Transaction.js.map +1 -1
- package/_cjs/tempo/actions/fee.js +61 -0
- package/_cjs/tempo/actions/fee.js.map +1 -1
- package/_cjs/tempo/chainConfig.js +16 -6
- package/_cjs/tempo/chainConfig.js.map +1 -1
- package/_cjs/tempo/chains/index.js +11 -0
- package/_cjs/tempo/chains/index.js.map +1 -0
- package/_cjs/tempo/errors.js +58 -0
- package/_cjs/tempo/errors.js.map +1 -0
- package/_cjs/tempo/index.js +17 -1
- package/_cjs/tempo/index.js.map +1 -1
- package/_cjs/utils/abi/encodeEventTopics.js +4 -2
- package/_cjs/utils/abi/encodeEventTopics.js.map +1 -1
- package/_cjs/utils/block/formatBlockParameter.js +16 -0
- package/_cjs/utils/block/formatBlockParameter.js.map +1 -0
- package/_cjs/utils/ccipTunnel.js +65 -0
- package/_cjs/utils/ccipTunnel.js.map +1 -0
- package/_cjs/utils/index.js +6 -4
- package/_cjs/utils/index.js.map +1 -1
- package/_cjs/utils/nonceManager.js +7 -3
- package/_cjs/utils/nonceManager.js.map +1 -1
- package/_cjs/utils/observe.js +7 -1
- package/_cjs/utils/observe.js.map +1 -1
- package/_cjs/utils/rpc/socket.js +19 -2
- package/_cjs/utils/rpc/socket.js.map +1 -1
- package/_esm/actions/ens/getEnsAddress.js +21 -6
- package/_esm/actions/ens/getEnsAddress.js.map +1 -1
- package/_esm/actions/public/call.js +76 -41
- package/_esm/actions/public/call.js.map +1 -1
- package/_esm/actions/public/getBalance.js +11 -4
- package/_esm/actions/public/getBalance.js.map +1 -1
- package/_esm/actions/public/getCode.js +12 -5
- package/_esm/actions/public/getCode.js.map +1 -1
- package/_esm/actions/public/getProof.js +9 -5
- package/_esm/actions/public/getProof.js.map +1 -1
- package/_esm/actions/public/getStorageAt.js +9 -4
- package/_esm/actions/public/getStorageAt.js.map +1 -1
- package/_esm/actions/public/getTransactionCount.js +10 -7
- package/_esm/actions/public/getTransactionCount.js.map +1 -1
- package/_esm/actions/public/multicall.js +3 -1
- package/_esm/actions/public/multicall.js.map +1 -1
- package/_esm/actions/public/readContract.js.map +1 -1
- package/_esm/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_esm/actions/wallet/sendTransaction.js +14 -0
- package/_esm/actions/wallet/sendTransaction.js.map +1 -1
- package/_esm/actions/wallet/sendTransactionSync.js +15 -0
- package/_esm/actions/wallet/sendTransactionSync.js.map +1 -1
- package/_esm/chains/definitions/arc.js +16 -0
- package/_esm/chains/definitions/arc.js.map +1 -0
- package/_esm/chains/definitions/mizuhikiTestnetAwaji.js +26 -0
- package/_esm/chains/definitions/mizuhikiTestnetAwaji.js.map +1 -0
- package/_esm/chains/definitions/morphHolesky.js +1 -1
- package/_esm/chains/definitions/morphHolesky.js.map +1 -1
- package/_esm/chains/definitions/sentrix.js +26 -0
- package/_esm/chains/definitions/sentrix.js.map +1 -0
- package/_esm/chains/definitions/sentrixTestnet.js +27 -0
- package/_esm/chains/definitions/sentrixTestnet.js.map +1 -0
- package/_esm/chains/definitions/sova.js +1 -1
- package/_esm/chains/definitions/sova.js.map +1 -1
- package/_esm/chains/index.js +4 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/constants/solidity.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/index.js +1 -0
- package/_esm/index.js.map +1 -1
- package/_esm/tempo/Chain.js +6 -0
- package/_esm/tempo/Chain.js.map +1 -0
- package/_esm/tempo/Decorator.js +1 -0
- package/_esm/tempo/Decorator.js.map +1 -1
- package/_esm/tempo/Formatters.js +10 -4
- package/_esm/tempo/Formatters.js.map +1 -1
- package/_esm/tempo/Transaction.js +16 -6
- package/_esm/tempo/Transaction.js.map +1 -1
- package/_esm/tempo/actions/fee.js +83 -0
- package/_esm/tempo/actions/fee.js.map +1 -1
- package/_esm/tempo/actions/wallet.js +2 -2
- package/_esm/tempo/chainConfig.js +18 -8
- package/_esm/tempo/chainConfig.js.map +1 -1
- package/_esm/tempo/chains/index.js +3 -0
- package/_esm/tempo/chains/index.js.map +1 -0
- package/_esm/tempo/errors.js +51 -0
- package/_esm/tempo/errors.js.map +1 -0
- package/_esm/tempo/index.js +2 -0
- package/_esm/tempo/index.js.map +1 -1
- package/_esm/utils/abi/encodeEventTopics.js +6 -2
- package/_esm/utils/abi/encodeEventTopics.js.map +1 -1
- package/_esm/utils/block/formatBlockParameter.js +39 -0
- package/_esm/utils/block/formatBlockParameter.js.map +1 -0
- package/_esm/utils/ccipTunnel.js +62 -0
- package/_esm/utils/ccipTunnel.js.map +1 -0
- package/_esm/utils/index.js +1 -0
- package/_esm/utils/index.js.map +1 -1
- package/_esm/utils/nonceManager.js +7 -3
- package/_esm/utils/nonceManager.js.map +1 -1
- package/_esm/utils/observe.js +7 -1
- package/_esm/utils/observe.js.map +1 -1
- package/_esm/utils/rpc/socket.js +20 -2
- package/_esm/utils/rpc/socket.js.map +1 -1
- package/_types/actions/ens/getEnsAddress.d.ts +3 -1
- package/_types/actions/ens/getEnsAddress.d.ts.map +1 -1
- package/_types/actions/public/call.d.ts +17 -6
- package/_types/actions/public/call.d.ts.map +1 -1
- package/_types/actions/public/getBalance.d.ts +15 -3
- package/_types/actions/public/getBalance.d.ts.map +1 -1
- package/_types/actions/public/getCode.d.ts +15 -4
- package/_types/actions/public/getCode.d.ts.map +1 -1
- package/_types/actions/public/getProof.d.ts +14 -3
- package/_types/actions/public/getProof.d.ts.map +1 -1
- package/_types/actions/public/getStorageAt.d.ts +15 -4
- package/_types/actions/public/getStorageAt.d.ts.map +1 -1
- package/_types/actions/public/getTransactionCount.d.ts +15 -3
- package/_types/actions/public/getTransactionCount.d.ts.map +1 -1
- package/_types/actions/public/multicall.d.ts +1 -1
- package/_types/actions/public/multicall.d.ts.map +1 -1
- package/_types/actions/public/readContract.d.ts +1 -1
- package/_types/actions/public/readContract.d.ts.map +1 -1
- package/_types/actions/wallet/prepareTransactionRequest.d.ts +4 -2
- package/_types/actions/wallet/prepareTransactionRequest.d.ts.map +1 -1
- package/_types/actions/wallet/sendTransaction.d.ts.map +1 -1
- package/_types/actions/wallet/sendTransactionSync.d.ts.map +1 -1
- package/_types/chains/definitions/arc.d.ts +54 -0
- package/_types/chains/definitions/arc.d.ts.map +1 -0
- package/_types/chains/definitions/mizuhikiTestnetAwaji.d.ts +46 -0
- package/_types/chains/definitions/mizuhikiTestnetAwaji.d.ts.map +1 -0
- package/_types/chains/definitions/morphHolesky.d.ts +1 -1
- package/_types/chains/definitions/sentrix.d.ts +46 -0
- package/_types/chains/definitions/sentrix.d.ts.map +1 -0
- package/_types/chains/definitions/sentrixTestnet.d.ts +46 -0
- package/_types/chains/definitions/sentrixTestnet.d.ts.map +1 -0
- package/_types/chains/definitions/sova.d.ts +1 -1
- package/_types/chains/index.d.ts +4 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/constants/solidity.d.ts +16 -3
- package/_types/constants/solidity.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/index.d.ts +1 -0
- package/_types/index.d.ts.map +1 -1
- package/_types/tempo/Chain.d.ts +5 -0
- package/_types/tempo/Chain.d.ts.map +1 -0
- package/_types/tempo/Decorator.d.ts +23 -0
- package/_types/tempo/Decorator.d.ts.map +1 -1
- package/_types/tempo/Formatters.d.ts.map +1 -1
- package/_types/tempo/Transaction.d.ts.map +1 -1
- package/_types/tempo/actions/fee.d.ts +38 -0
- package/_types/tempo/actions/fee.d.ts.map +1 -1
- package/_types/tempo/actions/wallet.d.ts +9 -6
- package/_types/tempo/actions/wallet.d.ts.map +1 -1
- package/_types/tempo/chainConfig.d.ts.map +1 -1
- package/_types/tempo/chains/index.d.ts +2 -0
- package/_types/tempo/chains/index.d.ts.map +1 -0
- package/_types/tempo/errors.d.ts +36 -0
- package/_types/tempo/errors.d.ts.map +1 -0
- package/_types/tempo/index.d.ts +2 -0
- package/_types/tempo/index.d.ts.map +1 -1
- package/_types/types/block.d.ts +3 -4
- package/_types/types/block.d.ts.map +1 -1
- package/_types/types/eip1193.d.ts +1 -1
- package/_types/types/eip1193.d.ts.map +1 -1
- package/_types/utils/abi/encodeEventTopics.d.ts +6 -2
- package/_types/utils/abi/encodeEventTopics.d.ts.map +1 -1
- package/_types/utils/block/formatBlockParameter.d.ts +45 -0
- package/_types/utils/block/formatBlockParameter.d.ts.map +1 -0
- package/_types/utils/ccipTunnel.d.ts +9 -0
- package/_types/utils/ccipTunnel.d.ts.map +1 -0
- package/_types/utils/index.d.ts +1 -0
- package/_types/utils/index.d.ts.map +1 -1
- package/_types/utils/nonceManager.d.ts.map +1 -1
- package/_types/utils/observe.d.ts.map +1 -1
- package/_types/utils/rpc/socket.d.ts.map +1 -1
- package/actions/ens/getEnsAddress.ts +34 -6
- package/actions/public/call.ts +125 -51
- package/actions/public/getBalance.ts +30 -9
- package/actions/public/getCode.ts +35 -11
- package/actions/public/getProof.ts +27 -11
- package/actions/public/getStorageAt.ts +33 -10
- package/actions/public/getTransactionCount.ts +33 -11
- package/actions/public/multicall.ts +6 -0
- package/actions/public/readContract.ts +2 -0
- package/actions/wallet/prepareTransactionRequest.ts +11 -15
- package/actions/wallet/sendTransaction.ts +13 -0
- package/actions/wallet/sendTransactionSync.ts +16 -0
- package/chains/definitions/arc.ts +16 -0
- package/chains/definitions/mizuhikiTestnetAwaji.ts +26 -0
- package/chains/definitions/morphHolesky.ts +1 -1
- package/chains/definitions/sentrix.ts +26 -0
- package/chains/definitions/sentrixTestnet.ts +27 -0
- package/chains/definitions/sova.ts +1 -1
- package/chains/index.ts +4 -0
- package/constants/solidity.ts +4 -4
- package/errors/version.ts +1 -1
- package/index.ts +4 -0
- package/package.json +11 -3
- package/tempo/Chain.ts +20 -0
- package/tempo/Decorator.ts +27 -0
- package/tempo/Formatters.ts +15 -4
- package/tempo/Transaction.ts +16 -6
- package/tempo/actions/fee.ts +117 -1
- package/tempo/actions/wallet.ts +9 -6
- package/tempo/chainConfig.ts +18 -12
- package/tempo/chains/index.ts +9 -0
- package/tempo/chains/package.json +6 -0
- package/tempo/errors.ts +78 -0
- package/tempo/index.ts +2 -0
- package/types/block.ts +3 -5
- package/types/eip1193.ts +1 -1
- package/utils/abi/encodeEventTopics.ts +25 -6
- package/utils/block/formatBlockParameter.ts +63 -0
- package/utils/ccipTunnel.ts +67 -0
- package/utils/index.ts +4 -0
- package/utils/nonceManager.ts +7 -3
- package/utils/observe.ts +7 -4
- package/utils/rpc/socket.ts +21 -2
package/tempo/Decorator.ts
CHANGED
|
@@ -1389,6 +1389,31 @@ export type Decorator<
|
|
|
1389
1389
|
) => () => void
|
|
1390
1390
|
}
|
|
1391
1391
|
fee: {
|
|
1392
|
+
/**
|
|
1393
|
+
* Validates that a token can be used as a Tempo fee token.
|
|
1394
|
+
*
|
|
1395
|
+
* @example
|
|
1396
|
+
* ```ts
|
|
1397
|
+
* import { createClient, http } from 'viem'
|
|
1398
|
+
* import { tempo } from 'viem/chains'
|
|
1399
|
+
* import { tempoActions } from 'viem/tempo'
|
|
1400
|
+
*
|
|
1401
|
+
* const client = createClient({
|
|
1402
|
+
* chain: tempo
|
|
1403
|
+
* transport: http(),
|
|
1404
|
+
* }).extend(tempoActions())
|
|
1405
|
+
*
|
|
1406
|
+
* const { address } = await client.fee.validateToken({
|
|
1407
|
+
* token: '0x20c0000000000000000000000000000000000001',
|
|
1408
|
+
* })
|
|
1409
|
+
* ```
|
|
1410
|
+
*
|
|
1411
|
+
* @param parameters - Parameters.
|
|
1412
|
+
* @returns The fee token address, ID, and metadata.
|
|
1413
|
+
*/
|
|
1414
|
+
validateToken: (
|
|
1415
|
+
parameters: feeActions.validateToken.Parameters,
|
|
1416
|
+
) => Promise<feeActions.validateToken.ReturnValue>
|
|
1392
1417
|
/**
|
|
1393
1418
|
* Gets the user's default fee token.
|
|
1394
1419
|
*
|
|
@@ -4321,6 +4346,8 @@ export function decorator() {
|
|
|
4321
4346
|
nonceActions.watchNonceIncremented(client, parameters),
|
|
4322
4347
|
},
|
|
4323
4348
|
fee: {
|
|
4349
|
+
validateToken: (parameters) =>
|
|
4350
|
+
feeActions.validateToken(client, parameters),
|
|
4324
4351
|
// @ts-expect-error
|
|
4325
4352
|
getUserToken: (parameters) =>
|
|
4326
4353
|
// @ts-expect-error
|
package/tempo/Formatters.ts
CHANGED
|
@@ -72,6 +72,10 @@ export function formatTransactionRequest(
|
|
|
72
72
|
): TransactionRequestRpc {
|
|
73
73
|
const request = r as TransactionRequest & {
|
|
74
74
|
account?: viem_Account | Address | undefined
|
|
75
|
+
feePayerSignature?:
|
|
76
|
+
| { r: Hex.Hex; s: Hex.Hex; yParity: number; v?: number | undefined }
|
|
77
|
+
| null
|
|
78
|
+
| undefined
|
|
75
79
|
keyData?: Hex.Hex | undefined
|
|
76
80
|
keyId?: Address | undefined
|
|
77
81
|
keyType?: 'p256' | 'secp256k1' | 'webAuthn' | undefined
|
|
@@ -100,10 +104,17 @@ export function formatTransactionRequest(
|
|
|
100
104
|
},
|
|
101
105
|
]
|
|
102
106
|
|
|
103
|
-
// If we have marked the transaction as intended to be paid
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
+
// If we have marked the transaction as intended to be paid by a fee
|
|
108
|
+
// payer (feePayer: true), we strip the fee token from the sender's
|
|
109
|
+
// sign payload — per TIP-76 the sender does not commit to it; the fee
|
|
110
|
+
// payer chooses and commits to the token via its own signature.
|
|
111
|
+
//
|
|
112
|
+
// Once the fee payer has signed (`feePayerSignature` is populated),
|
|
113
|
+
// the relay has chosen a token and signed over it. The broadcast
|
|
114
|
+
// envelope must therefore include `feeToken` so the chain can verify
|
|
115
|
+
// the fee payer's signature and identify which token to charge.
|
|
116
|
+
if (request.feePayer === true && !request.feePayerSignature)
|
|
117
|
+
delete request.feeToken
|
|
107
118
|
|
|
108
119
|
const rpc = ox_TransactionRequest.toRpc({
|
|
109
120
|
...request,
|
package/tempo/Transaction.ts
CHANGED
|
@@ -325,10 +325,16 @@ async function serializeTempo(
|
|
|
325
325
|
...(nonce ? { nonce: BigInt(nonce) } : {}),
|
|
326
326
|
} satisfies TxTempo.TxEnvelopeTempo
|
|
327
327
|
|
|
328
|
-
// If we have marked the transaction as intended to be paid
|
|
329
|
-
//
|
|
330
|
-
//
|
|
331
|
-
|
|
328
|
+
// If we have marked the transaction as intended to be paid by a fee
|
|
329
|
+
// payer (feePayer: true), we strip the fee token from the sender's
|
|
330
|
+
// sign payload — per TIP-76 the sender does not commit to it; the fee
|
|
331
|
+
// payer chooses and commits to the token via its own signature.
|
|
332
|
+
//
|
|
333
|
+
// Once the fee payer has signed (`feePayerSignature` is populated),
|
|
334
|
+
// the relay has chosen a token and signed over it. The broadcast
|
|
335
|
+
// envelope must therefore include `feeToken` so the chain can verify
|
|
336
|
+
// the fee payer's signature and identify which token to charge.
|
|
337
|
+
if (feePayer === true && !feePayerSignature) delete transaction_ox.feeToken
|
|
332
338
|
|
|
333
339
|
if (signature && typeof transaction.feePayer === 'object') {
|
|
334
340
|
const tx = TxTempo.from(transaction_ox, {
|
|
@@ -372,8 +378,12 @@ async function serializeTempo(
|
|
|
372
378
|
|
|
373
379
|
return TxTempo.serialize(
|
|
374
380
|
// If we have specified a fee payer, the user will not be signing over the fee token.
|
|
375
|
-
// Defer the fee token signing to the fee payer.
|
|
376
|
-
|
|
381
|
+
// Defer the fee token signing to the fee payer. Once the fee payer has signed,
|
|
382
|
+
// keep `feeToken` so the broadcast envelope carries the token the chain must charge.
|
|
383
|
+
{
|
|
384
|
+
...transaction_ox,
|
|
385
|
+
...(feePayer && !feePayerSignature ? { feeToken: undefined } : {}),
|
|
386
|
+
},
|
|
377
387
|
{
|
|
378
388
|
feePayerSignature: undefined,
|
|
379
389
|
signature,
|
package/tempo/actions/fee.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { writeContractSync } from '../../actions/wallet/writeContractSync.js'
|
|
|
11
11
|
import type { Client } from '../../clients/createClient.js'
|
|
12
12
|
import type { Transport } from '../../clients/transports/createTransport.js'
|
|
13
13
|
import { zeroAddress } from '../../constants/address.js'
|
|
14
|
-
import type { BaseErrorType } from '../../errors/base.js'
|
|
14
|
+
import type { BaseError, BaseErrorType } from '../../errors/base.js'
|
|
15
15
|
import type { Chain } from '../../types/chain.js'
|
|
16
16
|
import type { ExtractAbiItem, GetEventArgs } from '../../types/contract.js'
|
|
17
17
|
import type { Log, Log as viem_Log } from '../../types/log.js'
|
|
@@ -19,6 +19,12 @@ import type { Compute, UnionOmit } from '../../types/utils.js'
|
|
|
19
19
|
import { parseEventLogs } from '../../utils/abi/parseEventLogs.js'
|
|
20
20
|
import * as Abis from '../Abis.js'
|
|
21
21
|
import * as Addresses from '../Addresses.js'
|
|
22
|
+
import {
|
|
23
|
+
FeeTokenNotTip20Error,
|
|
24
|
+
FeeTokenNotUsdError,
|
|
25
|
+
FeeTokenPausedError,
|
|
26
|
+
InvalidFeeTokenError,
|
|
27
|
+
} from '../errors.js'
|
|
22
28
|
import type {
|
|
23
29
|
GetAccountParameter,
|
|
24
30
|
ReadParameters,
|
|
@@ -26,6 +32,116 @@ import type {
|
|
|
26
32
|
} from '../internal/types.js'
|
|
27
33
|
import { defineCall } from '../internal/utils.js'
|
|
28
34
|
import type { TransactionReceipt } from '../Transaction.js'
|
|
35
|
+
import * as tokenActions from './token.js'
|
|
36
|
+
|
|
37
|
+
const tip20AddressPrefix = '0x20c0'
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validates that a token can be used as a Tempo fee token.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { createClient, http } from 'viem'
|
|
45
|
+
* import { tempo } from 'viem/chains'
|
|
46
|
+
* import { Actions } from 'viem/tempo'
|
|
47
|
+
*
|
|
48
|
+
* const client = createClient({
|
|
49
|
+
* chain: tempo,
|
|
50
|
+
* transport: http(),
|
|
51
|
+
* })
|
|
52
|
+
*
|
|
53
|
+
* const { address, metadata } = await Actions.fee.validateToken(client, {
|
|
54
|
+
* token: '0x20c0000000000000000000000000000000000001',
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @param client - Client.
|
|
59
|
+
* @param parameters - Parameters.
|
|
60
|
+
* @returns The fee token address, ID, and metadata.
|
|
61
|
+
*/
|
|
62
|
+
export async function validateToken<chain extends Chain | undefined>(
|
|
63
|
+
client: Client<Transport, chain>,
|
|
64
|
+
parameters: validateToken.Parameters,
|
|
65
|
+
): Promise<validateToken.ReturnValue> {
|
|
66
|
+
const { token, ...rest } = parameters
|
|
67
|
+
const token_ = String(token)
|
|
68
|
+
const address = (() => {
|
|
69
|
+
try {
|
|
70
|
+
return TokenId.toAddress(token)
|
|
71
|
+
} catch (cause) {
|
|
72
|
+
throw new InvalidFeeTokenError({
|
|
73
|
+
cause: cause as BaseError | Error,
|
|
74
|
+
token: token_,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
})()
|
|
78
|
+
|
|
79
|
+
if (!address.toLowerCase().startsWith(tip20AddressPrefix))
|
|
80
|
+
throw new FeeTokenNotTip20Error({ token: address })
|
|
81
|
+
|
|
82
|
+
const isPathUsd = address.toLowerCase() === Addresses.pathUsd.toLowerCase()
|
|
83
|
+
if (!isPathUsd) {
|
|
84
|
+
const isTip20 = await readContract(client, {
|
|
85
|
+
...rest,
|
|
86
|
+
address: Addresses.tip20Factory,
|
|
87
|
+
abi: Abis.tip20Factory,
|
|
88
|
+
functionName: 'isTIP20',
|
|
89
|
+
args: [address],
|
|
90
|
+
}).catch((cause) => {
|
|
91
|
+
throw new InvalidFeeTokenError({
|
|
92
|
+
cause: cause as BaseError | Error,
|
|
93
|
+
token: address,
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
if (!isTip20) throw new FeeTokenNotTip20Error({ token: address })
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const metadata = await tokenActions
|
|
100
|
+
.getMetadata(client, {
|
|
101
|
+
...rest,
|
|
102
|
+
token: address,
|
|
103
|
+
})
|
|
104
|
+
.catch((cause) => {
|
|
105
|
+
throw new InvalidFeeTokenError({
|
|
106
|
+
cause: cause as BaseError | Error,
|
|
107
|
+
token: address,
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
if (metadata.currency !== 'USD')
|
|
112
|
+
throw new FeeTokenNotUsdError({
|
|
113
|
+
currency: metadata.currency,
|
|
114
|
+
token: address,
|
|
115
|
+
})
|
|
116
|
+
if (metadata.paused === true)
|
|
117
|
+
throw new FeeTokenPausedError({ token: address })
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
address,
|
|
121
|
+
id: TokenId.fromAddress(address),
|
|
122
|
+
metadata,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export declare namespace validateToken {
|
|
127
|
+
export type Parameters = ReadParameters & {
|
|
128
|
+
/** Address or ID of the TIP20 token. */
|
|
129
|
+
token: TokenId.TokenIdOrAddress
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type ReturnValue = Compute<{
|
|
133
|
+
address: Address
|
|
134
|
+
id: bigint
|
|
135
|
+
metadata: tokenActions.getMetadata.ReturnValue
|
|
136
|
+
}>
|
|
137
|
+
|
|
138
|
+
export type ErrorType =
|
|
139
|
+
| FeeTokenNotTip20Error
|
|
140
|
+
| FeeTokenNotUsdError
|
|
141
|
+
| FeeTokenPausedError
|
|
142
|
+
| InvalidFeeTokenError
|
|
143
|
+
| BaseErrorType
|
|
144
|
+
}
|
|
29
145
|
|
|
30
146
|
/**
|
|
31
147
|
* Gets the user's default fee token.
|
package/tempo/actions/wallet.ts
CHANGED
|
@@ -213,8 +213,8 @@ export declare namespace swap {
|
|
|
213
213
|
* })
|
|
214
214
|
*
|
|
215
215
|
* const result = await Actions.wallet.deposit(client, {
|
|
216
|
-
*
|
|
217
|
-
*
|
|
216
|
+
* amount: '1.5',
|
|
217
|
+
* token: 'pathUsd',
|
|
218
218
|
* })
|
|
219
219
|
* ```
|
|
220
220
|
*
|
|
@@ -243,14 +243,17 @@ export declare namespace deposit {
|
|
|
243
243
|
export type Parameters = {
|
|
244
244
|
/** Deposit address to pre-fill. */
|
|
245
245
|
address?: Address | undefined
|
|
246
|
+
/** Human-readable amount to pre-fill (for example, "1.5"). */
|
|
247
|
+
amount?: string | undefined
|
|
246
248
|
/** Source chain ID to pre-fill. */
|
|
247
249
|
chainId?: number | undefined
|
|
248
250
|
/** Human-readable account display name. */
|
|
249
251
|
displayName?: string | undefined
|
|
250
|
-
/**
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
/**
|
|
253
|
+
* Token to pre-fill, accepted as either a contract address or a supported
|
|
254
|
+
* deposit token symbol. Omit to let the user choose.
|
|
255
|
+
*/
|
|
256
|
+
token?: Address | string | undefined
|
|
254
257
|
}
|
|
255
258
|
|
|
256
259
|
export type ReturnValue =
|
package/tempo/chainConfig.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import * as Address from 'ox/Address'
|
|
2
1
|
import * as Hex from 'ox/Hex'
|
|
3
|
-
import * as PublicKey from 'ox/PublicKey'
|
|
4
2
|
import { SignatureEnvelope, type TokenId } from 'ox/tempo'
|
|
5
3
|
import { getCode } from '../actions/public/getCode.js'
|
|
6
4
|
import { verifyHash } from '../actions/public/verifyHash.js'
|
|
@@ -115,9 +113,24 @@ export const chainConfig = {
|
|
|
115
113
|
// Access key (keychain) signature verification: check the key is
|
|
116
114
|
// authorized, not expired, and not revoked on the AccountKeychain.
|
|
117
115
|
if (envelope?.type === 'keychain' && mode === 'allowAccessKey') {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
// For v2 keychain envelopes, the inner signature signs
|
|
117
|
+
// keccak256(0x04 || hash || userAddress).
|
|
118
|
+
const innerPayload =
|
|
119
|
+
envelope.version === 'v2'
|
|
120
|
+
? keccak256(Hex.concat('0x04', hash, address))
|
|
121
|
+
: hash
|
|
122
|
+
|
|
123
|
+
const accessKeyAddress = (() => {
|
|
124
|
+
try {
|
|
125
|
+
return SignatureEnvelope.extractAddress({
|
|
126
|
+
payload: innerPayload,
|
|
127
|
+
signature: envelope.inner,
|
|
128
|
+
})
|
|
129
|
+
} catch {
|
|
130
|
+
return undefined
|
|
131
|
+
}
|
|
132
|
+
})()
|
|
133
|
+
if (!accessKeyAddress) return false
|
|
121
134
|
|
|
122
135
|
const keyInfo = await getMetadata(client, {
|
|
123
136
|
account: address,
|
|
@@ -129,13 +142,6 @@ export const chainConfig = {
|
|
|
129
142
|
if (keyInfo.isRevoked) return false
|
|
130
143
|
if (keyInfo.expiry <= BigInt(Math.floor(Date.now() / 1000)))
|
|
131
144
|
return false
|
|
132
|
-
|
|
133
|
-
// For v2 keychain envelopes, the inner signature signs
|
|
134
|
-
// keccak256(0x04 || hash || userAddress).
|
|
135
|
-
const innerPayload =
|
|
136
|
-
envelope.version === 'v2'
|
|
137
|
-
? keccak256(Hex.concat('0x04', hash, address))
|
|
138
|
-
: hash
|
|
139
145
|
return SignatureEnvelope.verify(envelope.inner, {
|
|
140
146
|
address: accessKeyAddress,
|
|
141
147
|
payload: innerPayload,
|
package/tempo/errors.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { BaseError } from '../errors/base.js'
|
|
2
|
+
|
|
3
|
+
export type InvalidFeeTokenErrorType = InvalidFeeTokenError & {
|
|
4
|
+
name: 'InvalidFeeTokenError'
|
|
5
|
+
}
|
|
6
|
+
export class InvalidFeeTokenError extends BaseError {
|
|
7
|
+
constructor({
|
|
8
|
+
cause,
|
|
9
|
+
token,
|
|
10
|
+
}: {
|
|
11
|
+
cause?: BaseError | Error | undefined
|
|
12
|
+
token: string
|
|
13
|
+
}) {
|
|
14
|
+
super(`Fee token "${token}" is invalid.`, {
|
|
15
|
+
cause,
|
|
16
|
+
docsPath: '/tempo/transactions',
|
|
17
|
+
docsSlug: 'pay-fees-with-stablecoins',
|
|
18
|
+
metaMessages: [
|
|
19
|
+
'Fee tokens must be unpaused USD-denominated TIP-20 tokens.',
|
|
20
|
+
'Use `client.fee.validateToken({ token })` before sending transactions or setting fee preferences.',
|
|
21
|
+
],
|
|
22
|
+
name: 'InvalidFeeTokenError',
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type FeeTokenNotTip20ErrorType = FeeTokenNotTip20Error & {
|
|
28
|
+
name: 'FeeTokenNotTip20Error'
|
|
29
|
+
}
|
|
30
|
+
export class FeeTokenNotTip20Error extends BaseError {
|
|
31
|
+
constructor({ token }: { token: string }) {
|
|
32
|
+
super(`Fee token "${token}" is not a TIP-20 token.`, {
|
|
33
|
+
docsPath: '/tempo/transactions',
|
|
34
|
+
docsSlug: 'pay-fees-with-stablecoins',
|
|
35
|
+
metaMessages: [
|
|
36
|
+
'Fee tokens must be TIP-20 token addresses or token IDs.',
|
|
37
|
+
'TIP-20 token addresses use the `0x20c0...` address prefix.',
|
|
38
|
+
],
|
|
39
|
+
name: 'FeeTokenNotTip20Error',
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type FeeTokenNotUsdErrorType = FeeTokenNotUsdError & {
|
|
45
|
+
name: 'FeeTokenNotUsdError'
|
|
46
|
+
}
|
|
47
|
+
export class FeeTokenNotUsdError extends BaseError {
|
|
48
|
+
constructor({
|
|
49
|
+
currency,
|
|
50
|
+
token,
|
|
51
|
+
}: {
|
|
52
|
+
currency: string
|
|
53
|
+
token: string
|
|
54
|
+
}) {
|
|
55
|
+
super(`Fee token "${token}" is denominated in "${currency}", not "USD".`, {
|
|
56
|
+
docsPath: '/tempo/transactions',
|
|
57
|
+
docsSlug: 'pay-fees-with-stablecoins',
|
|
58
|
+
metaMessages: [
|
|
59
|
+
'Only USD-denominated TIP-20 tokens can be used as fee tokens.',
|
|
60
|
+
],
|
|
61
|
+
name: 'FeeTokenNotUsdError',
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type FeeTokenPausedErrorType = FeeTokenPausedError & {
|
|
67
|
+
name: 'FeeTokenPausedError'
|
|
68
|
+
}
|
|
69
|
+
export class FeeTokenPausedError extends BaseError {
|
|
70
|
+
constructor({ token }: { token: string }) {
|
|
71
|
+
super(`Fee token "${token}" is paused.`, {
|
|
72
|
+
docsPath: '/tempo/transactions',
|
|
73
|
+
docsSlug: 'pay-fees-with-stablecoins',
|
|
74
|
+
metaMessages: ['Paused TIP-20 tokens cannot be used as fee tokens.'],
|
|
75
|
+
name: 'FeeTokenPausedError',
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}
|
package/tempo/index.ts
CHANGED
|
@@ -24,11 +24,13 @@ export * as Account from './Account.js'
|
|
|
24
24
|
export * as Addresses from './Addresses.js'
|
|
25
25
|
export * as Actions from './actions/index.js'
|
|
26
26
|
export * as Capabilities from './Capabilities.js'
|
|
27
|
+
export * as Chain from './Chain.js'
|
|
27
28
|
export {
|
|
28
29
|
type Decorator as TempoActions,
|
|
29
30
|
decorator as tempoActions,
|
|
30
31
|
} from './Decorator.js'
|
|
31
32
|
export * as Expiry from './Expiry.js'
|
|
33
|
+
export * from './errors.js'
|
|
32
34
|
export * as Formatters from './Formatters.js'
|
|
33
35
|
export * as Hardfork from './Hardfork.js'
|
|
34
36
|
export * as P256 from './P256.js'
|
package/types/block.ts
CHANGED
|
@@ -69,10 +69,7 @@ export type Block<
|
|
|
69
69
|
withdrawalsRoot?: Hex | undefined
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
export type BlockIdentifier<quantity = bigint> =
|
|
73
|
-
/** Whether or not to throw an error if the block is not in the canonical chain as described below. Only allowed in conjunction with the blockHash tag. Defaults to false. */
|
|
74
|
-
requireCanonical?: boolean | undefined
|
|
75
|
-
} & (
|
|
72
|
+
export type BlockIdentifier<quantity = bigint> =
|
|
76
73
|
| {
|
|
77
74
|
/** The block in the canonical chain with this number */
|
|
78
75
|
blockNumber: BlockNumber<quantity>
|
|
@@ -80,8 +77,9 @@ export type BlockIdentifier<quantity = bigint> = {
|
|
|
80
77
|
| {
|
|
81
78
|
/** The block uniquely identified by this hash. The `blockNumber` and `blockHash` properties are mutually exclusive; exactly one of them must be set. */
|
|
82
79
|
blockHash: Hash
|
|
80
|
+
/** Whether or not to throw an error if the block is not in the canonical chain as described below. Only allowed in conjunction with the blockHash tag. Defaults to false. */
|
|
81
|
+
requireCanonical?: boolean | undefined
|
|
83
82
|
}
|
|
84
|
-
)
|
|
85
83
|
|
|
86
84
|
/** Represents a block number in the blockchain. */
|
|
87
85
|
export type BlockNumber<quantity = bigint> = quantity
|
package/types/eip1193.ts
CHANGED
|
@@ -974,7 +974,7 @@ export type PublicRpcSchema = [
|
|
|
974
974
|
address: Address,
|
|
975
975
|
/** An array of storage-keys that should be proofed and included. */
|
|
976
976
|
storageKeys: Hash[],
|
|
977
|
-
block: BlockNumber | BlockTag,
|
|
977
|
+
block: BlockNumber | BlockTag | BlockIdentifier,
|
|
978
978
|
]
|
|
979
979
|
ReturnType: Proof
|
|
980
980
|
},
|
|
@@ -66,7 +66,22 @@ export type EncodeEventTopicsParameters<
|
|
|
66
66
|
> &
|
|
67
67
|
(hasEvents extends true ? unknown : never)
|
|
68
68
|
|
|
69
|
-
export type EncodeEventTopicsReturnType
|
|
69
|
+
export type EncodeEventTopicsReturnType<
|
|
70
|
+
abi extends Abi | readonly unknown[] = Abi,
|
|
71
|
+
eventName extends ContractEventName<abi> | undefined = undefined,
|
|
72
|
+
///
|
|
73
|
+
resolvedEvent = abi extends Abi
|
|
74
|
+
? eventName extends string
|
|
75
|
+
? Extract<ExtractAbiEvents<abi>, { name: eventName }>
|
|
76
|
+
: abi['length'] extends 1
|
|
77
|
+
? abi[0]
|
|
78
|
+
: ExtractAbiEvents<abi>
|
|
79
|
+
: unknown,
|
|
80
|
+
> = IsNarrowable<abi, Abi> extends true
|
|
81
|
+
? [resolvedEvent] extends [{ anonymous: true }]
|
|
82
|
+
? (Hex | Hex[] | null)[]
|
|
83
|
+
: [Hex, ...(Hex | Hex[] | null)[]]
|
|
84
|
+
: (Hex | Hex[] | null)[]
|
|
70
85
|
|
|
71
86
|
export type EncodeEventTopicsErrorType =
|
|
72
87
|
| AbiEventNotFoundErrorType
|
|
@@ -81,7 +96,7 @@ export function encodeEventTopics<
|
|
|
81
96
|
eventName extends ContractEventName<abi> | undefined = undefined,
|
|
82
97
|
>(
|
|
83
98
|
parameters: EncodeEventTopicsParameters<abi, eventName>,
|
|
84
|
-
): EncodeEventTopicsReturnType {
|
|
99
|
+
): EncodeEventTopicsReturnType<abi, eventName> {
|
|
85
100
|
const { abi, eventName, args } = parameters as EncodeEventTopicsParameters
|
|
86
101
|
|
|
87
102
|
let abiItem = abi[0]
|
|
@@ -94,9 +109,6 @@ export function encodeEventTopics<
|
|
|
94
109
|
if (abiItem.type !== 'event')
|
|
95
110
|
throw new AbiEventNotFoundError(undefined, { docsPath })
|
|
96
111
|
|
|
97
|
-
const definition = formatAbiItem(abiItem)
|
|
98
|
-
const signature = toEventSelector(definition as EventDefinition)
|
|
99
|
-
|
|
100
112
|
let topics: (Hex | Hex[] | null)[] = []
|
|
101
113
|
if (args && 'inputs' in abiItem) {
|
|
102
114
|
const indexedInputs = abiItem.inputs?.filter(
|
|
@@ -121,7 +133,14 @@ export function encodeEventTopics<
|
|
|
121
133
|
}) ?? []
|
|
122
134
|
}
|
|
123
135
|
}
|
|
124
|
-
|
|
136
|
+
// Anonymous events are not identified by a signature topic, so the event
|
|
137
|
+
// selector must not be prepended.
|
|
138
|
+
if (abiItem.anonymous)
|
|
139
|
+
return topics as EncodeEventTopicsReturnType<abi, eventName>
|
|
140
|
+
|
|
141
|
+
const definition = formatAbiItem(abiItem)
|
|
142
|
+
const signature = toEventSelector(definition as EventDefinition)
|
|
143
|
+
return [signature, ...topics] as EncodeEventTopicsReturnType<abi, eventName>
|
|
125
144
|
}
|
|
126
145
|
|
|
127
146
|
export type EncodeArgErrorType =
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorType } from '../../errors/base.js'
|
|
2
|
+
import type { BlockTag } from '../../types/block.js'
|
|
3
|
+
import type { Hash, Hex } from '../../types/misc.js'
|
|
4
|
+
import type { RpcBlockIdentifier } from '../../types/rpc.js'
|
|
5
|
+
import type { NumberToHexErrorType } from '../encoding/toHex.js'
|
|
6
|
+
import { numberToHex } from '../encoding/toHex.js'
|
|
7
|
+
|
|
8
|
+
type FormatBlockParameterParameters = {
|
|
9
|
+
blockHash?: Hash | undefined
|
|
10
|
+
blockNumber?: bigint | undefined
|
|
11
|
+
blockTag?: BlockTag | undefined
|
|
12
|
+
requireCanonical?: boolean | undefined
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type RpcBlockHashIdentifier = Extract<RpcBlockIdentifier, { blockHash: Hash }>
|
|
16
|
+
|
|
17
|
+
type FormatBlockParameterReturnType = Hex | BlockTag | RpcBlockHashIdentifier
|
|
18
|
+
|
|
19
|
+
export type FormatBlockParameterErrorType = BaseErrorType | NumberToHexErrorType
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Formats block parameters for RPC calls according to EIP-1898.
|
|
23
|
+
*
|
|
24
|
+
* @param parameters - Block parameters
|
|
25
|
+
* @returns Formatted block parameter for RPC call
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Using block tag
|
|
29
|
+
* formatBlockParameter({ blockTag: 'latest' })
|
|
30
|
+
* // => 'latest'
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Using block number
|
|
34
|
+
* formatBlockParameter({ blockNumber: 69420n })
|
|
35
|
+
* // => '0x10f2c'
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Using block hash (EIP-1898)
|
|
39
|
+
* formatBlockParameter({ blockHash: '0x...' })
|
|
40
|
+
* // => { blockHash: '0x...' }
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Using block hash with requireCanonical (EIP-1898)
|
|
44
|
+
* formatBlockParameter({ blockHash: '0x...', requireCanonical: true })
|
|
45
|
+
* // => { blockHash: '0x...', requireCanonical: true }
|
|
46
|
+
*/
|
|
47
|
+
export function formatBlockParameter(
|
|
48
|
+
parameters: FormatBlockParameterParameters,
|
|
49
|
+
): FormatBlockParameterReturnType {
|
|
50
|
+
const { blockHash, blockNumber, blockTag, requireCanonical } = parameters
|
|
51
|
+
|
|
52
|
+
if (requireCanonical !== undefined && !blockHash)
|
|
53
|
+
throw new BaseError(
|
|
54
|
+
'`requireCanonical` can only be provided when `blockHash` is set.',
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if (blockHash)
|
|
58
|
+
return requireCanonical ? { blockHash, requireCanonical } : { blockHash }
|
|
59
|
+
|
|
60
|
+
if (typeof blockNumber === 'bigint') return numberToHex(blockNumber)
|
|
61
|
+
|
|
62
|
+
return blockTag ?? 'latest'
|
|
63
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { batchGatewayAbi } from '../constants/abis.js'
|
|
2
|
+
import { solidityError } from '../constants/solidity.js'
|
|
3
|
+
import { HttpRequestError } from '../errors/request.js'
|
|
4
|
+
import { decodeErrorResult } from './abi/decodeErrorResult.js'
|
|
5
|
+
import { decodeFunctionResult } from './abi/decodeFunctionResult.js'
|
|
6
|
+
import { encodeFunctionData } from './abi/encodeFunctionData.js'
|
|
7
|
+
import { ccipRequest as ccipRequest_ } from './ccip.js'
|
|
8
|
+
import { localBatchGatewayUrl } from './ens/localBatchGatewayRequest.js'
|
|
9
|
+
|
|
10
|
+
export type CcipReadTunnelParameters = {
|
|
11
|
+
batchGateways: string[]
|
|
12
|
+
ccipRequest?: typeof ccipRequest_
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function ccipReadTunnel({
|
|
16
|
+
batchGateways,
|
|
17
|
+
ccipRequest = ccipRequest_,
|
|
18
|
+
}: CcipReadTunnelParameters): { request: typeof ccipRequest_ } {
|
|
19
|
+
return {
|
|
20
|
+
async request({ data, sender, urls }) {
|
|
21
|
+
if (urls.includes(localBatchGatewayUrl)) {
|
|
22
|
+
return ccipRequest({
|
|
23
|
+
data,
|
|
24
|
+
sender,
|
|
25
|
+
urls: batchGateways,
|
|
26
|
+
})
|
|
27
|
+
} else {
|
|
28
|
+
const [failures, responses] = decodeFunctionResult({
|
|
29
|
+
abi: batchGatewayAbi,
|
|
30
|
+
functionName: 'query',
|
|
31
|
+
data: await ccipRequest({
|
|
32
|
+
data: encodeFunctionData({
|
|
33
|
+
abi: batchGatewayAbi,
|
|
34
|
+
functionName: 'query',
|
|
35
|
+
args: [[{ sender, data, urls }]],
|
|
36
|
+
}),
|
|
37
|
+
sender,
|
|
38
|
+
urls: batchGateways,
|
|
39
|
+
}),
|
|
40
|
+
})
|
|
41
|
+
if (failures[0]) {
|
|
42
|
+
let error: Error | undefined
|
|
43
|
+
try {
|
|
44
|
+
const res = decodeErrorResult({
|
|
45
|
+
abi: [...batchGatewayAbi, solidityError],
|
|
46
|
+
data: responses[0],
|
|
47
|
+
})
|
|
48
|
+
if (res.errorName === 'HttpError') {
|
|
49
|
+
error = new HttpRequestError({
|
|
50
|
+
body: { message: res.args[1] },
|
|
51
|
+
status: res.args[0],
|
|
52
|
+
url: urls.join(' | '),
|
|
53
|
+
})
|
|
54
|
+
} else {
|
|
55
|
+
const message = res.args[0]
|
|
56
|
+
if (message) {
|
|
57
|
+
error = new Error(message)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
} catch {}
|
|
61
|
+
throw error ?? new Error('An unknown error occurred.')
|
|
62
|
+
}
|
|
63
|
+
return responses[0]
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
}
|
package/utils/index.ts
CHANGED
|
@@ -155,6 +155,10 @@ export {
|
|
|
155
155
|
offchainLookupAbiItem,
|
|
156
156
|
offchainLookupSignature,
|
|
157
157
|
} from './ccip.js'
|
|
158
|
+
export {
|
|
159
|
+
type CcipReadTunnelParameters,
|
|
160
|
+
ccipReadTunnel,
|
|
161
|
+
} from './ccipTunnel.js'
|
|
158
162
|
export {
|
|
159
163
|
type AssertCurrentChainErrorType,
|
|
160
164
|
type AssertCurrentChainParameters,
|