@lendasat/lendaswap-sdk-pure 0.2.24 → 0.2.26
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/dist/arkade-network.d.ts +8 -0
- package/dist/arkade-network.d.ts.map +1 -0
- package/dist/arkade-network.js +40 -0
- package/dist/arkade-network.js.map +1 -0
- package/dist/arkade.d.ts.map +1 -1
- package/dist/arkade.js +2 -9
- package/dist/arkade.js.map +1 -1
- package/dist/cctp/constants.d.ts.map +1 -1
- package/dist/cctp/constants.js +4 -0
- package/dist/cctp/constants.js.map +1 -1
- package/dist/cctp/fee.d.ts +49 -0
- package/dist/cctp/fee.d.ts.map +1 -0
- package/dist/cctp/fee.js +70 -0
- package/dist/cctp/fee.js.map +1 -0
- package/dist/cctp/index.d.ts +2 -1
- package/dist/cctp/index.d.ts.map +1 -1
- package/dist/cctp/index.js +2 -1
- package/dist/cctp/index.js.map +1 -1
- package/dist/cctp/utils.d.ts +15 -0
- package/dist/cctp/utils.d.ts.map +1 -1
- package/dist/cctp/utils.js +41 -0
- package/dist/cctp/utils.js.map +1 -1
- package/dist/cctp-bridge/bridge.d.ts +62 -0
- package/dist/cctp-bridge/bridge.d.ts.map +1 -0
- package/dist/cctp-bridge/bridge.js +74 -0
- package/dist/cctp-bridge/bridge.js.map +1 -0
- package/dist/cctp-bridge/index.d.ts +17 -0
- package/dist/cctp-bridge/index.d.ts.map +1 -0
- package/dist/cctp-bridge/index.js +16 -0
- package/dist/cctp-bridge/index.js.map +1 -0
- package/dist/cctp-inbound/approveAndBurn.d.ts +68 -0
- package/dist/cctp-inbound/approveAndBurn.d.ts.map +1 -0
- package/dist/cctp-inbound/approveAndBurn.js +95 -0
- package/dist/cctp-inbound/approveAndBurn.js.map +1 -0
- package/dist/cctp-inbound/burn.d.ts +51 -0
- package/dist/cctp-inbound/burn.d.ts.map +1 -0
- package/dist/cctp-inbound/burn.js +66 -0
- package/dist/cctp-inbound/burn.js.map +1 -0
- package/dist/cctp-inbound/chainMap.d.ts +48 -0
- package/dist/cctp-inbound/chainMap.d.ts.map +1 -0
- package/dist/cctp-inbound/chainMap.js +103 -0
- package/dist/cctp-inbound/chainMap.js.map +1 -0
- package/dist/cctp-inbound/client.d.ts +1573 -0
- package/dist/cctp-inbound/client.d.ts.map +1 -0
- package/dist/cctp-inbound/client.js +117 -0
- package/dist/cctp-inbound/client.js.map +1 -0
- package/dist/cctp-inbound/eip2612.d.ts +77 -0
- package/dist/cctp-inbound/eip2612.d.ts.map +1 -0
- package/dist/cctp-inbound/eip2612.js +95 -0
- package/dist/cctp-inbound/eip2612.js.map +1 -0
- package/dist/cctp-inbound/evmSignerAdapter.d.ts +25 -0
- package/dist/cctp-inbound/evmSignerAdapter.d.ts.map +1 -0
- package/dist/cctp-inbound/evmSignerAdapter.js +50 -0
- package/dist/cctp-inbound/evmSignerAdapter.js.map +1 -0
- package/dist/cctp-inbound/fundSwap.d.ts +94 -0
- package/dist/cctp-inbound/fundSwap.d.ts.map +1 -0
- package/dist/cctp-inbound/fundSwap.js +90 -0
- package/dist/cctp-inbound/fundSwap.js.map +1 -0
- package/dist/cctp-inbound/index.d.ts +35 -0
- package/dist/cctp-inbound/index.d.ts.map +1 -0
- package/dist/cctp-inbound/index.js +33 -0
- package/dist/cctp-inbound/index.js.map +1 -0
- package/dist/cctp-inbound/permit2.d.ts +33 -0
- package/dist/cctp-inbound/permit2.d.ts.map +1 -0
- package/dist/cctp-inbound/permit2.js +32 -0
- package/dist/cctp-inbound/permit2.js.map +1 -0
- package/dist/cctp-inbound/preflight.d.ts +36 -0
- package/dist/cctp-inbound/preflight.d.ts.map +1 -0
- package/dist/cctp-inbound/preflight.js +67 -0
- package/dist/cctp-inbound/preflight.js.map +1 -0
- package/dist/cctp-inbound/smartAccount.d.ts +1518 -0
- package/dist/cctp-inbound/smartAccount.d.ts.map +1 -0
- package/dist/cctp-inbound/smartAccount.js +117 -0
- package/dist/cctp-inbound/smartAccount.js.map +1 -0
- package/dist/cctp-inbound/submit.d.ts +75 -0
- package/dist/cctp-inbound/submit.d.ts.map +1 -0
- package/dist/cctp-inbound/submit.js +126 -0
- package/dist/cctp-inbound/submit.js.map +1 -0
- package/dist/cctp-inbound/types.d.ts +30 -0
- package/dist/cctp-inbound/types.d.ts.map +1 -0
- package/dist/cctp-inbound/types.js +5 -0
- package/dist/cctp-inbound/types.js.map +1 -0
- package/dist/cctp-inbound/userOp.d.ts +93 -0
- package/dist/cctp-inbound/userOp.d.ts.map +1 -0
- package/dist/cctp-inbound/userOp.js +151 -0
- package/dist/cctp-inbound/userOp.js.map +1 -0
- package/dist/client.d.ts +166 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +565 -32
- package/dist/client.js.map +1 -1
- package/dist/create/arkade.d.ts.map +1 -1
- package/dist/create/arkade.js +21 -19
- package/dist/create/arkade.js.map +1 -1
- package/dist/create/bitcoin.d.ts.map +1 -1
- package/dist/create/bitcoin.js +17 -15
- package/dist/create/bitcoin.js.map +1 -1
- package/dist/create/evm-to-arkade.d.ts.map +1 -1
- package/dist/create/evm-to-arkade.js +2 -0
- package/dist/create/evm-to-arkade.js.map +1 -1
- package/dist/create/evm-to-bitcoin.d.ts.map +1 -1
- package/dist/create/evm-to-bitcoin.js +2 -0
- package/dist/create/evm-to-bitcoin.js.map +1 -1
- package/dist/create/evm-to-lightning.d.ts.map +1 -1
- package/dist/create/evm-to-lightning.js +6 -3
- package/dist/create/evm-to-lightning.js.map +1 -1
- package/dist/create/lightning.d.ts.map +1 -1
- package/dist/create/lightning.js +17 -15
- package/dist/create/lightning.js.map +1 -1
- package/dist/create/types.d.ts +40 -0
- package/dist/create/types.d.ts.map +1 -1
- package/dist/delegate.d.ts.map +1 -1
- package/dist/delegate.js +2 -31
- package/dist/delegate.js.map +1 -1
- package/dist/evm/wallet.d.ts +16 -0
- package/dist/evm/wallet.d.ts.map +1 -1
- package/dist/evm/wallet.js.map +1 -1
- package/dist/generated/api.d.ts +408 -2
- package/dist/generated/api.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/redeem/arkade.d.ts.map +1 -1
- package/dist/redeem/arkade.js +4 -43
- package/dist/redeem/arkade.js.map +1 -1
- package/dist/redeem/gasless.d.ts +16 -0
- package/dist/redeem/gasless.d.ts.map +1 -1
- package/dist/redeem/gasless.js +3 -1
- package/dist/redeem/gasless.js.map +1 -1
- package/dist/refund/arkade.d.ts.map +1 -1
- package/dist/refund/arkade.js +3 -39
- package/dist/refund/arkade.js.map +1 -1
- package/dist/refund/{collab.d.ts → collab-arkade-evm.d.ts} +6 -6
- package/dist/refund/collab-arkade-evm.d.ts.map +1 -0
- package/dist/refund/{collab.js → collab-arkade-evm.js} +6 -38
- package/dist/refund/collab-arkade-evm.js.map +1 -0
- package/dist/refund/collab-arkade-lightning.d.ts +59 -0
- package/dist/refund/collab-arkade-lightning.d.ts.map +1 -0
- package/dist/refund/collab-arkade-lightning.js +208 -0
- package/dist/refund/collab-arkade-lightning.js.map +1 -0
- package/dist/refund/index.d.ts +3 -2
- package/dist/refund/index.d.ts.map +1 -1
- package/dist/refund/index.js +3 -2
- package/dist/refund/index.js.map +1 -1
- package/dist/tokens.d.ts +18 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +43 -7
- package/dist/tokens.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +27 -2
- package/dist/refund/collab.d.ts.map +0 -1
- package/dist/refund/collab.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smartAccount.d.ts","sourceRoot":"","sources":["../../src/cctp-inbound/smartAccount.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a ZeroDev Kernel smart-account client on Arbitrum, owned by a
|
|
3
|
+
* viem `Account` supplied by the consumer (Privy, wagmi, raw private
|
|
4
|
+
* key — any viem-compatible signer).
|
|
5
|
+
*
|
|
6
|
+
* The smart-account address is deterministic from `(owner, factory,
|
|
7
|
+
* impl, salt)`, which makes it usable as both:
|
|
8
|
+
* - `mintRecipient` on the source-chain CCTP burn (USDC arrives here)
|
|
9
|
+
* - `destinationCaller` (bytes32-padded) — only this account can
|
|
10
|
+
* call `receiveMessage` on Arbitrum
|
|
11
|
+
*
|
|
12
|
+
* The account is counterfactually deployed: the bytecode doesn't exist
|
|
13
|
+
* on-chain until the first UserOperation submits, and its `initCode`
|
|
14
|
+
* is provided by Kernel's factory.
|
|
15
|
+
*
|
|
16
|
+
* Bundler + paymaster both live at the same Alchemy app URL; the
|
|
17
|
+
* policy id is passed via the ERC-7677 `paymasterContext`.
|
|
18
|
+
*/
|
|
19
|
+
import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator";
|
|
20
|
+
import { createKernelAccount, createKernelAccountClient } from "@zerodev/sdk";
|
|
21
|
+
import { getEntryPoint, KERNEL_V3_1 } from "@zerodev/sdk/constants";
|
|
22
|
+
import { createPublicClient, http } from "viem";
|
|
23
|
+
import { createPaymasterClient } from "viem/account-abstraction";
|
|
24
|
+
import { arbitrum } from "viem/chains";
|
|
25
|
+
import { evmSignerToKernelOwner } from "./evmSignerAdapter.js";
|
|
26
|
+
/**
|
|
27
|
+
* Creates a Kernel smart-account client ready to send UserOperations.
|
|
28
|
+
* Async — resolves once the account address + validator are derived.
|
|
29
|
+
*
|
|
30
|
+
* @returns `{ client, account, accountAddress }` where `accountAddress`
|
|
31
|
+
* is the deterministic smart-account address.
|
|
32
|
+
*/
|
|
33
|
+
export async function createSwapSmartAccountClient(params) {
|
|
34
|
+
const { signer, aa, chain = arbitrum } = params;
|
|
35
|
+
const { bundlerUrl, paymasterPolicyId } = aa;
|
|
36
|
+
if (!bundlerUrl) {
|
|
37
|
+
throw new Error("aa.bundlerUrl is required");
|
|
38
|
+
}
|
|
39
|
+
if (!paymasterPolicyId) {
|
|
40
|
+
throw new Error("aa.paymasterPolicyId is required");
|
|
41
|
+
}
|
|
42
|
+
const entryPoint = getEntryPoint("0.7");
|
|
43
|
+
const publicClient = createPublicClient({
|
|
44
|
+
chain,
|
|
45
|
+
transport: http(bundlerUrl),
|
|
46
|
+
});
|
|
47
|
+
// Adapt the EvmSigner to a viem LocalAccount so ZeroDev's validator
|
|
48
|
+
// can treat it as the owner. The adapter throws a clear error if
|
|
49
|
+
// `signer.signMessage` is missing (required for Kernel's UserOp sig).
|
|
50
|
+
const kernelOwner = evmSignerToKernelOwner(signer);
|
|
51
|
+
// ZeroDev's ECDSA validator is the signature scheme gating the Kernel
|
|
52
|
+
// account — owner signs, validator checks via ERC-1271.
|
|
53
|
+
const validator = await signerToEcdsaValidator(publicClient, {
|
|
54
|
+
signer: kernelOwner,
|
|
55
|
+
entryPoint,
|
|
56
|
+
kernelVersion: KERNEL_V3_1,
|
|
57
|
+
});
|
|
58
|
+
const account = await createKernelAccount(publicClient, {
|
|
59
|
+
plugins: { sudo: validator },
|
|
60
|
+
entryPoint,
|
|
61
|
+
kernelVersion: KERNEL_V3_1,
|
|
62
|
+
});
|
|
63
|
+
// Alchemy serves standard ERC-7677 paymaster methods
|
|
64
|
+
// (`pm_getPaymasterStubData` / `pm_getPaymasterData`) on the same app
|
|
65
|
+
// URL as the bundler. Passing the policy id via `paymasterContext`
|
|
66
|
+
// lets viem call both methods at the right points in the UserOp
|
|
67
|
+
// preparation flow (stub → gas estimate → final paymaster data).
|
|
68
|
+
const paymasterClient = createPaymasterClient({
|
|
69
|
+
transport: http(bundlerUrl),
|
|
70
|
+
});
|
|
71
|
+
const client = createKernelAccountClient({
|
|
72
|
+
account,
|
|
73
|
+
chain,
|
|
74
|
+
bundlerTransport: http(bundlerUrl),
|
|
75
|
+
paymaster: paymasterClient,
|
|
76
|
+
paymasterContext: { policyId: paymasterPolicyId },
|
|
77
|
+
userOperation: {
|
|
78
|
+
// ZeroDev's default fetcher calls `zd_getUserOperationGasPrice`,
|
|
79
|
+
// which Alchemy's bundler rejects. Use Alchemy's
|
|
80
|
+
// `rundler_maxPriorityFeePerGas` instead and combine with viem's
|
|
81
|
+
// base-fee estimate for maxFeePerGas. Falls back to a static
|
|
82
|
+
// floor (0.001 gwei) if the rundler method isn't available.
|
|
83
|
+
estimateFeesPerGas: async () => {
|
|
84
|
+
const STATIC_MIN_PRIORITY = 1000000n;
|
|
85
|
+
let maxPriorityFeePerGas = STATIC_MIN_PRIORITY;
|
|
86
|
+
try {
|
|
87
|
+
const resp = await fetch(bundlerUrl, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: { "Content-Type": "application/json" },
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
jsonrpc: "2.0",
|
|
92
|
+
id: 1,
|
|
93
|
+
method: "rundler_maxPriorityFeePerGas",
|
|
94
|
+
params: [],
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
const json = await resp.json();
|
|
98
|
+
if (typeof json.result === "string") {
|
|
99
|
+
const rundlerFee = BigInt(json.result);
|
|
100
|
+
maxPriorityFeePerGas =
|
|
101
|
+
rundlerFee > STATIC_MIN_PRIORITY
|
|
102
|
+
? rundlerFee
|
|
103
|
+
: STATIC_MIN_PRIORITY;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
/* fall through to static floor */
|
|
108
|
+
}
|
|
109
|
+
const baseFees = await publicClient.estimateFeesPerGas();
|
|
110
|
+
const maxFeePerGas = baseFees.maxFeePerGas + maxPriorityFeePerGas;
|
|
111
|
+
return { maxFeePerGas, maxPriorityFeePerGas };
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
return { client, account, accountAddress: account.address };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=smartAccount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smartAccount.js","sourceRoot":"","sources":["../../src/cctp-inbound/smartAccount.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `submitUserOp` — end-to-end UserOp submission for the CCTP-inbound
|
|
3
|
+
* settlement step. Composes:
|
|
4
|
+
*
|
|
5
|
+
* 1. Fetch HTLC/DEX calldata from the backend.
|
|
6
|
+
* 2. Build a Kernel smart-account client owned by the caller's signer.
|
|
7
|
+
* 3. Check the smart-account USDC balance; skip `receiveMessage` if
|
|
8
|
+
* funds already landed (retry-safe).
|
|
9
|
+
* 4. Compose the 3-call UserOp batch.
|
|
10
|
+
* 5. Send the UserOp via the bundler; optionally wait for the
|
|
11
|
+
* on-chain tx hash.
|
|
12
|
+
*
|
|
13
|
+
* The authoritative high-level primitive for a settlement — most
|
|
14
|
+
* consumers call this (or the even-higher-level `Client.fundSwap`).
|
|
15
|
+
*/
|
|
16
|
+
import type { Address, Chain, Hex } from "viem";
|
|
17
|
+
import type { ApiClient } from "../api/client.js";
|
|
18
|
+
import type { EvmSigner } from "../evm/wallet.js";
|
|
19
|
+
import type { AaConfig } from "./types.js";
|
|
20
|
+
export interface SubmitUserOpParams {
|
|
21
|
+
/** Swap ID assigned by the backend at create time. */
|
|
22
|
+
swapId: string;
|
|
23
|
+
/**
|
|
24
|
+
* Kernel smart-account owner as the SDK's `EvmSigner`. Requires
|
|
25
|
+
* `signer.signMessage` (optional on `EvmSigner`) — Kernel's validator
|
|
26
|
+
* signs the UserOp hash via it. Clear error thrown if missing.
|
|
27
|
+
*/
|
|
28
|
+
signer: EvmSigner;
|
|
29
|
+
/** Raw IRIS message bytes (hex, 0x-prefixed). */
|
|
30
|
+
cctpMessage: Hex;
|
|
31
|
+
/** Raw IRIS attestation bytes (hex, 0x-prefixed). */
|
|
32
|
+
cctpAttestation: Hex;
|
|
33
|
+
/**
|
|
34
|
+
* Settlement chain. Defaults to Arbitrum mainnet — the only
|
|
35
|
+
* supported chain today, parameterised for future extension.
|
|
36
|
+
*/
|
|
37
|
+
chain?: Chain;
|
|
38
|
+
/** Return immediately after submission without waiting for receipt. */
|
|
39
|
+
noWait?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* When `true`, run each batched call individually via `eth_call`
|
|
42
|
+
* before submission and log per-call status to the console. Useful
|
|
43
|
+
* for iterating on ABI / calldata issues — bundler reverts are
|
|
44
|
+
* aggregated and often opaque. Never throws; the bundler's real
|
|
45
|
+
* simulation on `sendUserOperation` remains the authoritative check.
|
|
46
|
+
*/
|
|
47
|
+
preflightSimulate?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface SubmitUserOpResult {
|
|
50
|
+
/** Bundler-assigned UserOperation hash. */
|
|
51
|
+
userOpHash: Hex;
|
|
52
|
+
/** Deterministic smart-account address (owned by `signer`). */
|
|
53
|
+
smartAccountAddress: Address;
|
|
54
|
+
/**
|
|
55
|
+
* On-chain transaction hash for the bundle containing this UserOp.
|
|
56
|
+
* Populated when `noWait !== true` — omitted when the caller opts
|
|
57
|
+
* out of waiting.
|
|
58
|
+
*/
|
|
59
|
+
transactionHash?: Hex;
|
|
60
|
+
}
|
|
61
|
+
/** Inputs needed from the `CctpInboundClient` to execute a submission. */
|
|
62
|
+
export interface SubmitUserOpContext {
|
|
63
|
+
apiClient: ApiClient;
|
|
64
|
+
aa: AaConfig;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Execute the full CCTP-inbound settlement UserOp for a swap.
|
|
68
|
+
*
|
|
69
|
+
* This is intentionally a free function rather than a
|
|
70
|
+
* `CctpInboundClient` method — the client exposes a thin wrapper that
|
|
71
|
+
* injects its own state; tests and advanced consumers can call the
|
|
72
|
+
* free function directly with a custom `SubmitUserOpContext`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function submitCctpInboundUserOp(context: SubmitUserOpContext, params: SubmitUserOpParams): Promise<SubmitUserOpResult>;
|
|
75
|
+
//# sourceMappingURL=submit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/cctp-inbound/submit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAGhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmC3C,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,EAAE,SAAS,CAAC;IAClB,iDAAiD;IACjD,WAAW,EAAE,GAAG,CAAC;IACjB,qDAAqD;IACrD,eAAe,EAAE,GAAG,CAAC;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,UAAU,EAAE,GAAG,CAAC;IAChB,+DAA+D;IAC/D,mBAAmB,EAAE,OAAO,CAAC;IAC7B;;;;OAIG;IACH,eAAe,CAAC,EAAE,GAAG,CAAC;CACvB;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,EAAE,EAAE,QAAQ,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CA+F7B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `submitUserOp` — end-to-end UserOp submission for the CCTP-inbound
|
|
3
|
+
* settlement step. Composes:
|
|
4
|
+
*
|
|
5
|
+
* 1. Fetch HTLC/DEX calldata from the backend.
|
|
6
|
+
* 2. Build a Kernel smart-account client owned by the caller's signer.
|
|
7
|
+
* 3. Check the smart-account USDC balance; skip `receiveMessage` if
|
|
8
|
+
* funds already landed (retry-safe).
|
|
9
|
+
* 4. Compose the 3-call UserOp batch.
|
|
10
|
+
* 5. Send the UserOp via the bundler; optionally wait for the
|
|
11
|
+
* on-chain tx hash.
|
|
12
|
+
*
|
|
13
|
+
* The authoritative high-level primitive for a settlement — most
|
|
14
|
+
* consumers call this (or the even-higher-level `Client.fundSwap`).
|
|
15
|
+
*/
|
|
16
|
+
import { createPublicClient, http } from "viem";
|
|
17
|
+
import { arbitrum } from "viem/chains";
|
|
18
|
+
import { MESSAGE_TRANSMITTER_V2 } from "../cctp/constants.js";
|
|
19
|
+
import { simulateBatchCalls } from "./preflight.js";
|
|
20
|
+
import { createSwapSmartAccountClient } from "./smartAccount.js";
|
|
21
|
+
import { buildCctpInboundBatch, } from "./userOp.js";
|
|
22
|
+
/**
|
|
23
|
+
* CCTPv2 burn/mint message layout (see Circle's `MessageTransmitterV2`):
|
|
24
|
+
*
|
|
25
|
+
* offset size field
|
|
26
|
+
* 0 4 version
|
|
27
|
+
* 4 4 sourceDomain
|
|
28
|
+
* 8 4 destinationDomain
|
|
29
|
+
* 12 32 nonce <-- what we extract
|
|
30
|
+
* 44 32 sender
|
|
31
|
+
* ...
|
|
32
|
+
*
|
|
33
|
+
* Hex-string offsets include the "0x" prefix and 2 chars per byte, so the
|
|
34
|
+
* nonce sits at chars [26, 90).
|
|
35
|
+
*/
|
|
36
|
+
function extractNonce(cctpMessage) {
|
|
37
|
+
return `0x${cctpMessage.slice(26, 26 + 64)}`;
|
|
38
|
+
}
|
|
39
|
+
/** `MessageTransmitterV2.usedNonces(bytes32)` — returns 0 if unused. */
|
|
40
|
+
const USED_NONCES_ABI = [
|
|
41
|
+
{
|
|
42
|
+
type: "function",
|
|
43
|
+
name: "usedNonces",
|
|
44
|
+
stateMutability: "view",
|
|
45
|
+
inputs: [{ name: "nonce", type: "bytes32" }],
|
|
46
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Execute the full CCTP-inbound settlement UserOp for a swap.
|
|
51
|
+
*
|
|
52
|
+
* This is intentionally a free function rather than a
|
|
53
|
+
* `CctpInboundClient` method — the client exposes a thin wrapper that
|
|
54
|
+
* injects its own state; tests and advanced consumers can call the
|
|
55
|
+
* free function directly with a custom `SubmitUserOpContext`.
|
|
56
|
+
*/
|
|
57
|
+
export async function submitCctpInboundUserOp(context, params) {
|
|
58
|
+
const { apiClient, aa } = context;
|
|
59
|
+
const { swapId, signer, cctpMessage, cctpAttestation, chain = arbitrum, noWait, preflightSimulate, } = params;
|
|
60
|
+
// 1. Fetch the HTLC/DEX calldata the backend built for this swap.
|
|
61
|
+
const { data, error } = await apiClient.GET("/swap/{id}/swap-and-lock-calldata-userop", { params: { path: { id: swapId } } });
|
|
62
|
+
if (error || !data) {
|
|
63
|
+
throw new Error(`Failed to fetch CCTP-inbound calldata for swap ${swapId}: ${JSON.stringify(error)}`);
|
|
64
|
+
}
|
|
65
|
+
const server = data;
|
|
66
|
+
// 2. Derive the Kernel client + the smart-account address.
|
|
67
|
+
const { client: aaClient, account: smartAccount, accountAddress, } = await createSwapSmartAccountClient({ signer, aa, chain });
|
|
68
|
+
// 3. Decide whether to include `receiveMessage` in the batch, based on
|
|
69
|
+
// whether *this specific burn's nonce* has already been consumed by
|
|
70
|
+
// MessageTransmitter. A prior balance-based heuristic here was
|
|
71
|
+
// unsafe: any USDC that happened to be at the smart-account address
|
|
72
|
+
// (residual from a partial prior attempt, a direct transfer, …) made
|
|
73
|
+
// it skip `receiveMessage` even if the current burn was still
|
|
74
|
+
// unminted, stranding the fresh funds. Nonce consumption is the
|
|
75
|
+
// authoritative signal — `MessageTransmitter.usedNonces(nonce)`
|
|
76
|
+
// returns non-zero iff the mint for *this* message has landed.
|
|
77
|
+
// Reuses the bundler URL as the node RPC (Alchemy serves both).
|
|
78
|
+
const publicClient = createPublicClient({
|
|
79
|
+
chain,
|
|
80
|
+
transport: http(aa.bundlerUrl),
|
|
81
|
+
});
|
|
82
|
+
const nonce = extractNonce(cctpMessage);
|
|
83
|
+
const usedNonce = (await publicClient.readContract({
|
|
84
|
+
address: MESSAGE_TRANSMITTER_V2,
|
|
85
|
+
abi: USED_NONCES_ABI,
|
|
86
|
+
functionName: "usedNonces",
|
|
87
|
+
args: [nonce],
|
|
88
|
+
}));
|
|
89
|
+
const skipReceiveMessage = usedNonce !== 0n;
|
|
90
|
+
// 4. Compose the 3-call batch (receiveMessage + approve + HTLC create).
|
|
91
|
+
const { calls } = await buildCctpInboundBatch({
|
|
92
|
+
server,
|
|
93
|
+
smartAccountAddress: accountAddress,
|
|
94
|
+
signTypedData: (args) => smartAccount.signTypedData(args),
|
|
95
|
+
cctpMessage,
|
|
96
|
+
cctpAttestation,
|
|
97
|
+
chainId: chain.id,
|
|
98
|
+
skipReceiveMessage,
|
|
99
|
+
});
|
|
100
|
+
// 5. Optional debug pre-flight: per-call `eth_call` with the smart
|
|
101
|
+
// account as `from`, logging per-call status. The bundler's
|
|
102
|
+
// full simulation at `sendUserOperation` is the authoritative
|
|
103
|
+
// check — this is purely for observability while iterating.
|
|
104
|
+
if (preflightSimulate) {
|
|
105
|
+
await simulateBatchCalls({
|
|
106
|
+
calls,
|
|
107
|
+
smartAccount: accountAddress,
|
|
108
|
+
publicClient,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// 6. Send the UserOp via the bundler. Paymaster sponsorship is wired
|
|
112
|
+
// into the Kernel client already, so no gas is owed by the caller.
|
|
113
|
+
const userOpHash = await aaClient.sendUserOperation({ calls });
|
|
114
|
+
if (noWait) {
|
|
115
|
+
return { userOpHash, smartAccountAddress: accountAddress };
|
|
116
|
+
}
|
|
117
|
+
const receipt = await aaClient.waitForUserOperationReceipt({
|
|
118
|
+
hash: userOpHash,
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
userOpHash,
|
|
122
|
+
smartAccountAddress: accountAddress,
|
|
123
|
+
transactionHash: receipt.receipt?.transactionHash,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=submit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../../src/cctp-inbound/submit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the CCTP-inbound flow.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Account-abstraction configuration for the CCTP-inbound path.
|
|
6
|
+
*
|
|
7
|
+
* The CCTP-inbound flow requires an ERC-4337 bundler and paymaster to
|
|
8
|
+
* fund the `receiveMessage + approve + HTLC-create` UserOp atomically
|
|
9
|
+
* on the settlement chain (Arbitrum). The user's connected wallet owns
|
|
10
|
+
* the Kernel smart account; the SDK just wires the plumbing.
|
|
11
|
+
*
|
|
12
|
+
* All URLs point to the same Alchemy app (bundler and Gas Manager share
|
|
13
|
+
* a base URL); the policy id is passed via ERC-7677 paymaster context.
|
|
14
|
+
*/
|
|
15
|
+
export interface AaConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Bundler JSON-RPC URL (also serves as the paymaster URL for Alchemy
|
|
18
|
+
* Gas Manager via ERC-7677 `pm_*` methods).
|
|
19
|
+
*
|
|
20
|
+
* @example `https://arb-mainnet.g.alchemy.com/v2/<API_KEY>`
|
|
21
|
+
*/
|
|
22
|
+
bundlerUrl: string;
|
|
23
|
+
/**
|
|
24
|
+
* Alchemy Gas Manager policy id (UUID). Passed to the paymaster RPC
|
|
25
|
+
* via the ERC-7677 context object so the bundler knows which policy
|
|
26
|
+
* is sponsoring this UserOp.
|
|
27
|
+
*/
|
|
28
|
+
paymasterPolicyId: string;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cctp-inbound/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cctp-inbound/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compose the `executeBatch` calldata for a CCTP-inbound UserOperation.
|
|
3
|
+
*
|
|
4
|
+
* The smart account's batch atomically runs:
|
|
5
|
+
* 1. `MessageTransmitter.receiveMessage(message, attestation)` — mints
|
|
6
|
+
* USDC to the smart account.
|
|
7
|
+
* 2. `USDC.approve(Permit2, max)` — idempotent.
|
|
8
|
+
* 3. `HTLCCoordinator.executeAndCreateWithPermit2(...)` — uses an
|
|
9
|
+
* ERC-1271 signature from the smart account as `depositor`.
|
|
10
|
+
*
|
|
11
|
+
* All three calls execute with `msg.sender = smartAccount`, so CCTPv2's
|
|
12
|
+
* `destinationCaller` gate (pinned to the same address on the burn) is
|
|
13
|
+
* satisfied.
|
|
14
|
+
*/
|
|
15
|
+
import type { Address, Hex } from "viem";
|
|
16
|
+
/**
|
|
17
|
+
* Shape returned by the backend's
|
|
18
|
+
* `GET /v1/swap/:id/swap-and-lock-calldata-userop` endpoint.
|
|
19
|
+
* Field names match the REST JSON (snake_case).
|
|
20
|
+
*/
|
|
21
|
+
export interface UseropCalldataResponse {
|
|
22
|
+
coordinator_address: string;
|
|
23
|
+
permit2_address: string;
|
|
24
|
+
source_token_address: string;
|
|
25
|
+
source_amount: string;
|
|
26
|
+
lock_token_address: string;
|
|
27
|
+
preimage_hash: string;
|
|
28
|
+
claim_address: string;
|
|
29
|
+
timelock: number;
|
|
30
|
+
calls: Array<{
|
|
31
|
+
target: string;
|
|
32
|
+
value: string;
|
|
33
|
+
call_data: string;
|
|
34
|
+
}>;
|
|
35
|
+
calls_hash: string;
|
|
36
|
+
relay_fee?: string;
|
|
37
|
+
aa: {
|
|
38
|
+
entry_point: string;
|
|
39
|
+
account_factory: string;
|
|
40
|
+
account_impl: string;
|
|
41
|
+
salt: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Sign arbitrary EIP-712 typed data with the smart account.
|
|
46
|
+
*
|
|
47
|
+
* For Kernel this wraps the hash with its "message marker" before
|
|
48
|
+
* ecrecover, so the resulting sig passes ERC-1271 verification on the
|
|
49
|
+
* deployed account. Pass `kernelAccount.signTypedData` directly.
|
|
50
|
+
*/
|
|
51
|
+
export type SignTypedDataFn = (args: any) => Promise<Hex>;
|
|
52
|
+
export interface BuildCctpInboundBatchParams {
|
|
53
|
+
/** Calldata payload from the backend. */
|
|
54
|
+
server: UseropCalldataResponse;
|
|
55
|
+
/** Deterministic smart-account address that owns the HTLC deposit. */
|
|
56
|
+
smartAccountAddress: Address;
|
|
57
|
+
/** Produces an ERC-1271-compatible Permit2 signature via the smart account. */
|
|
58
|
+
signTypedData: SignTypedDataFn;
|
|
59
|
+
/** Raw IRIS message bytes (hex, 0x-prefixed). */
|
|
60
|
+
cctpMessage: Hex;
|
|
61
|
+
/** Raw IRIS attestation bytes (hex, 0x-prefixed). */
|
|
62
|
+
cctpAttestation: Hex;
|
|
63
|
+
/** Settlement chain id — used as the Permit2 domain chain id. */
|
|
64
|
+
chainId: number;
|
|
65
|
+
/** Whether USDC is already at `smartAccountAddress` (skip receiveMessage). */
|
|
66
|
+
skipReceiveMessage?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/** A single (target, data, value) call the smart account will execute. */
|
|
69
|
+
export interface BatchCall {
|
|
70
|
+
to: Address;
|
|
71
|
+
data: Hex;
|
|
72
|
+
value: bigint;
|
|
73
|
+
}
|
|
74
|
+
export interface BuiltBatch {
|
|
75
|
+
calls: BatchCall[];
|
|
76
|
+
/** The Permit2 nonce used in the witness; useful to log / surface. */
|
|
77
|
+
permit2Nonce: bigint;
|
|
78
|
+
/** Deadline embedded in the Permit2 signature (unix seconds). */
|
|
79
|
+
permit2Deadline: bigint;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns the list of calls the smart account's `executeBatch` will run.
|
|
83
|
+
* The Permit2 signature is produced via the Kernel smart account's
|
|
84
|
+
* `signTypedData` — Kernel wraps the hash before signing so the sig
|
|
85
|
+
* passes its own ERC-1271 verification once the account is deployed.
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildCctpInboundBatch(params: BuildCctpInboundBatchParams): Promise<BuiltBatch>;
|
|
88
|
+
/**
|
|
89
|
+
* Convert an EVM address (20 bytes) into the bytes32 form CCTPv2's
|
|
90
|
+
* `depositForBurn` expects for `mintRecipient` and `destinationCaller`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function addressToBytes32Hex(address: Address): Hex;
|
|
93
|
+
//# sourceMappingURL=userOp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userOp.d.ts","sourceRoot":"","sources":["../../src/cctp-inbound/userOp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAmB,MAAM,MAAM,CAAC;AAiC1D;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE;QACF,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;;;;GAMG;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAE1D,MAAM,WAAW,2BAA2B;IAC1C,yCAAyC;IACzC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,sEAAsE;IACtE,mBAAmB,EAAE,OAAO,CAAC;IAC7B,+EAA+E;IAC/E,aAAa,EAAE,eAAe,CAAC;IAC/B,iDAAiD;IACjD,WAAW,EAAE,GAAG,CAAC;IACjB,qDAAqD;IACrD,eAAe,EAAE,GAAG,CAAC;IACrB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,0EAA0E;AAC1E,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,UAAU,CAAC,CA4HrB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAEzD"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compose the `executeBatch` calldata for a CCTP-inbound UserOperation.
|
|
3
|
+
*
|
|
4
|
+
* The smart account's batch atomically runs:
|
|
5
|
+
* 1. `MessageTransmitter.receiveMessage(message, attestation)` — mints
|
|
6
|
+
* USDC to the smart account.
|
|
7
|
+
* 2. `USDC.approve(Permit2, max)` — idempotent.
|
|
8
|
+
* 3. `HTLCCoordinator.executeAndCreateWithPermit2(...)` — uses an
|
|
9
|
+
* ERC-1271 signature from the smart account as `depositor`.
|
|
10
|
+
*
|
|
11
|
+
* All three calls execute with `msg.sender = smartAccount`, so CCTPv2's
|
|
12
|
+
* `destinationCaller` gate (pinned to the same address on the burn) is
|
|
13
|
+
* satisfied.
|
|
14
|
+
*/
|
|
15
|
+
import { encodeAbiParameters, encodeFunctionData, isErc6492Signature, maxUint256, parseAbi, parseErc6492Signature, } from "viem";
|
|
16
|
+
import { buildPermit2TypedData } from "../evm/coordinator.js";
|
|
17
|
+
/** MessageTransmitter v2 — same on every CCTPv2 EVM chain. */
|
|
18
|
+
const MESSAGE_TRANSMITTER_V2 = "0x81D40F21F12A8F0E3252Bccb954D722d4c464B64";
|
|
19
|
+
/** Canonical Permit2 deployment — same on all EVM chains. */
|
|
20
|
+
const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
21
|
+
const MESSAGE_TRANSMITTER_ABI = parseAbi([
|
|
22
|
+
"function receiveMessage(bytes message, bytes attestation) external returns (bool)",
|
|
23
|
+
]);
|
|
24
|
+
const ERC20_APPROVE_ABI = parseAbi([
|
|
25
|
+
"function approve(address spender, uint256 amount) external returns (bool)",
|
|
26
|
+
]);
|
|
27
|
+
const HTLC_COORDINATOR_ABI = parseAbi([
|
|
28
|
+
"struct TokenPermissions { address token; uint256 amount; }",
|
|
29
|
+
"struct PermitTransferFrom { TokenPermissions permitted; uint256 nonce; uint256 deadline; }",
|
|
30
|
+
"struct Call { address target; uint256 value; bytes callData; }",
|
|
31
|
+
"function executeAndCreateWithPermit2(Call[] calls, bytes32 preimageHash, address token, address claimAddress, uint256 timelock, address depositor, PermitTransferFrom permit, bytes signature) external",
|
|
32
|
+
]);
|
|
33
|
+
/**
|
|
34
|
+
* Returns the list of calls the smart account's `executeBatch` will run.
|
|
35
|
+
* The Permit2 signature is produced via the Kernel smart account's
|
|
36
|
+
* `signTypedData` — Kernel wraps the hash before signing so the sig
|
|
37
|
+
* passes its own ERC-1271 verification once the account is deployed.
|
|
38
|
+
*/
|
|
39
|
+
export async function buildCctpInboundBatch(params) {
|
|
40
|
+
const { server, smartAccountAddress, signTypedData, cctpMessage, cctpAttestation, chainId, skipReceiveMessage, } = params;
|
|
41
|
+
const calls = [];
|
|
42
|
+
// 1. receiveMessage — skip if USDC already landed (front-runner / retry).
|
|
43
|
+
if (!skipReceiveMessage) {
|
|
44
|
+
const receiveMessageData = encodeFunctionData({
|
|
45
|
+
abi: MESSAGE_TRANSMITTER_ABI,
|
|
46
|
+
functionName: "receiveMessage",
|
|
47
|
+
args: [cctpMessage, cctpAttestation],
|
|
48
|
+
});
|
|
49
|
+
calls.push({
|
|
50
|
+
to: MESSAGE_TRANSMITTER_V2,
|
|
51
|
+
data: receiveMessageData,
|
|
52
|
+
value: 0n,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// 2. USDC.approve(Permit2, max) — idempotent; lets Permit2 pull from us.
|
|
56
|
+
const approveData = encodeFunctionData({
|
|
57
|
+
abi: ERC20_APPROVE_ABI,
|
|
58
|
+
functionName: "approve",
|
|
59
|
+
args: [PERMIT2_ADDRESS, maxUint256],
|
|
60
|
+
});
|
|
61
|
+
calls.push({
|
|
62
|
+
to: server.source_token_address,
|
|
63
|
+
data: approveData,
|
|
64
|
+
value: 0n,
|
|
65
|
+
});
|
|
66
|
+
// 3. Permit2 witness signature, produced via the smart account.
|
|
67
|
+
// Kernel's signTypedData applies its message-marker wrap so the
|
|
68
|
+
// resulting sig passes ERC-1271 when Permit2 calls back into the
|
|
69
|
+
// (by then-deployed) account.
|
|
70
|
+
const nonceBytes = new Uint8Array(32);
|
|
71
|
+
crypto.getRandomValues(nonceBytes);
|
|
72
|
+
const permit2Nonce = BigInt(`0x${Array.from(nonceBytes)
|
|
73
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
74
|
+
.join("")}`);
|
|
75
|
+
const permit2Deadline = BigInt(Math.floor(Date.now() / 1000) + 30 * 60);
|
|
76
|
+
const sourceAmount = BigInt(server.source_amount);
|
|
77
|
+
const typedData = buildPermit2TypedData({
|
|
78
|
+
chainId,
|
|
79
|
+
coordinatorAddress: server.coordinator_address,
|
|
80
|
+
sourceToken: server.source_token_address,
|
|
81
|
+
sourceAmount,
|
|
82
|
+
preimageHash: server.preimage_hash,
|
|
83
|
+
lockToken: server.lock_token_address,
|
|
84
|
+
claimAddress: server.claim_address,
|
|
85
|
+
refundAddress: server.coordinator_address,
|
|
86
|
+
timelock: server.timelock,
|
|
87
|
+
callsHash: server.calls_hash,
|
|
88
|
+
nonce: permit2Nonce,
|
|
89
|
+
deadline: permit2Deadline,
|
|
90
|
+
});
|
|
91
|
+
const rawSignature = (await signTypedData({
|
|
92
|
+
domain: typedData.domain,
|
|
93
|
+
types: typedData.types,
|
|
94
|
+
primaryType: typedData.primaryType,
|
|
95
|
+
message: typedData.message,
|
|
96
|
+
}));
|
|
97
|
+
// viem's `toSmartAccount` auto-wraps `signTypedData` output in ERC-6492
|
|
98
|
+
// whenever the account's factory/factoryData are non-empty. Permit2 is
|
|
99
|
+
// not ERC-6492-aware, so strip the wrapper and pass the raw Kernel
|
|
100
|
+
// signature. The account will be deployed by factoryData during the
|
|
101
|
+
// UserOp *before* Permit2 verifies, so Permit2 takes the ERC-1271
|
|
102
|
+
// path and Kernel's `isValidSignature` accepts the raw sig.
|
|
103
|
+
const permit2Signature = isErc6492Signature(rawSignature)
|
|
104
|
+
? parseErc6492Signature(rawSignature).signature
|
|
105
|
+
: rawSignature;
|
|
106
|
+
// 4. executeAndCreateWithPermit2
|
|
107
|
+
const dexCalls = server.calls.map((c) => ({
|
|
108
|
+
target: c.target,
|
|
109
|
+
value: BigInt(c.value),
|
|
110
|
+
callData: c.call_data,
|
|
111
|
+
}));
|
|
112
|
+
const executeData = encodeFunctionData({
|
|
113
|
+
abi: HTLC_COORDINATOR_ABI,
|
|
114
|
+
functionName: "executeAndCreateWithPermit2",
|
|
115
|
+
args: [
|
|
116
|
+
dexCalls,
|
|
117
|
+
server.preimage_hash,
|
|
118
|
+
server.lock_token_address,
|
|
119
|
+
server.claim_address,
|
|
120
|
+
BigInt(server.timelock),
|
|
121
|
+
smartAccountAddress,
|
|
122
|
+
{
|
|
123
|
+
permitted: {
|
|
124
|
+
token: server.source_token_address,
|
|
125
|
+
amount: sourceAmount,
|
|
126
|
+
},
|
|
127
|
+
nonce: permit2Nonce,
|
|
128
|
+
deadline: permit2Deadline,
|
|
129
|
+
},
|
|
130
|
+
permit2Signature,
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
calls.push({
|
|
134
|
+
to: server.coordinator_address,
|
|
135
|
+
data: executeData,
|
|
136
|
+
value: 0n,
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
calls,
|
|
140
|
+
permit2Nonce,
|
|
141
|
+
permit2Deadline,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Convert an EVM address (20 bytes) into the bytes32 form CCTPv2's
|
|
146
|
+
* `depositForBurn` expects for `mintRecipient` and `destinationCaller`.
|
|
147
|
+
*/
|
|
148
|
+
export function addressToBytes32Hex(address) {
|
|
149
|
+
return encodeAbiParameters([{ type: "address" }], [address]);
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=userOp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userOp.js","sourceRoot":"","sources":["../../src/cctp-inbound/userOp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,QAAQ,EACR,qBAAqB,GACtB,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,8DAA8D;AAC9D,MAAM,sBAAsB,GAC1B,4CAAqD,CAAC;AAExD,6DAA6D;AAC7D,MAAM,eAAe,GAAG,4CAAqD,CAAC;AAE9E,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IACvC,mFAAmF;CACpF,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACjC,2EAA2E;CAC5E,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IACpC,4DAA4D;IAC5D,4FAA4F;IAC5F,gEAAgE;IAChE,yMAAyM;CAC1M,CAAC,CAAC;AAqEH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAmC;IAEnC,MAAM,EACJ,MAAM,EACN,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,eAAe,EACf,OAAO,EACP,kBAAkB,GACnB,GAAG,MAAM,CAAC;IAEX,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,0EAA0E;IAC1E,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;YAC5C,GAAG,EAAE,uBAAuB;YAC5B,YAAY,EAAE,gBAAgB;YAC9B,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC;SACrC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,sBAAiC;YACrC,IAAI,EAAE,kBAAkB;YACxB,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,MAAM,WAAW,GAAG,kBAAkB,CAAC;QACrC,GAAG,EAAE,iBAAiB;QACtB,YAAY,EAAE,SAAS;QACvB,IAAI,EAAE,CAAC,eAA0B,EAAE,UAAU,CAAC;KAC/C,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,MAAM,CAAC,oBAA+B;QAC1C,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,EAAE;KACV,CAAC,CAAC;IAEH,gEAAgE;IAChE,mEAAmE;IACnE,oEAAoE;IACpE,iCAAiC;IACjC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACtC,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,MAAM,CACzB,KAAK,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,EAAE,CACd,CAAC;IACF,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAElD,MAAM,SAAS,GAAG,qBAAqB,CAAC;QACtC,OAAO;QACP,kBAAkB,EAAE,MAAM,CAAC,mBAAmB;QAC9C,WAAW,EAAE,MAAM,CAAC,oBAAoB;QACxC,YAAY;QACZ,YAAY,EAAE,MAAM,CAAC,aAAa;QAClC,SAAS,EAAE,MAAM,CAAC,kBAAkB;QACpC,YAAY,EAAE,MAAM,CAAC,aAAa;QAClC,aAAa,EAAE,MAAM,CAAC,mBAAmB;QACzC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,UAAU;QAC5B,KAAK,EAAE,YAAY;QACnB,QAAQ,EAAE,eAAe;KAC1B,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,CAAC,MAAM,aAAa,CAAC;QACxC,MAAM,EAAE,SAAS,CAAC,MAAyB;QAC3C,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,OAAO,EAAE,SAAS,CAAC,OAAO;KAC3B,CAAC,CAAQ,CAAC;IAEX,wEAAwE;IACxE,uEAAuE;IACvE,mEAAmE;IACnE,oEAAoE;IACpE,kEAAkE;IAClE,4DAA4D;IAC5D,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,YAAY,CAAC;QACvD,CAAC,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,SAAS;QAC/C,CAAC,CAAC,YAAY,CAAC;IAEjB,iCAAiC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,EAAE,CAAC,CAAC,MAAiB;QAC3B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACtB,QAAQ,EAAE,CAAC,CAAC,SAAgB;KAC7B,CAAC,CAAC,CAAC;IAEJ,MAAM,WAAW,GAAG,kBAAkB,CAAC;QACrC,GAAG,EAAE,oBAAoB;QACzB,YAAY,EAAE,6BAA6B;QAC3C,IAAI,EAAE;YACJ,QAAQ;YACR,MAAM,CAAC,aAAoB;YAC3B,MAAM,CAAC,kBAA6B;YACpC,MAAM,CAAC,aAAwB;YAC/B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;YACvB,mBAAmB;YACnB;gBACE,SAAS,EAAE;oBACT,KAAK,EAAE,MAAM,CAAC,oBAA+B;oBAC7C,MAAM,EAAE,YAAY;iBACrB;gBACD,KAAK,EAAE,YAAY;gBACnB,QAAQ,EAAE,eAAe;aAC1B;YACD,gBAAgB;SACjB;KACF,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,MAAM,CAAC,mBAA8B;QACzC,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,EAAE;KACV,CAAC,CAAC;IAEH,OAAO;QACL,KAAK;QACL,YAAY;QACZ,eAAe;KAChB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAQ,CAAC;AACtE,CAAC"}
|