@usewhisk/cctp 0.0.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SignorDev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # @usewhisk/cctp
2
+
3
+ CCTP V2 protocol layer for Whisk.
4
+
5
+ Direct integration with CCTP V2 contracts and Circle's Iris attestation
6
+ API across all four supported ecosystems: **EVM** (viem-typed
7
+ `TokenMessengerV2` / `MessageTransmitterV2` calls), **Solana**
8
+ (Anchor-encoded instructions), **Stellar** (Soroban invocations with
9
+ the `CctpForwarder` for inbound), and **Starknet** (Cairo `Call`
10
+ values with proper `ByteArray` encoding). Pure protocol builders and
11
+ HTTP client: no wallet state, no transaction submission. The engine
12
+ layer (`@usewhisk/core`) consumes this package and hands the resulting
13
+ calldata to a per-ecosystem wallet adapter.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pnpm add @usewhisk/cctp
19
+ ```
20
+
21
+ `viem`, `@solana/web3.js`, `@stellar/stellar-sdk` and `starknet` are
22
+ direct dependencies. EVM ABIs are exported as `viem`-typed const arrays.
23
+
24
+ The chain registry, ABIs and Iris client are also available on their
25
+ own as `@usewhisk/cctp/chains`, `@usewhisk/cctp/abi` and
26
+ `@usewhisk/cctp/iris`.
27
+
28
+ ## Quickstart
29
+
30
+ Build the calls for a Fast Transfer from Base mainnet to Arbitrum One:
31
+
32
+ ```ts
33
+ import {
34
+ Base,
35
+ Arbitrum,
36
+ getBurnFees,
37
+ pickFeeTier,
38
+ buildBurnIntent,
39
+ } from "@usewhisk/cctp";
40
+
41
+ const tiers = await getBurnFees(
42
+ "mainnet",
43
+ Base.cctpDomain,
44
+ Arbitrum.cctpDomain,
45
+ );
46
+ const tier = pickFeeTier(tiers, "fast");
47
+
48
+ const intent = buildBurnIntent({
49
+ source: Base,
50
+ destination: Arbitrum,
51
+ amount: 25_000_000n, // 25 USDC (6 decimals)
52
+ mintRecipient: "0xabc...",
53
+ fee: { tier, forwarderLevel: "med" },
54
+ });
55
+
56
+ // intent.calls: ordered { to, data, value } for the wallet to sign.
57
+ ```
58
+
59
+ ## Polling for the attestation
60
+
61
+ Once the burn lands, Iris publishes a message for the source-chain tx.
62
+ Circle's forwarder picks it up on its own; you only need to poll if you
63
+ want to show progress or fall back to a manual mint.
64
+
65
+ ```ts
66
+ import { pollMessages } from "@usewhisk/cctp";
67
+
68
+ const msg = await pollMessages(
69
+ { sourceDomain: Base.cctpDomain, transactionHash: burnTxHash },
70
+ { network: "mainnet" },
71
+ );
72
+ ```
73
+
74
+ By default polling stops once the forwarder has minted or failed, or,
75
+ for a burn without the forwarder, once the attestation is complete.
76
+ Pass `isDone` to choose your own condition. It resolves to `null` if
77
+ Iris has nothing by the timeout.
78
+
79
+ ## Manual mint (recovery)
80
+
81
+ If `msg.forwardState === "FAILED"`, build the destination-chain
82
+ `receiveMessage` calldata yourself:
83
+
84
+ ```ts
85
+ import { buildMintIntent } from "@usewhisk/cctp";
86
+
87
+ const mint = buildMintIntent({
88
+ destination: Arbitrum,
89
+ message: msg.message,
90
+ attestation: msg.attestation,
91
+ });
92
+
93
+ // mint.call -> { to, data, value: 0n }
94
+ ```
95
+
96
+ `buildMintIntent` is for EVM destinations. Use
97
+ `buildSolanaReceiveIntent`, `buildStellarMintIntent` or
98
+ `buildStarknetReceiveIntent` for the others.
99
+
100
+ ## What it does
101
+
102
+ - **Chain registry:** every chain that supports CCTP V2 on EVM, Solana,
103
+ Stellar and Starknet (mainnet and testnet), with USDC address,
104
+ contract addresses, domain, default RPC URLs and capability flags.
105
+ - **Contract ABIs:** `TokenMessengerV2`, `MessageTransmitterV2`, USDC.
106
+ - **Iris API client:** fees, signed upfront-fee quotes, message fetch
107
+ and poll, reattest, with a shared rate limiter.
108
+ - **Forwarder hookData:** the magic bytes that ask Circle's forwarder
109
+ to submit the destination mint.
110
+ - **Address encoding:** bytes32 mint recipients for every ecosystem.
111
+ - **Fee math:** protocol fee (bps) plus forwarder fee, with optional
112
+ buffers.
113
+ - **Burn builders:** `buildBurnIntent` and `buildBurnWithFeesIntent`
114
+ (EVM), `buildSolanaBurnIntent`, `buildStellarBurnIntent`,
115
+ `buildStarknetBurnIntent`. The forwarder is on by default.
116
+ - **Mint builders:** `receiveMessage` calldata for recovery on every
117
+ ecosystem.
118
+
119
+ ## What it does not do
120
+
121
+ - Send transactions. The engine hands calldata to a wallet adapter.
122
+ - Hold wallet state or signers.
123
+
124
+ ## Error handling
125
+
126
+ Every failure mode throws a typed error in a single hierarchy rooted at
127
+ `CctpError`:
128
+
129
+ ```ts
130
+ import {
131
+ CctpError,
132
+ InvalidInputError,
133
+ IrisHttpError,
134
+ IrisNetworkError,
135
+ IrisAbortedError,
136
+ ProtocolError,
137
+ UnsupportedError,
138
+ isCctpError,
139
+ } from "@usewhisk/cctp";
140
+
141
+ try {
142
+ const intent = buildBurnIntent(input);
143
+ } catch (err) {
144
+ if (err instanceof InvalidInputError) {
145
+ // bad amount, bad address, identical source and destination
146
+ } else if (err instanceof ProtocolError) {
147
+ // amount above the 10M cap, Fast Transfer not offered on the source
148
+ } else if (isCctpError(err)) {
149
+ // any other typed failure: inspect err.code
150
+ }
151
+ }
152
+ ```
153
+
154
+ `IrisHttpError` carries `status`, `bodySnippet`, and `url` for
155
+ debugging. `IrisRateLimitedError` carries `retryAt`. `IrisAbortedError`
156
+ is thrown when an `AbortSignal` cancels a request. Use `err.code` for
157
+ stable programmatic dispatch.
158
+
159
+ ## Supported chains
160
+
161
+ Chain ids are strings such as `Base_Sepolia`. `getChain(id)` returns the
162
+ entry, and `CHAINS` lists them all. "Fast source" means Circle offers Fast
163
+ Transfer for burns from that chain; on the others, Circle's standard
164
+ attestation is the only option. "Forwarding" means Circle's Forwarding Service
165
+ can mint on that chain.
166
+
167
+ | Chain | Mainnet id | Testnet id | Domain | Fast source | Forwarding |
168
+ | ----------- | ------------- | ---------------------- | ------ | ----------- | ---------- |
169
+ | Ethereum | `Ethereum` | `Ethereum_Sepolia` | 0 | yes | yes |
170
+ | Avalanche | `Avalanche` | `Avalanche_Fuji` | 1 | no | yes |
171
+ | OP Mainnet | `Optimism` | `Optimism_Sepolia` | 2 | yes | yes |
172
+ | Arbitrum | `Arbitrum` | `Arbitrum_Sepolia` | 3 | yes | yes |
173
+ | Base | `Base` | `Base_Sepolia` | 6 | yes | yes |
174
+ | Polygon PoS | `Polygon` | `Polygon_Amoy_Testnet` | 7 | no | yes |
175
+ | Unichain | `Unichain` | `Unichain_Sepolia` | 10 | yes | yes |
176
+ | Linea | `Linea` | `Linea_Sepolia` | 11 | yes | yes |
177
+ | Codex | `Codex` | `Codex_Testnet` | 12 | yes | yes |
178
+ | Sonic | `Sonic` | `Sonic_Testnet` | 13 | no | yes |
179
+ | World Chain | `World_Chain` | `World_Chain_Sepolia` | 14 | yes | yes |
180
+ | Monad | `Monad` | `Monad_Testnet` | 15 | no | yes |
181
+ | Sei | `Sei` | `Sei_Testnet` | 16 | no | yes |
182
+ | XDC | `XDC` | `XDC_Apothem` | 18 | no | yes |
183
+ | HyperEVM | `HyperEVM` | `HyperEVM_Testnet` | 19 | no | yes |
184
+ | Ink | `Ink` | `Ink_Testnet` | 21 | yes | yes |
185
+ | Plume | `Plume` | `Plume_Testnet` | 22 | yes | yes |
186
+ | Arc | `Arc` | `Arc_Testnet` | 26 | no | yes |
187
+ | EDGE | `Edge` | `Edge_Testnet` | 28 | yes | yes |
188
+ | Injective | `Injective` | `Injective_Testnet` | 29 | no | no |
189
+ | Morph | `Morph` | `Morph_Testnet` | 30 | yes | no |
190
+ | Pharos | `Pharos` | `Pharos_Testnet` | 31 | no | no |
191
+ | Cronos | `Cronos` | `Cronos_Testnet` | 32 | no | no |
192
+ | Plasma | `Plasma` | `Plasma_Testnet` | 33 | no | no |
193
+ | X Layer | `X_Layer` | `X_Layer_Testnet` | 37 | yes | no |
194
+ | Solana | `Solana` | `Solana_Devnet` | 5 | yes | yes |
195
+ | Stellar | `Stellar` | `Stellar_Testnet` | 27 | no | no |
196
+ | Starknet | `Starknet` | `Starknet_Sepolia` | 25 | yes | no |
197
+
198
+ `pnpm --filter @usewhisk/cctp check:registry` reads each EVM entry back from
199
+ its public RPCs: chain id, `localDomain()`, the TokenMessenger's transmitter,
200
+ and the USDC symbol and decimals.
201
+
202
+ ## Live tests
203
+
204
+ Unit tests run on every commit. There's a separate live integration
205
+ suite that hits the real Iris sandbox; run it before publishing:
206
+
207
+ ```bash
208
+ IRIS_LIVE=1 pnpm --filter @usewhisk/cctp test
209
+ ```
210
+
211
+ ## Status
212
+
213
+ v0.1, under active development. The API may change before v1.
214
+
215
+ ## Links
216
+
217
+ - **Source:** <https://github.com/usewhisk/whisk/tree/main/packages/cctp>
218
+ - **Issues:** <https://github.com/usewhisk/whisk/issues>
package/dist/abi.cjs ADDED
@@ -0,0 +1,239 @@
1
+ 'use strict';
2
+
3
+ // src/abi/tokenMessengerV2.ts
4
+ var tokenMessengerV2Abi = [
5
+ {
6
+ type: "function",
7
+ name: "depositForBurn",
8
+ stateMutability: "nonpayable",
9
+ inputs: [
10
+ { name: "amount", type: "uint256" },
11
+ { name: "destinationDomain", type: "uint32" },
12
+ { name: "mintRecipient", type: "bytes32" },
13
+ { name: "burnToken", type: "address" },
14
+ { name: "destinationCaller", type: "bytes32" },
15
+ { name: "maxFee", type: "uint256" },
16
+ { name: "minFinalityThreshold", type: "uint32" }
17
+ ],
18
+ outputs: []
19
+ },
20
+ {
21
+ type: "function",
22
+ name: "depositForBurnWithHook",
23
+ stateMutability: "nonpayable",
24
+ inputs: [
25
+ { name: "amount", type: "uint256" },
26
+ { name: "destinationDomain", type: "uint32" },
27
+ { name: "mintRecipient", type: "bytes32" },
28
+ { name: "burnToken", type: "address" },
29
+ { name: "destinationCaller", type: "bytes32" },
30
+ { name: "maxFee", type: "uint256" },
31
+ { name: "minFinalityThreshold", type: "uint32" },
32
+ { name: "hookData", type: "bytes" }
33
+ ],
34
+ outputs: []
35
+ },
36
+ {
37
+ type: "event",
38
+ name: "DepositForBurn",
39
+ anonymous: false,
40
+ inputs: [
41
+ { name: "burnToken", type: "address", indexed: true },
42
+ { name: "amount", type: "uint256", indexed: false },
43
+ { name: "depositor", type: "address", indexed: true },
44
+ { name: "mintRecipient", type: "bytes32", indexed: false },
45
+ { name: "destinationDomain", type: "uint32", indexed: false },
46
+ { name: "destinationTokenMessenger", type: "bytes32", indexed: false },
47
+ { name: "destinationCaller", type: "bytes32", indexed: false },
48
+ { name: "maxFee", type: "uint256", indexed: false },
49
+ { name: "minFinalityThreshold", type: "uint32", indexed: false },
50
+ { name: "hookData", type: "bytes", indexed: false }
51
+ ]
52
+ }
53
+ ];
54
+
55
+ // src/abi/messageTransmitterV2.ts
56
+ var messageTransmitterV2Abi = [
57
+ {
58
+ type: "function",
59
+ name: "receiveMessage",
60
+ stateMutability: "nonpayable",
61
+ inputs: [
62
+ { name: "message", type: "bytes" },
63
+ { name: "attestation", type: "bytes" }
64
+ ],
65
+ outputs: [{ name: "success", type: "bool" }]
66
+ },
67
+ {
68
+ type: "function",
69
+ name: "usedNonces",
70
+ stateMutability: "view",
71
+ inputs: [{ name: "nonce", type: "bytes32" }],
72
+ outputs: [{ name: "isUsed", type: "uint256" }]
73
+ },
74
+ {
75
+ type: "event",
76
+ name: "MessageReceived",
77
+ anonymous: false,
78
+ inputs: [
79
+ { name: "caller", type: "address", indexed: true },
80
+ { name: "sourceDomain", type: "uint32", indexed: true },
81
+ { name: "nonce", type: "bytes32", indexed: true },
82
+ { name: "sender", type: "bytes32", indexed: false },
83
+ { name: "finalityThresholdExecuted", type: "uint32", indexed: false },
84
+ { name: "messageBody", type: "bytes", indexed: false }
85
+ ]
86
+ },
87
+ {
88
+ type: "event",
89
+ name: "MessageSent",
90
+ anonymous: false,
91
+ inputs: [{ name: "message", type: "bytes", indexed: false }]
92
+ }
93
+ ];
94
+
95
+ // src/abi/usdc.ts
96
+ var usdcAbi = [
97
+ {
98
+ type: "function",
99
+ name: "balanceOf",
100
+ stateMutability: "view",
101
+ inputs: [{ name: "account", type: "address" }],
102
+ outputs: [{ name: "balance", type: "uint256" }]
103
+ },
104
+ {
105
+ type: "function",
106
+ name: "allowance",
107
+ stateMutability: "view",
108
+ inputs: [
109
+ { name: "owner", type: "address" },
110
+ { name: "spender", type: "address" }
111
+ ],
112
+ outputs: [{ name: "remaining", type: "uint256" }]
113
+ },
114
+ {
115
+ type: "function",
116
+ name: "decimals",
117
+ stateMutability: "view",
118
+ inputs: [],
119
+ outputs: [{ name: "", type: "uint8" }]
120
+ },
121
+ {
122
+ type: "function",
123
+ name: "approve",
124
+ stateMutability: "nonpayable",
125
+ inputs: [
126
+ { name: "spender", type: "address" },
127
+ { name: "value", type: "uint256" }
128
+ ],
129
+ outputs: [{ name: "", type: "bool" }]
130
+ },
131
+ {
132
+ type: "function",
133
+ name: "transfer",
134
+ stateMutability: "nonpayable",
135
+ inputs: [
136
+ { name: "to", type: "address" },
137
+ { name: "value", type: "uint256" }
138
+ ],
139
+ outputs: [{ name: "", type: "bool" }]
140
+ },
141
+ {
142
+ type: "function",
143
+ name: "nonces",
144
+ stateMutability: "view",
145
+ inputs: [{ name: "owner", type: "address" }],
146
+ outputs: [{ name: "", type: "uint256" }]
147
+ },
148
+ {
149
+ type: "function",
150
+ name: "DOMAIN_SEPARATOR",
151
+ stateMutability: "view",
152
+ inputs: [],
153
+ outputs: [{ name: "", type: "bytes32" }]
154
+ },
155
+ {
156
+ type: "function",
157
+ name: "permit",
158
+ stateMutability: "nonpayable",
159
+ inputs: [
160
+ { name: "owner", type: "address" },
161
+ { name: "spender", type: "address" },
162
+ { name: "value", type: "uint256" },
163
+ { name: "deadline", type: "uint256" },
164
+ { name: "v", type: "uint8" },
165
+ { name: "r", type: "bytes32" },
166
+ { name: "s", type: "bytes32" }
167
+ ],
168
+ outputs: []
169
+ },
170
+ {
171
+ type: "event",
172
+ name: "Transfer",
173
+ anonymous: false,
174
+ inputs: [
175
+ { name: "from", type: "address", indexed: true },
176
+ { name: "to", type: "address", indexed: true },
177
+ { name: "value", type: "uint256", indexed: false }
178
+ ]
179
+ },
180
+ {
181
+ type: "event",
182
+ name: "Approval",
183
+ anonymous: false,
184
+ inputs: [
185
+ { name: "owner", type: "address", indexed: true },
186
+ { name: "spender", type: "address", indexed: true },
187
+ { name: "value", type: "uint256", indexed: false }
188
+ ]
189
+ }
190
+ ];
191
+
192
+ // src/abi/tokenMessengerWithFees.ts
193
+ var tokenMessengerWithFeesAbi = [
194
+ {
195
+ type: "function",
196
+ name: "depositForBurnWithFees",
197
+ stateMutability: "payable",
198
+ inputs: [
199
+ { name: "amount", type: "uint256" },
200
+ { name: "destinationDomain", type: "uint32" },
201
+ { name: "mintRecipient", type: "bytes32" },
202
+ { name: "burnToken", type: "address" },
203
+ { name: "destinationCaller", type: "bytes32" },
204
+ {
205
+ name: "claim",
206
+ type: "tuple",
207
+ components: [
208
+ { name: "signedQuote", type: "bytes" },
209
+ { name: "refundAddress", type: "address" }
210
+ ]
211
+ }
212
+ ],
213
+ outputs: []
214
+ },
215
+ {
216
+ type: "function",
217
+ name: "getFee",
218
+ stateMutability: "pure",
219
+ inputs: [{ name: "signedQuote", type: "bytes" }],
220
+ outputs: [
221
+ { name: "totalFee", type: "uint256" },
222
+ { name: "feeToken", type: "address" }
223
+ ]
224
+ },
225
+ {
226
+ type: "function",
227
+ name: "tokenMessenger",
228
+ stateMutability: "view",
229
+ inputs: [],
230
+ outputs: [{ name: "", type: "address" }]
231
+ }
232
+ ];
233
+
234
+ exports.messageTransmitterV2Abi = messageTransmitterV2Abi;
235
+ exports.tokenMessengerV2Abi = tokenMessengerV2Abi;
236
+ exports.tokenMessengerWithFeesAbi = tokenMessengerWithFeesAbi;
237
+ exports.usdcAbi = usdcAbi;
238
+ //# sourceMappingURL=abi.cjs.map
239
+ //# sourceMappingURL=abi.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/abi/tokenMessengerV2.ts","../src/abi/messageTransmitterV2.ts","../src/abi/usdc.ts","../src/abi/tokenMessengerWithFees.ts"],"names":[],"mappings":"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","file":"abi.cjs","sourcesContent":["/**\n * `TokenMessengerV2` ABI (relevant subset).\n *\n * Source: github.com/circlefin/evm-cctp-contracts (v2 abis).\n * Only the functions and events Whisk actually calls are included.\n */\nexport const tokenMessengerV2Abi = [\n {\n type: \"function\",\n name: \"depositForBurn\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"amount\", type: \"uint256\" },\n { name: \"destinationDomain\", type: \"uint32\" },\n { name: \"mintRecipient\", type: \"bytes32\" },\n { name: \"burnToken\", type: \"address\" },\n { name: \"destinationCaller\", type: \"bytes32\" },\n { name: \"maxFee\", type: \"uint256\" },\n { name: \"minFinalityThreshold\", type: \"uint32\" },\n ],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"depositForBurnWithHook\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"amount\", type: \"uint256\" },\n { name: \"destinationDomain\", type: \"uint32\" },\n { name: \"mintRecipient\", type: \"bytes32\" },\n { name: \"burnToken\", type: \"address\" },\n { name: \"destinationCaller\", type: \"bytes32\" },\n { name: \"maxFee\", type: \"uint256\" },\n { name: \"minFinalityThreshold\", type: \"uint32\" },\n { name: \"hookData\", type: \"bytes\" },\n ],\n outputs: [],\n },\n {\n type: \"event\",\n name: \"DepositForBurn\",\n anonymous: false,\n inputs: [\n { name: \"burnToken\", type: \"address\", indexed: true },\n { name: \"amount\", type: \"uint256\", indexed: false },\n { name: \"depositor\", type: \"address\", indexed: true },\n { name: \"mintRecipient\", type: \"bytes32\", indexed: false },\n { name: \"destinationDomain\", type: \"uint32\", indexed: false },\n { name: \"destinationTokenMessenger\", type: \"bytes32\", indexed: false },\n { name: \"destinationCaller\", type: \"bytes32\", indexed: false },\n { name: \"maxFee\", type: \"uint256\", indexed: false },\n { name: \"minFinalityThreshold\", type: \"uint32\", indexed: false },\n { name: \"hookData\", type: \"bytes\", indexed: false },\n ],\n },\n] as const;\n","/**\n * The subset of `MessageTransmitterV2` Whisk uses: `receiveMessage` for\n * manual recovery, `usedNonces` to check whether a message was minted, and\n * the `MessageReceived` and `MessageSent` events.\n */\nexport const messageTransmitterV2Abi = [\n {\n type: \"function\",\n name: \"receiveMessage\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"message\", type: \"bytes\" },\n { name: \"attestation\", type: \"bytes\" },\n ],\n outputs: [{ name: \"success\", type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"usedNonces\",\n stateMutability: \"view\",\n inputs: [{ name: \"nonce\", type: \"bytes32\" }],\n outputs: [{ name: \"isUsed\", type: \"uint256\" }],\n },\n {\n type: \"event\",\n name: \"MessageReceived\",\n anonymous: false,\n inputs: [\n { name: \"caller\", type: \"address\", indexed: true },\n { name: \"sourceDomain\", type: \"uint32\", indexed: true },\n { name: \"nonce\", type: \"bytes32\", indexed: true },\n { name: \"sender\", type: \"bytes32\", indexed: false },\n { name: \"finalityThresholdExecuted\", type: \"uint32\", indexed: false },\n { name: \"messageBody\", type: \"bytes\", indexed: false },\n ],\n },\n {\n type: \"event\",\n name: \"MessageSent\",\n anonymous: false,\n inputs: [{ name: \"message\", type: \"bytes\", indexed: false }],\n },\n] as const;\n","/**\n * The parts of the USDC (FiatTokenV2) ABI that Whisk needs.\n *\n * Read: balanceOf, allowance, decimals, nonces, DOMAIN_SEPARATOR.\n * Write: approve, transfer, permit (EIP-2612).\n */\nexport const usdcAbi = [\n {\n type: \"function\",\n name: \"balanceOf\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"balance\", type: \"uint256\" }],\n },\n {\n type: \"function\",\n name: \"allowance\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"remaining\", type: \"uint256\" }],\n },\n {\n type: \"function\",\n name: \"decimals\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n {\n type: \"function\",\n name: \"approve\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"transfer\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"nonces\",\n stateMutability: \"view\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n type: \"function\",\n name: \"DOMAIN_SEPARATOR\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bytes32\" }],\n },\n {\n type: \"function\",\n name: \"permit\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n { name: \"v\", type: \"uint8\" },\n { name: \"r\", type: \"bytes32\" },\n { name: \"s\", type: \"bytes32\" },\n ],\n outputs: [],\n },\n {\n type: \"event\",\n name: \"Transfer\",\n anonymous: false,\n inputs: [\n { name: \"from\", type: \"address\", indexed: true },\n { name: \"to\", type: \"address\", indexed: true },\n { name: \"value\", type: \"uint256\", indexed: false },\n ],\n },\n {\n type: \"event\",\n name: \"Approval\",\n anonymous: false,\n inputs: [\n { name: \"owner\", type: \"address\", indexed: true },\n { name: \"spender\", type: \"address\", indexed: true },\n { name: \"value\", type: \"uint256\", indexed: false },\n ],\n },\n] as const;\n","/**\n * The parts of Circle's `TokenMessengerWithFees` that Whisk calls, from the ABI\n * in Circle's contract interface reference. Only the `bytes signedQuote`\n * overload of each burn is listed, so encoding never has to pick between them.\n */\nexport const tokenMessengerWithFeesAbi = [\n {\n type: \"function\",\n name: \"depositForBurnWithFees\",\n stateMutability: \"payable\",\n inputs: [\n { name: \"amount\", type: \"uint256\" },\n { name: \"destinationDomain\", type: \"uint32\" },\n { name: \"mintRecipient\", type: \"bytes32\" },\n { name: \"burnToken\", type: \"address\" },\n { name: \"destinationCaller\", type: \"bytes32\" },\n {\n name: \"claim\",\n type: \"tuple\",\n components: [\n { name: \"signedQuote\", type: \"bytes\" },\n { name: \"refundAddress\", type: \"address\" },\n ],\n },\n ],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"getFee\",\n stateMutability: \"pure\",\n inputs: [{ name: \"signedQuote\", type: \"bytes\" }],\n outputs: [\n { name: \"totalFee\", type: \"uint256\" },\n { name: \"feeToken\", type: \"address\" },\n ],\n },\n {\n type: \"function\",\n name: \"tokenMessenger\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n] as const;\n"]}