@rareprotocol/rare-cli 1.1.0 → 1.2.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/dist/client.js CHANGED
@@ -17,6 +17,7 @@ var contractAddresses = {
17
17
  sepolia: {
18
18
  factory: getAddress("0x3c7526a0975156299ceef369b8ff3c01cc670523"),
19
19
  auction: getAddress("0xC8Edc7049b233641ad3723D6C60019D1c8771612"),
20
+ rareBridge: getAddress("0xdC168291658f6C5F1D0b33E573c4d289DCA9dD08"),
20
21
  sovereignFactory: getAddress("0x46B2850ba7787734F648A6848b5eDE0815C1F8Bf"),
21
22
  lazySovereignFactory: getAddress("0xc5B8Ad9003673a23d005A6448C74d8955a1a38fA"),
22
23
  rareMinter: getAddress("0xd28Dc0B89104d7BBd902F338a0193fF063617ccE"),
@@ -34,6 +35,7 @@ var contractAddresses = {
34
35
  mainnet: {
35
36
  factory: getAddress("0xAe8E375a268Ed6442bEaC66C6254d6De5AeD4aB1"),
36
37
  auction: getAddress("0x6D7c44773C52D396F43c2D511B81aa168E9a7a42"),
38
+ rareBridge: getAddress("0x88135dd0e7a8a2e42272dda89849a997ce2e83f7"),
37
39
  sovereignFactory: getAddress("0xe980ec62378529d95ba446433f4deb6324129c59"),
38
40
  lazySovereignFactory: getAddress("0xba798BD606d86D207ca2751510173532899117a1"),
39
41
  rareMinter: getAddress("0x5fa112EFeD8297bec0010b312208d223E0cE891E"),
@@ -44,19 +46,27 @@ var contractAddresses = {
44
46
  marketplaceSettings: getAddress("0x61DBF87164d33FD3695256DC8Ba74D3B1d304170"),
45
47
  erc20ApprovalManager: getAddress("0xa837a7eAff154Ab837617Cf7250648D3Ec0A4436"),
46
48
  erc721ApprovalManager: getAddress("0x4bb0Deea6d1A30C601338aAB776d394C2AE5c0F8"),
47
- liquidFactory: getAddress("0xbb4341CFd588a098e9aCE1D224178836426c4a8E"),
49
+ liquidFactory: getAddress("0x25f993C222fE5e891128a782A5168f1C78629540"),
48
50
  swapRouter: getAddress("0xEBd58EdA8408d9EA409f2c2bE8898BD9738f3583"),
49
51
  v4Quoter: getAddress("0x52F0E24D1c21C8A0cB1e5a5dD6198556BD9E1203")
50
52
  },
51
53
  base: {
52
54
  factory: getAddress("0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd"),
53
- auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2")
55
+ auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2"),
56
+ rareBridge: getAddress("0x3b41e21094611d152a08d3691a70837f1a077dae")
54
57
  },
55
58
  "base-sepolia": {
56
59
  factory: getAddress("0x2b181ae0f1aea6fed75591b04991b1a3f9868d51"),
57
- auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2")
60
+ auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2"),
61
+ rareBridge: getAddress("0xca491bb62A7730E97F500510132C47633DDD0229")
58
62
  }
59
63
  };
64
+ var ccipChainSelectors = {
65
+ mainnet: 5009297550715157269n,
66
+ sepolia: 16015286601757825753n,
67
+ base: 15971525489660198786n,
68
+ "base-sepolia": 10344971235874465080n
69
+ };
60
70
  var canonicalV4Pools = {
61
71
  sepolia: {
62
72
  rareEthPool: {
@@ -206,6 +216,16 @@ function getCanonicalV4Pools(chain) {
206
216
  }
207
217
  return pools;
208
218
  }
219
+ function getRareBridgeAddress(chain) {
220
+ const address = getContractAddresses(chain).rareBridge;
221
+ if (!address) {
222
+ throw new Error(`RareBridge is not configured on "${chain}". Supported RareBridge chains: mainnet, sepolia, base, base-sepolia.`);
223
+ }
224
+ return address;
225
+ }
226
+ function getCcipChainSelector(chain) {
227
+ return ccipChainSelectors[chain];
228
+ }
209
229
  function isSupportedChain(value) {
210
230
  return supportedChains.some((chain) => chain === value);
211
231
  }
@@ -248,8 +268,12 @@ var RareApiError = class extends Error {
248
268
 
249
269
  // src/data-access/base-url.ts
250
270
  var DEFAULT_RARE_API_BASE_URL = "https://api.superrare.com";
271
+ function normalizeRareApiBaseUrlCandidate(baseUrl) {
272
+ const trimmedBaseUrl = baseUrl?.trim();
273
+ return trimmedBaseUrl === "" ? void 0 : trimmedBaseUrl;
274
+ }
251
275
  function resolveRareApiBaseUrl(baseUrl) {
252
- return process.env.RARE_API_BASE_URL ?? baseUrl ?? DEFAULT_RARE_API_BASE_URL;
276
+ return normalizeRareApiBaseUrlCandidate(process.env.RARE_API_BASE_URL) ?? normalizeRareApiBaseUrlCandidate(baseUrl) ?? DEFAULT_RARE_API_BASE_URL;
253
277
  }
254
278
 
255
279
  // src/data-access/client.ts
@@ -3481,6 +3505,50 @@ var auctionAbi = [
3481
3505
  ];
3482
3506
 
3483
3507
  // src/sdk/approvals-shell.ts
3508
+ var ApprovalSideEffectError = class extends Error {
3509
+ operation;
3510
+ approvals;
3511
+ constructor(params) {
3512
+ super(
3513
+ `${approvalSummary(params.approvals)} before ${params.operation}, but ${params.operation} did not complete. The approval remains valid; retry the operation or revoke approval if it should not remain active.`,
3514
+ { cause: params.cause }
3515
+ );
3516
+ this.name = "ApprovalSideEffectError";
3517
+ this.operation = params.operation;
3518
+ this.approvals = params.approvals;
3519
+ }
3520
+ };
3521
+ async function runWithApprovalSideEffectAlert(params) {
3522
+ try {
3523
+ return await params.run();
3524
+ } catch (error) {
3525
+ const approvals = params.approvals.filter(hasApprovalTxHash);
3526
+ if (approvals.length === 0) {
3527
+ throw error;
3528
+ }
3529
+ throw new ApprovalSideEffectError({
3530
+ operation: params.operation,
3531
+ approvals,
3532
+ cause: error
3533
+ });
3534
+ }
3535
+ }
3536
+ function hasApprovalTxHash(approval) {
3537
+ return approval.approvalTxHash !== void 0;
3538
+ }
3539
+ function approvalSummary(approvals) {
3540
+ const [approval] = approvals;
3541
+ return approvals.length === 1 && approval !== void 0 ? `Approval transaction ${approval.approvalTxHash} was mined (${approvalDetails(approval)})` : `Approval transactions were mined: ${approvals.map((sideEffect) => `${sideEffect.approvalTxHash} (${approvalDetails(sideEffect)})`).join(", ")}`;
3542
+ }
3543
+ function approvalDetails(approval) {
3544
+ if (approval.type === "erc20" || approval.type === "erc20-reset") {
3545
+ return `${approval.type}; token ${approval.target}; spender ${approval.spender ?? "unknown"}`;
3546
+ }
3547
+ if (approval.type === "minter") {
3548
+ return `minter; collection ${approval.target}; minter ${approval.minter ?? "unknown"}`;
3549
+ }
3550
+ return `nft; contract ${approval.target}; operator ${approval.operator ?? "unknown"}`;
3551
+ }
3484
3552
  var approvalAbi = [
3485
3553
  {
3486
3554
  inputs: [{ name: "owner", type: "address" }, { name: "operator", type: "address" }],
@@ -3633,7 +3701,7 @@ async function toTokenAmount(publicClient, token, value, field) {
3633
3701
  }
3634
3702
  async function ensureTokenAllowance(publicClient, walletClient, account, owner, token, spender, amount) {
3635
3703
  if (isAddressEqual4(token, ETH_ADDRESS) || amount === 0n) {
3636
- return;
3704
+ return void 0;
3637
3705
  }
3638
3706
  const allowance = await publicClient.readContract({
3639
3707
  address: token,
@@ -3642,7 +3710,7 @@ async function ensureTokenAllowance(publicClient, walletClient, account, owner,
3642
3710
  args: [owner, spender]
3643
3711
  });
3644
3712
  if (allowance >= amount) {
3645
- return;
3713
+ return void 0;
3646
3714
  }
3647
3715
  const approveTx = await walletClient.writeContract({
3648
3716
  address: token,
@@ -3652,7 +3720,14 @@ async function ensureTokenAllowance(publicClient, walletClient, account, owner,
3652
3720
  account,
3653
3721
  chain: void 0
3654
3722
  });
3655
- await publicClient.waitForTransactionReceipt({ hash: approveTx });
3723
+ await confirmErc20Approval(publicClient, {
3724
+ approvalTxHash: approveTx,
3725
+ currency: token,
3726
+ accountAddress: owner,
3727
+ spenderAddress: spender,
3728
+ requiredAmount: amount
3729
+ });
3730
+ return approveTx;
3656
3731
  }
3657
3732
  var PaymentApprovalRequiredError = class extends Error {
3658
3733
  requiredAmount;
@@ -3725,7 +3800,13 @@ async function preparePaymentAmountForSpender(opts) {
3725
3800
  account,
3726
3801
  chain: void 0
3727
3802
  });
3728
- await publicClient.waitForTransactionReceipt({ hash: approvalTxHash });
3803
+ await confirmErc20Approval(publicClient, {
3804
+ approvalTxHash,
3805
+ currency,
3806
+ accountAddress,
3807
+ spenderAddress,
3808
+ requiredAmount
3809
+ });
3729
3810
  return {
3730
3811
  value: 0n,
3731
3812
  requiredAmount,
@@ -3763,6 +3844,23 @@ async function readAllowance(publicClient, currency, accountAddress, spenderAddr
3763
3844
  args: [accountAddress, spenderAddress]
3764
3845
  });
3765
3846
  }
3847
+ async function confirmErc20Approval(publicClient, params) {
3848
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: params.approvalTxHash });
3849
+ if (receipt.status !== "success") {
3850
+ throw new Error(`ERC20 approval transaction ${params.approvalTxHash} did not succeed.`);
3851
+ }
3852
+ const allowance = await readAllowance(
3853
+ publicClient,
3854
+ params.currency,
3855
+ params.accountAddress,
3856
+ params.spenderAddress
3857
+ );
3858
+ if (allowance < params.requiredAmount) {
3859
+ throw new Error(
3860
+ `ERC20 approval transaction ${params.approvalTxHash} was mined but allowance for spender ${params.spenderAddress} is ${allowance.toString()} raw units, below the required ${params.requiredAmount.toString()} raw units.`
3861
+ );
3862
+ }
3863
+ }
3766
3864
 
3767
3865
  // src/sdk/validation-core.ts
3768
3866
  import { isHex } from "viem";
@@ -4207,6 +4305,11 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
4207
4305
  accountAddress,
4208
4306
  currentUnixTimestamp()
4209
4307
  );
4308
+ const auctionType = await publicClient.readContract({
4309
+ address: addresses.auction,
4310
+ abi: auctionAbi,
4311
+ functionName: plan.auctionType === "scheduled" ? "SCHEDULED_AUCTION" : "COLDIE_AUCTION"
4312
+ });
4210
4313
  const approvalTxHash = await approveNftContractIfNeeded({
4211
4314
  publicClient,
4212
4315
  walletClient,
@@ -4216,30 +4319,37 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
4216
4319
  operator: addresses.auction,
4217
4320
  autoApprove: params.autoApprove
4218
4321
  });
4219
- const auctionType = await publicClient.readContract({
4220
- address: addresses.auction,
4221
- abi: auctionAbi,
4222
- functionName: plan.auctionType === "scheduled" ? "SCHEDULED_AUCTION" : "COLDIE_AUCTION"
4223
- });
4224
- const txHash = await walletClient.writeContract({
4225
- address: addresses.auction,
4226
- abi: auctionAbi,
4227
- functionName: "configureAuction",
4228
- args: [
4229
- auctionType,
4230
- plan.nftAddress,
4231
- plan.tokenId,
4232
- plan.startingPrice,
4233
- plan.currency,
4234
- plan.duration,
4235
- plan.startTime,
4236
- plan.splitAddresses,
4237
- plan.splitRatios
4238
- ],
4239
- account,
4240
- chain: void 0
4322
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
4323
+ operation: "auction create",
4324
+ approvals: [{
4325
+ type: "nft",
4326
+ approvalTxHash,
4327
+ target: plan.nftAddress,
4328
+ operator: addresses.auction
4329
+ }],
4330
+ run: async () => {
4331
+ const targetTxHash = await walletClient.writeContract({
4332
+ address: addresses.auction,
4333
+ abi: auctionAbi,
4334
+ functionName: "configureAuction",
4335
+ args: [
4336
+ auctionType,
4337
+ plan.nftAddress,
4338
+ plan.tokenId,
4339
+ plan.startingPrice,
4340
+ plan.currency,
4341
+ plan.duration,
4342
+ plan.startTime,
4343
+ plan.splitAddresses,
4344
+ plan.splitRatios
4345
+ ],
4346
+ account,
4347
+ chain: void 0
4348
+ });
4349
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4350
+ return { txHash: targetTxHash, receipt: targetReceipt };
4351
+ }
4241
4352
  });
4242
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4243
4353
  return {
4244
4354
  txHash,
4245
4355
  receipt,
@@ -4265,22 +4375,34 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
4265
4375
  amount: plan.amount,
4266
4376
  autoApprove: params.autoApprove
4267
4377
  });
4268
- const txHash = await walletClient.writeContract({
4269
- address: addresses.auction,
4270
- abi: auctionAbi,
4271
- functionName: "bid",
4272
- args: [params.contract, plan.tokenId, plan.currency, plan.amount],
4273
- account,
4274
- chain: void 0,
4275
- value: payment.value
4378
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
4379
+ operation: "auction bid",
4380
+ approvals: [{
4381
+ type: "erc20",
4382
+ approvalTxHash: payment.approvalTxHash,
4383
+ target: plan.currency,
4384
+ spender: addresses.auction
4385
+ }],
4386
+ run: async () => {
4387
+ const targetTxHash = await walletClient.writeContract({
4388
+ address: addresses.auction,
4389
+ abi: auctionAbi,
4390
+ functionName: "bid",
4391
+ args: [params.contract, plan.tokenId, plan.currency, plan.amount],
4392
+ account,
4393
+ chain: void 0,
4394
+ value: payment.value
4395
+ });
4396
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4397
+ return { txHash: targetTxHash, receipt: targetReceipt };
4398
+ }
4276
4399
  });
4277
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4278
4400
  return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
4279
4401
  },
4280
4402
  async settle(params) {
4281
4403
  const { walletClient, account } = requireWallet(config);
4282
4404
  const plan = planAuctionTokenAction(params);
4283
- const txHash = await walletClient.writeContract({
4405
+ const targetTxHash = await walletClient.writeContract({
4284
4406
  address: addresses.auction,
4285
4407
  abi: auctionAbi,
4286
4408
  functionName: "settleAuction",
@@ -4288,13 +4410,13 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
4288
4410
  account,
4289
4411
  chain: void 0
4290
4412
  });
4291
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4292
- return { txHash, receipt };
4413
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4414
+ return { txHash: targetTxHash, receipt: targetReceipt };
4293
4415
  },
4294
4416
  async cancel(params) {
4295
4417
  const { walletClient, account } = requireWallet(config);
4296
4418
  const plan = planAuctionTokenAction(params);
4297
- const txHash = await walletClient.writeContract({
4419
+ const targetTxHash = await walletClient.writeContract({
4298
4420
  address: addresses.auction,
4299
4421
  abi: auctionAbi,
4300
4422
  functionName: "cancelAuction",
@@ -4302,8 +4424,8 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
4302
4424
  account,
4303
4425
  chain: void 0
4304
4426
  });
4305
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4306
- return { txHash, receipt };
4427
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4428
+ return { txHash: targetTxHash, receipt: targetReceipt };
4307
4429
  },
4308
4430
  async status(params) {
4309
4431
  const plan = planAuctionTokenAction(params);
@@ -4380,23 +4502,35 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
4380
4502
  amount: plan.amount,
4381
4503
  autoApprove: params.autoApprove
4382
4504
  });
4383
- const txHash = await walletClient.writeContract({
4384
- address: addresses.auction,
4385
- abi: auctionAbi,
4386
- functionName: "offer",
4387
- args: [params.contract, plan.tokenId, plan.currency, plan.amount, false],
4388
- account,
4389
- chain: void 0,
4390
- value: payment.value
4505
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
4506
+ operation: "offer create",
4507
+ approvals: [{
4508
+ type: "erc20",
4509
+ approvalTxHash: payment.approvalTxHash,
4510
+ target: plan.currency,
4511
+ spender: addresses.auction
4512
+ }],
4513
+ run: async () => {
4514
+ const targetTxHash = await walletClient.writeContract({
4515
+ address: addresses.auction,
4516
+ abi: auctionAbi,
4517
+ functionName: "offer",
4518
+ args: [params.contract, plan.tokenId, plan.currency, plan.amount, false],
4519
+ account,
4520
+ chain: void 0,
4521
+ value: payment.value
4522
+ });
4523
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4524
+ return { txHash: targetTxHash, receipt: targetReceipt };
4525
+ }
4391
4526
  });
4392
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4393
4527
  return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
4394
4528
  },
4395
4529
  async cancel(params) {
4396
4530
  const { walletClient, account } = requireWallet(config);
4397
4531
  const currency = params.currency === void 0 ? ETH_ADDRESS : resolveCurrencyForSdk(params.currency, chain).address;
4398
4532
  const plan = planOfferCancel({ ...params, currency });
4399
- const txHash = await walletClient.writeContract({
4533
+ const targetTxHash = await walletClient.writeContract({
4400
4534
  address: addresses.auction,
4401
4535
  abi: auctionAbi,
4402
4536
  functionName: "cancelOffer",
@@ -4404,8 +4538,8 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
4404
4538
  account,
4405
4539
  chain: void 0
4406
4540
  });
4407
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4408
- return { txHash, receipt };
4541
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4542
+ return { txHash: targetTxHash, receipt: targetReceipt };
4409
4543
  },
4410
4544
  async accept(params) {
4411
4545
  const { walletClient, account, accountAddress } = requireWallet(config);
@@ -4422,22 +4556,34 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
4422
4556
  operator: addresses.auction,
4423
4557
  autoApprove: params.autoApprove
4424
4558
  });
4425
- const txHash = await walletClient.writeContract({
4426
- address: addresses.auction,
4427
- abi: auctionAbi,
4428
- functionName: "acceptOffer",
4429
- args: [
4430
- params.contract,
4431
- plan.tokenId,
4432
- plan.currency,
4433
- plan.amount,
4434
- plan.splitAddresses,
4435
- plan.splitRatios
4436
- ],
4437
- account,
4438
- chain: void 0
4559
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
4560
+ operation: "offer accept",
4561
+ approvals: [{
4562
+ type: "nft",
4563
+ approvalTxHash,
4564
+ target: params.contract,
4565
+ operator: addresses.auction
4566
+ }],
4567
+ run: async () => {
4568
+ const targetTxHash = await walletClient.writeContract({
4569
+ address: addresses.auction,
4570
+ abi: auctionAbi,
4571
+ functionName: "acceptOffer",
4572
+ args: [
4573
+ params.contract,
4574
+ plan.tokenId,
4575
+ plan.currency,
4576
+ plan.amount,
4577
+ plan.splitAddresses,
4578
+ plan.splitRatios
4579
+ ],
4580
+ account,
4581
+ chain: void 0
4582
+ });
4583
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4584
+ return { txHash: targetTxHash, receipt: targetReceipt };
4585
+ }
4439
4586
  });
4440
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4441
4587
  return { txHash, receipt, approvalTxHash };
4442
4588
  },
4443
4589
  async status(params) {
@@ -4502,29 +4648,41 @@ function createListingNamespace(publicClient, config, chain, addresses) {
4502
4648
  operator: addresses.auction,
4503
4649
  autoApprove: params.autoApprove
4504
4650
  });
4505
- const txHash = await walletClient.writeContract({
4506
- address: addresses.auction,
4507
- abi: auctionAbi,
4508
- functionName: "setSalePrice",
4509
- args: [
4510
- plan.nftAddress,
4511
- plan.tokenId,
4512
- plan.currency,
4513
- plan.price,
4514
- plan.target,
4515
- plan.splitAddresses,
4516
- plan.splitRatios
4517
- ],
4518
- account,
4519
- chain: void 0
4651
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
4652
+ operation: "listing create",
4653
+ approvals: [{
4654
+ type: "nft",
4655
+ approvalTxHash,
4656
+ target: plan.nftAddress,
4657
+ operator: addresses.auction
4658
+ }],
4659
+ run: async () => {
4660
+ const targetTxHash = await walletClient.writeContract({
4661
+ address: addresses.auction,
4662
+ abi: auctionAbi,
4663
+ functionName: "setSalePrice",
4664
+ args: [
4665
+ plan.nftAddress,
4666
+ plan.tokenId,
4667
+ plan.currency,
4668
+ plan.price,
4669
+ plan.target,
4670
+ plan.splitAddresses,
4671
+ plan.splitRatios
4672
+ ],
4673
+ account,
4674
+ chain: void 0
4675
+ });
4676
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4677
+ return { txHash: targetTxHash, receipt: targetReceipt };
4678
+ }
4520
4679
  });
4521
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4522
4680
  return { txHash, receipt, approvalTxHash };
4523
4681
  },
4524
4682
  async cancel(params) {
4525
4683
  const { walletClient, account } = requireWallet(config);
4526
4684
  const plan = planListingCancel(params);
4527
- const txHash = await walletClient.writeContract({
4685
+ const targetTxHash = await walletClient.writeContract({
4528
4686
  address: addresses.auction,
4529
4687
  abi: auctionAbi,
4530
4688
  functionName: "removeSalePrice",
@@ -4532,8 +4690,8 @@ function createListingNamespace(publicClient, config, chain, addresses) {
4532
4690
  account,
4533
4691
  chain: void 0
4534
4692
  });
4535
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4536
- return { txHash, receipt };
4693
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4694
+ return { txHash: targetTxHash, receipt: targetReceipt };
4537
4695
  },
4538
4696
  async buy(params) {
4539
4697
  const { walletClient, account, accountAddress } = requireWallet(config);
@@ -4552,16 +4710,28 @@ function createListingNamespace(publicClient, config, chain, addresses) {
4552
4710
  amount: plan.amount,
4553
4711
  autoApprove: params.autoApprove
4554
4712
  });
4555
- const txHash = await walletClient.writeContract({
4556
- address: addresses.auction,
4557
- abi: auctionAbi,
4558
- functionName: "buy",
4559
- args: [params.contract, plan.tokenId, plan.currency, plan.amount],
4560
- account,
4561
- chain: void 0,
4562
- value: payment.value
4713
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
4714
+ operation: "listing buy",
4715
+ approvals: [{
4716
+ type: "erc20",
4717
+ approvalTxHash: payment.approvalTxHash,
4718
+ target: plan.currency,
4719
+ spender: addresses.auction
4720
+ }],
4721
+ run: async () => {
4722
+ const targetTxHash = await walletClient.writeContract({
4723
+ address: addresses.auction,
4724
+ abi: auctionAbi,
4725
+ functionName: "buy",
4726
+ args: [params.contract, plan.tokenId, plan.currency, plan.amount],
4727
+ account,
4728
+ chain: void 0,
4729
+ value: payment.value
4730
+ });
4731
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
4732
+ return { txHash: targetTxHash, receipt: targetReceipt };
4733
+ }
4563
4734
  });
4564
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
4565
4735
  return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
4566
4736
  },
4567
4737
  async status(params) {
@@ -4579,7 +4749,7 @@ function createListingNamespace(publicClient, config, chain, addresses) {
4579
4749
  }
4580
4750
 
4581
4751
  // src/sdk/batch-listing.ts
4582
- import { isAddressEqual as isAddressEqual9 } from "viem";
4752
+ import { isAddressEqual as isAddressEqual10 } from "viem";
4583
4753
 
4584
4754
  // src/contracts/abis/batch-listing.ts
4585
4755
  var batchListingAbi = [
@@ -5284,10 +5454,158 @@ function uniqueRoots(roots) {
5284
5454
  }
5285
5455
 
5286
5456
  // src/sdk/batch-listing-core.ts
5287
- import { isAddressEqual as isAddressEqual8 } from "viem";
5457
+ import { isAddressEqual as isAddressEqual9 } from "viem";
5458
+
5459
+ // src/sdk/merkle-core.ts
5460
+ import { Buffer } from "buffer";
5461
+ import { MerkleTree } from "merkletreejs";
5462
+ import {
5463
+ encodePacked as encodePacked2,
5464
+ getAddress as getAddress6,
5465
+ isAddress as isAddress5,
5466
+ isAddressEqual as isAddressEqual8,
5467
+ isHex as isHex3,
5468
+ keccak256 as keccak2562
5469
+ } from "viem";
5470
+ function hexBuffer(hex) {
5471
+ return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
5472
+ }
5473
+ function tokenLeaf(contract, tokenId) {
5474
+ const packed = encodePacked2(["address", "uint256"], [contract, tokenId]);
5475
+ return hexBuffer(keccak2562(packed));
5476
+ }
5477
+ function addressLeaf(address) {
5478
+ return hexBuffer(keccak2562(address));
5479
+ }
5480
+ function parseBytes32(value, field) {
5481
+ if (!isHex3(value, { strict: true }) || value.length !== 66) {
5482
+ throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
5483
+ }
5484
+ const normalized = value.toLowerCase();
5485
+ if (!isHex3(normalized, { strict: true }) || normalized.length !== 66) {
5486
+ throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
5487
+ }
5488
+ return normalized;
5489
+ }
5490
+ function parseBytes32Array(values, field) {
5491
+ return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
5492
+ }
5493
+ function compareTokenEntries(a, b) {
5494
+ if (!isAddressEqual8(a.contract, b.contract)) {
5495
+ return a.contract.localeCompare(b.contract);
5496
+ }
5497
+ return a.tokenId.localeCompare(b.tokenId);
5498
+ }
5499
+ function normalizeTokenEntry(token) {
5500
+ if (!isAddress5(token.contract)) {
5501
+ throw new Error(`Invalid token contract address: ${token.contract}`);
5502
+ }
5503
+ return {
5504
+ contract: getAddress6(token.contract),
5505
+ tokenId: String(token.tokenId),
5506
+ tokenIdBigInt: toInteger(token.tokenId, "tokenId")
5507
+ };
5508
+ }
5509
+ function buildBatchListingTree(tokens) {
5510
+ if (tokens.length < 2) {
5511
+ throw new Error("buildBatchListingTree requires at least two tokens");
5512
+ }
5513
+ const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
5514
+ const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
5515
+ const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
5516
+ sortPairs: true
5517
+ });
5518
+ return {
5519
+ root: parseBytes32(tree.getHexRoot(), "root"),
5520
+ tree,
5521
+ sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
5522
+ };
5523
+ }
5524
+ function buildAllowListTree(addresses) {
5525
+ if (addresses.length < 2) {
5526
+ throw new Error("buildAllowListTree requires at least two addresses");
5527
+ }
5528
+ const sorted = addresses.map((address) => {
5529
+ if (!isAddress5(address)) throw new Error(`Invalid allowlist address: ${address}`);
5530
+ return getAddress6(address);
5531
+ }).sort((a, b) => a.localeCompare(b));
5532
+ const leaves = sorted.map(addressLeaf);
5533
+ const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
5534
+ sortPairs: true
5535
+ });
5536
+ return {
5537
+ root: parseBytes32(tree.getHexRoot(), "root"),
5538
+ tree,
5539
+ sortedAddresses: sorted
5540
+ };
5541
+ }
5542
+ function getTokenProof(tree, contract, tokenId) {
5543
+ const leaf = tokenLeaf(getAddress6(contract), tokenId);
5544
+ return parseBytes32Array(tree.getHexProof(leaf), "proof");
5545
+ }
5546
+ function getAddressProof(tree, address) {
5547
+ const leaf = addressLeaf(getAddress6(address));
5548
+ return parseBytes32Array(tree.getHexProof(leaf), "proof");
5549
+ }
5550
+ function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
5551
+ const tokenIdBig = toInteger(tokenId, "tokenId");
5552
+ const contractChecksum = getAddress6(contract);
5553
+ const found = artifact.tokens.find(
5554
+ (token) => isAddressEqual8(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
5555
+ );
5556
+ if (found === void 0) {
5557
+ throw new Error(
5558
+ `Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
5559
+ );
5560
+ }
5561
+ const { tree, root } = buildBatchListingTree(
5562
+ artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
5563
+ );
5564
+ const artifactRoot = parseBytes32(artifact.root, "artifact.root");
5565
+ if (root !== artifactRoot) {
5566
+ throw new Error(
5567
+ `Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
5568
+ );
5569
+ }
5570
+ const allowListProofFields = buildAllowListProofFields(artifact, buyer);
5571
+ return {
5572
+ root: artifactRoot,
5573
+ contract: contractChecksum,
5574
+ tokenId: tokenIdBig.toString(),
5575
+ proof: getTokenProof(tree, contractChecksum, tokenIdBig),
5576
+ ...allowListProofFields ?? {}
5577
+ };
5578
+ }
5579
+ function buildAllowListProofFields(artifact, buyer) {
5580
+ if (artifact.allowList === void 0) return void 0;
5581
+ if (buyer === void 0) {
5582
+ throw new Error(
5583
+ "This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
5584
+ );
5585
+ }
5586
+ if (!isAddress5(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
5587
+ const buyerChecksum = getAddress6(buyer);
5588
+ const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual8(address, buyerChecksum));
5589
+ if (!inAllowList) {
5590
+ throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
5591
+ }
5592
+ const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
5593
+ const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
5594
+ if (root !== artifactAllowListRoot) {
5595
+ throw new Error(
5596
+ `Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
5597
+ );
5598
+ }
5599
+ return {
5600
+ allowListProof: getAddressProof(tree, buyerChecksum),
5601
+ allowListAddress: buyerChecksum
5602
+ };
5603
+ }
5604
+
5605
+ // src/sdk/batch-listing-core.ts
5288
5606
  function uniqueAddresses(addresses) {
5289
5607
  return addresses.reduce(
5290
- (unique, address) => unique.some((existing) => isAddressEqual8(existing, address)) ? unique : [...unique, address],
5608
+ (unique, address) => unique.some((existing) => isAddressEqual9(existing, address)) ? unique : [...unique, address],
5291
5609
  []
5292
5610
  );
5293
5611
  }
@@ -5331,7 +5649,7 @@ function shapeBatchListingStatus(params) {
5331
5649
  splitRecipients: [...params.listingConfig.splitRecipients],
5332
5650
  splitRatios: [...params.listingConfig.splitRatios],
5333
5651
  nonce: params.listingConfig.nonce,
5334
- isEth: isAddressEqual8(params.listingConfig.currency, ETH_ADDRESS),
5652
+ isEth: isAddressEqual9(params.listingConfig.currency, ETH_ADDRESS),
5335
5653
  hasListing,
5336
5654
  allowList: params.allowList,
5337
5655
  ...params.tokenStatus
@@ -5362,13 +5680,13 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5362
5680
  functionName: "ownerOf",
5363
5681
  args: [BigInt(token.tokenId)]
5364
5682
  });
5365
- if (!isAddressEqual9(owner, accountAddress)) {
5683
+ if (!isAddressEqual10(owner, accountAddress)) {
5366
5684
  throw new Error(
5367
5685
  `Token ${token.contract}/${token.tokenId} is owned by ${owner}, not the configured account ${accountAddress}. Re-check the token set before registering this batch listing.`
5368
5686
  );
5369
5687
  }
5370
5688
  }
5371
- const approvalTxHashes = await approveNftContracts({
5689
+ const nftApprovals = await approveNftContracts({
5372
5690
  publicClient,
5373
5691
  walletClient,
5374
5692
  account,
@@ -5377,26 +5695,38 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5377
5695
  nftAddresses: uniqueContracts,
5378
5696
  autoApprove: params.autoApprove
5379
5697
  });
5380
- const txHash = await walletClient.writeContract({
5381
- address: addresses.batchListing,
5382
- abi: batchListingAbi,
5383
- functionName: "registerSalePriceMerkleRoot",
5384
- args: [
5385
- artifact.root,
5386
- artifact.currency,
5387
- BigInt(artifact.amount),
5388
- splitConfig.splitAddresses,
5389
- splitConfig.splitRatios
5390
- ],
5391
- account,
5392
- chain: void 0
5698
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
5699
+ operation: "batch listing create",
5700
+ approvals: nftApprovals.map((approval) => ({
5701
+ type: "nft",
5702
+ approvalTxHash: approval.txHash,
5703
+ target: approval.nftAddress,
5704
+ operator: addresses.erc721ApprovalManager
5705
+ })),
5706
+ run: async () => {
5707
+ const targetTxHash = await walletClient.writeContract({
5708
+ address: addresses.batchListing,
5709
+ abi: batchListingAbi,
5710
+ functionName: "registerSalePriceMerkleRoot",
5711
+ args: [
5712
+ artifact.root,
5713
+ artifact.currency,
5714
+ BigInt(artifact.amount),
5715
+ splitConfig.splitAddresses,
5716
+ splitConfig.splitRatios
5717
+ ],
5718
+ account,
5719
+ chain: void 0
5720
+ });
5721
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
5722
+ return { txHash: targetTxHash, receipt: targetReceipt };
5723
+ }
5393
5724
  });
5394
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
5395
5725
  return {
5396
5726
  txHash,
5397
5727
  receipt,
5398
5728
  root: artifact.root,
5399
- approvalTxHashes: approvalTxHashes.length > 0 ? approvalTxHashes : void 0
5729
+ approvalTxHashes: nftApprovals.length > 0 ? nftApprovals.map((approval) => approval.txHash) : void 0
5400
5730
  };
5401
5731
  },
5402
5732
  async cancel(params) {
@@ -5409,7 +5739,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5409
5739
  creator: accountAddress,
5410
5740
  params
5411
5741
  });
5412
- const txHash = await walletClient.writeContract({
5742
+ const targetTxHash = await walletClient.writeContract({
5413
5743
  address: addresses.batchListing,
5414
5744
  abi: batchListingAbi,
5415
5745
  functionName: "cancelSalePriceMerkleRoot",
@@ -5417,8 +5747,8 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5417
5747
  account,
5418
5748
  chain: void 0
5419
5749
  });
5420
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
5421
- return { txHash, receipt, root };
5750
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
5751
+ return { txHash: targetTxHash, receipt: targetReceipt, root };
5422
5752
  },
5423
5753
  async buy(params) {
5424
5754
  const { walletClient, account, accountAddress } = requireWallet(config);
@@ -5449,25 +5779,37 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5449
5779
  amount,
5450
5780
  autoApprove: params.autoApprove
5451
5781
  });
5452
- const txHash = await walletClient.writeContract({
5453
- address: addresses.batchListing,
5454
- abi: batchListingAbi,
5455
- functionName: "buyWithMerkleProof",
5456
- args: [
5457
- proofArtifact.contract,
5458
- tokenIdBig,
5459
- currency,
5460
- amount,
5461
- params.creator,
5462
- proofArtifact.root,
5463
- proofArtifact.proof,
5464
- allowListProof
5465
- ],
5466
- account,
5467
- chain: void 0,
5468
- value: payment.value
5782
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
5783
+ operation: "batch listing buy",
5784
+ approvals: [{
5785
+ type: "erc20",
5786
+ approvalTxHash: payment.approvalTxHash,
5787
+ target: currency,
5788
+ spender: addresses.erc20ApprovalManager
5789
+ }],
5790
+ run: async () => {
5791
+ const targetTxHash = await walletClient.writeContract({
5792
+ address: addresses.batchListing,
5793
+ abi: batchListingAbi,
5794
+ functionName: "buyWithMerkleProof",
5795
+ args: [
5796
+ proofArtifact.contract,
5797
+ tokenIdBig,
5798
+ currency,
5799
+ amount,
5800
+ params.creator,
5801
+ proofArtifact.root,
5802
+ proofArtifact.proof,
5803
+ allowListProof
5804
+ ],
5805
+ account,
5806
+ chain: void 0,
5807
+ value: payment.value
5808
+ });
5809
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
5810
+ return { txHash: targetTxHash, receipt: targetReceipt };
5811
+ }
5469
5812
  });
5470
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
5471
5813
  return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
5472
5814
  },
5473
5815
  async setAllowlist(params) {
@@ -5485,7 +5827,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5485
5827
  requireInput(params.endTime ?? params.artifact?.allowList?.endTimestamp, "endTime"),
5486
5828
  "endTime"
5487
5829
  );
5488
- const txHash = await walletClient.writeContract({
5830
+ const targetTxHash = await walletClient.writeContract({
5489
5831
  address: addresses.batchListing,
5490
5832
  abi: batchListingAbi,
5491
5833
  functionName: "setAllowListConfig",
@@ -5493,8 +5835,8 @@ function createBatchListingNamespace(publicClient, config, addresses) {
5493
5835
  account,
5494
5836
  chain: void 0
5495
5837
  });
5496
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
5497
- return { txHash, receipt, root, allowListRoot, endTime };
5838
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
5839
+ return { txHash: targetTxHash, receipt: targetReceipt, root, allowListRoot, endTime };
5498
5840
  },
5499
5841
  async status(params) {
5500
5842
  const resolvedParams = await resolveBatchListingStatusParams({
@@ -5723,7 +6065,7 @@ function isHash(value) {
5723
6065
  }
5724
6066
  async function approveNftContracts(opts) {
5725
6067
  return opts.nftAddresses.reduce(async (previous, nftAddress) => {
5726
- const hashes = await previous;
6068
+ const approvals = await previous;
5727
6069
  const txHash = await approveNftContractIfNeeded({
5728
6070
  publicClient: opts.publicClient,
5729
6071
  walletClient: opts.walletClient,
@@ -5733,7 +6075,7 @@ async function approveNftContracts(opts) {
5733
6075
  operator: opts.operator,
5734
6076
  autoApprove: opts.autoApprove
5735
6077
  });
5736
- return isHash(txHash) ? [...hashes, txHash] : hashes;
6078
+ return isHash(txHash) ? [...approvals, { nftAddress, txHash }] : approvals;
5737
6079
  }, Promise.resolve([]));
5738
6080
  }
5739
6081
  async function prepareBatchListingPayment(opts) {
@@ -5786,7 +6128,7 @@ async function readTokenStatus(publicClient, batchListingAddress, params) {
5786
6128
 
5787
6129
  // src/sdk/batch-auction.ts
5788
6130
  import {
5789
- isAddressEqual as isAddressEqual11,
6131
+ isAddressEqual as isAddressEqual12,
5790
6132
  parseUnits as parseUnits3,
5791
6133
  parseEventLogs as parseEventLogs3
5792
6134
  } from "viem";
@@ -6018,7 +6360,7 @@ var batchAuctionHouseAbi = [
6018
6360
  ];
6019
6361
 
6020
6362
  // src/sdk/batch-auction-core.ts
6021
- import { isAddressEqual as isAddressEqual10 } from "viem";
6363
+ import { isAddressEqual as isAddressEqual11 } from "viem";
6022
6364
  var zeroAddress3 = ETH_ADDRESS;
6023
6365
  var marketplaceFeePercentage = 3n;
6024
6366
  function planBatchAuctionCreateLocalInputs(params, nowSeconds) {
@@ -6103,17 +6445,19 @@ function planBatchAuctionStatus(params) {
6103
6445
  };
6104
6446
  }
6105
6447
  function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
6106
- const hasAuction = details.startingTime > 0n && !isAddressEqual10(details.seller, zeroAddress3);
6107
- const hasRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n;
6108
- const duration = hasAuction ? details.duration : rootContext?.config.duration ?? 0n;
6448
+ const hasAuction = details.startingTime > 0n && !isAddressEqual11(details.seller, zeroAddress3);
6449
+ const hasCurrentRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n && rootContext.rootNonce === rootContext.config.nonce;
6450
+ const currentRootConfig = hasCurrentRootConfig ? rootContext.config : void 0;
6451
+ const hasRootConfig = currentRootConfig !== void 0;
6452
+ const duration = hasAuction ? details.duration : currentRootConfig?.duration ?? 0n;
6109
6453
  const startingTime = hasAuction ? details.startingTime : 0n;
6110
6454
  const endTime = hasAuction ? startingTime + duration : null;
6111
6455
  const ended = endTime !== null && nowSeconds >= endTime;
6112
- const currentBidder = currentBid.amount > 0n && !isAddressEqual10(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
6456
+ const currentBidder = currentBid.amount > 0n && !isAddressEqual11(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
6113
6457
  const seller = hasAuction ? details.seller : rootContext?.creator ?? zeroAddress3;
6114
- const currency = hasAuction ? details.currency : rootContext?.config.currency ?? ETH_ADDRESS;
6115
- const reserveAmount = hasAuction ? details.reserveAmount : rootContext?.config.reserveAmount ?? 0n;
6116
- const tokenNonceConsumed = rootContext === void 0 ? null : rootContext.tokenNonce >= rootContext.config.nonce;
6458
+ const currency = hasAuction ? details.currency : currentRootConfig?.currency ?? ETH_ADDRESS;
6459
+ const reserveAmount = hasAuction ? details.reserveAmount : currentRootConfig?.reserveAmount ?? 0n;
6460
+ const tokenNonceConsumed = rootContext === void 0 ? null : !hasCurrentRootConfig || rootContext.tokenNonce >= rootContext.config.nonce;
6117
6461
  return {
6118
6462
  seller,
6119
6463
  root: rootContext?.root ?? null,
@@ -6123,8 +6467,8 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
6123
6467
  creationBlock: details.creationBlock,
6124
6468
  startingTime,
6125
6469
  endTime,
6126
- splitAddresses: resolveStatusSplitAddresses(hasAuction, details, rootContext),
6127
- splitRatios: resolveStatusSplitRatios(hasAuction, details, rootContext),
6470
+ splitAddresses: resolveStatusSplitAddresses(hasAuction, details, currentRootConfig),
6471
+ splitRatios: resolveStatusSplitRatios(hasAuction, details, currentRootConfig),
6128
6472
  hasRootConfig,
6129
6473
  rootNonce: rootContext?.rootNonce ?? null,
6130
6474
  tokenNonce: rootContext?.tokenNonce ?? null,
@@ -6144,7 +6488,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
6144
6488
  hasRootConfig,
6145
6489
  tokenNonceConsumed
6146
6490
  }),
6147
- isEth: isAddressEqual10(currency, ETH_ADDRESS)
6491
+ isEth: isAddressEqual11(currency, ETH_ADDRESS)
6148
6492
  };
6149
6493
  }
6150
6494
  function shapeBatchAuctionDetailsRead(details) {
@@ -6255,28 +6599,28 @@ function planSplitRecipients(splitAddresses, splitRatios, accountAddress) {
6255
6599
  };
6256
6600
  }
6257
6601
  function uniqueAddresses2(addresses) {
6258
- return addresses.reduce((unique, address) => unique.some((candidate) => isAddressEqual10(candidate, address)) ? unique : [...unique, address], []);
6602
+ return addresses.reduce((unique, address) => unique.some((candidate) => isAddressEqual11(candidate, address)) ? unique : [...unique, address], []);
6259
6603
  }
6260
6604
  function addMinimumBidIncrease(amount) {
6261
6605
  return amount + amount * marketplaceFeePercentage / 100n;
6262
6606
  }
6263
- function resolveStatusSplitAddresses(hasAuction, details, rootContext) {
6607
+ function resolveStatusSplitAddresses(hasAuction, details, rootConfig) {
6264
6608
  if (hasAuction) {
6265
6609
  return [...details.splitAddresses];
6266
6610
  }
6267
- if (rootContext === void 0) {
6611
+ if (rootConfig === void 0) {
6268
6612
  return [];
6269
6613
  }
6270
- return [...rootContext.config.splitAddresses];
6614
+ return [...rootConfig.splitAddresses];
6271
6615
  }
6272
- function resolveStatusSplitRatios(hasAuction, details, rootContext) {
6616
+ function resolveStatusSplitRatios(hasAuction, details, rootConfig) {
6273
6617
  if (hasAuction) {
6274
6618
  return [...details.splitRatios];
6275
6619
  }
6276
- if (rootContext === void 0) {
6620
+ if (rootConfig === void 0) {
6277
6621
  return [];
6278
6622
  }
6279
- return [...rootContext.config.splitRatios];
6623
+ return [...rootConfig.splitRatios];
6280
6624
  }
6281
6625
  function resolveBatchAuctionState(params) {
6282
6626
  if (params.hasAuction) {
@@ -6310,7 +6654,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6310
6654
  currentUnixTimestamp2()
6311
6655
  );
6312
6656
  const erc721ApprovalManager = plan.approvalContracts.length === 0 ? void 0 : requireContractAddress(chain, "erc721ApprovalManager");
6313
- const approvalTxHashes = await approveNftContracts2({
6657
+ const nftApprovals = await approveNftContracts2({
6314
6658
  publicClient,
6315
6659
  account,
6316
6660
  accountAddress,
@@ -6319,31 +6663,43 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6319
6663
  nftAddresses: plan.approvalContracts,
6320
6664
  autoApprove: params.autoApprove
6321
6665
  });
6322
- const txHash = await walletClient.writeContract({
6323
- address: batchAuctionHouse,
6324
- abi: batchAuctionHouseAbi,
6325
- functionName: "registerAuctionMerkleRoot",
6326
- args: [
6327
- plan.root,
6328
- plan.currency,
6329
- plan.reserveAmount,
6330
- plan.duration,
6331
- plan.splitAddresses,
6332
- plan.splitRatios
6333
- ],
6334
- account,
6335
- chain: void 0
6336
- });
6337
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
6338
- const logs = parseEventLogs3({
6339
- abi: batchAuctionHouseAbi,
6340
- logs: receipt.logs,
6341
- eventName: "AuctionMerkleRootRegistered"
6666
+ const { txHash, receipt, registered } = await runWithApprovalSideEffectAlert({
6667
+ operation: "batch auction create",
6668
+ approvals: nftApprovals.map((approval) => ({
6669
+ type: "nft",
6670
+ approvalTxHash: approval.txHash,
6671
+ target: approval.nftAddress,
6672
+ operator: erc721ApprovalManager
6673
+ })),
6674
+ run: async () => {
6675
+ const targetTxHash = await walletClient.writeContract({
6676
+ address: batchAuctionHouse,
6677
+ abi: batchAuctionHouseAbi,
6678
+ functionName: "registerAuctionMerkleRoot",
6679
+ args: [
6680
+ plan.root,
6681
+ plan.currency,
6682
+ plan.reserveAmount,
6683
+ plan.duration,
6684
+ plan.splitAddresses,
6685
+ plan.splitRatios
6686
+ ],
6687
+ account,
6688
+ chain: void 0
6689
+ });
6690
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
6691
+ const logs = parseEventLogs3({
6692
+ abi: batchAuctionHouseAbi,
6693
+ logs: targetReceipt.logs,
6694
+ eventName: "AuctionMerkleRootRegistered"
6695
+ });
6696
+ const [registeredLog] = logs;
6697
+ if (!registeredLog) {
6698
+ throw new Error("Batch auction create transaction succeeded but AuctionMerkleRootRegistered was not found in logs.");
6699
+ }
6700
+ return { txHash: targetTxHash, receipt: targetReceipt, registered: registeredLog };
6701
+ }
6342
6702
  });
6343
- const [registered] = logs;
6344
- if (!registered) {
6345
- throw new Error("Batch auction create transaction succeeded but AuctionMerkleRootRegistered was not found in logs.");
6346
- }
6347
6703
  return {
6348
6704
  txHash,
6349
6705
  receipt,
@@ -6354,7 +6710,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6354
6710
  reserveAmount: registered.args.startingAmount,
6355
6711
  duration: registered.args.duration,
6356
6712
  nonce: registered.args.nonce,
6357
- approvalTxHashes
6713
+ approvalTxHashes: nftApprovals.map((approval) => approval.txHash)
6358
6714
  };
6359
6715
  },
6360
6716
  async cancel(params) {
@@ -6367,7 +6723,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6367
6723
  params
6368
6724
  );
6369
6725
  const plan = planBatchAuctionRoot(resolvedParams);
6370
- const txHash = await walletClient.writeContract({
6726
+ const targetTxHash = await walletClient.writeContract({
6371
6727
  address: batchAuctionHouse,
6372
6728
  abi: batchAuctionHouseAbi,
6373
6729
  functionName: "cancelAuctionMerkleRoot",
@@ -6375,10 +6731,10 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6375
6731
  account,
6376
6732
  chain: void 0
6377
6733
  });
6378
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
6734
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
6379
6735
  const logs = parseEventLogs3({
6380
6736
  abi: batchAuctionHouseAbi,
6381
- logs: receipt.logs,
6737
+ logs: targetReceipt.logs,
6382
6738
  eventName: "AuctionMerkleRootCancelled"
6383
6739
  });
6384
6740
  const [cancelled] = logs;
@@ -6386,8 +6742,8 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6386
6742
  throw new Error("Batch auction cancel transaction succeeded but AuctionMerkleRootCancelled was not found in logs.");
6387
6743
  }
6388
6744
  return {
6389
- txHash,
6390
- receipt,
6745
+ txHash: targetTxHash,
6746
+ receipt: targetReceipt,
6391
6747
  batchAuctionHouse,
6392
6748
  creator: cancelled.args.creator,
6393
6749
  root: cancelled.args.merkleRoot
@@ -6417,7 +6773,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6417
6773
  const price = requireInput(resolvedParams.price, "price");
6418
6774
  const amount = typeof price === "bigint" ? price : parseUnits3(stringifyAmountInput(price, "price"), await resolveCurrencyDecimals(publicClient, chain, currency));
6419
6775
  const plan = planBatchAuctionBid({ ...resolvedParams, currency, price: amount });
6420
- const erc20ApprovalManager = isAddressEqual11(plan.currency, ETH_ADDRESS) ? batchAuctionHouse : requireContractAddress(chain, "erc20ApprovalManager");
6776
+ const erc20ApprovalManager = isAddressEqual12(plan.currency, ETH_ADDRESS) ? batchAuctionHouse : requireContractAddress(chain, "erc20ApprovalManager");
6421
6777
  const payment = await preparePaymentAmountForSpender({
6422
6778
  publicClient,
6423
6779
  walletClient,
@@ -6428,33 +6784,45 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6428
6784
  requiredAmount: plan.requiredPayment,
6429
6785
  autoApprove: params.autoApprove
6430
6786
  });
6431
- const txHash = await walletClient.writeContract({
6432
- address: batchAuctionHouse,
6433
- abi: batchAuctionHouseAbi,
6434
- functionName: "bidWithAuctionMerkleProof",
6435
- args: [
6436
- plan.currency,
6437
- plan.contract,
6438
- plan.tokenId,
6439
- plan.creator,
6440
- plan.root,
6441
- plan.amount,
6442
- plan.proof
6443
- ],
6444
- account,
6445
- chain: void 0,
6446
- value: payment.value
6447
- });
6448
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
6449
- const logs = parseEventLogs3({
6450
- abi: batchAuctionHouseAbi,
6451
- logs: receipt.logs,
6452
- eventName: "AuctionMerkleBid"
6787
+ const { txHash, receipt, bid } = await runWithApprovalSideEffectAlert({
6788
+ operation: "batch auction bid",
6789
+ approvals: [{
6790
+ type: "erc20",
6791
+ approvalTxHash: payment.approvalTxHash,
6792
+ target: plan.currency,
6793
+ spender: erc20ApprovalManager
6794
+ }],
6795
+ run: async () => {
6796
+ const targetTxHash = await walletClient.writeContract({
6797
+ address: batchAuctionHouse,
6798
+ abi: batchAuctionHouseAbi,
6799
+ functionName: "bidWithAuctionMerkleProof",
6800
+ args: [
6801
+ plan.currency,
6802
+ plan.contract,
6803
+ plan.tokenId,
6804
+ plan.creator,
6805
+ plan.root,
6806
+ plan.amount,
6807
+ plan.proof
6808
+ ],
6809
+ account,
6810
+ chain: void 0,
6811
+ value: payment.value
6812
+ });
6813
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
6814
+ const logs = parseEventLogs3({
6815
+ abi: batchAuctionHouseAbi,
6816
+ logs: targetReceipt.logs,
6817
+ eventName: "AuctionMerkleBid"
6818
+ });
6819
+ const [bidLog] = logs;
6820
+ if (!bidLog) {
6821
+ throw new Error("Batch auction bid transaction succeeded but AuctionMerkleBid was not found in logs.");
6822
+ }
6823
+ return { txHash: targetTxHash, receipt: targetReceipt, bid: bidLog };
6824
+ }
6453
6825
  });
6454
- const [bid] = logs;
6455
- if (!bid) {
6456
- throw new Error("Batch auction bid transaction succeeded but AuctionMerkleBid was not found in logs.");
6457
- }
6458
6826
  return {
6459
6827
  txHash,
6460
6828
  receipt,
@@ -6475,7 +6843,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6475
6843
  const batchAuctionHouse = requireContractAddress(chain, "batchAuctionHouse");
6476
6844
  const { walletClient, account } = requireWallet(config);
6477
6845
  const plan = planBatchAuctionStatus(params);
6478
- const txHash = await walletClient.writeContract({
6846
+ const targetTxHash = await walletClient.writeContract({
6479
6847
  address: batchAuctionHouse,
6480
6848
  abi: batchAuctionHouseAbi,
6481
6849
  functionName: "settleAuction",
@@ -6483,10 +6851,10 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6483
6851
  account,
6484
6852
  chain: void 0
6485
6853
  });
6486
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
6854
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
6487
6855
  const logs = parseEventLogs3({
6488
6856
  abi: batchAuctionHouseAbi,
6489
- logs: receipt.logs,
6857
+ logs: targetReceipt.logs,
6490
6858
  eventName: "AuctionSettled"
6491
6859
  });
6492
6860
  const [settled] = logs;
@@ -6494,8 +6862,8 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
6494
6862
  throw new Error("Batch auction settle transaction succeeded but AuctionSettled was not found in logs.");
6495
6863
  }
6496
6864
  return {
6497
- txHash,
6498
- receipt,
6865
+ txHash: targetTxHash,
6866
+ receipt: targetReceipt,
6499
6867
  batchAuctionHouse,
6500
6868
  seller: settled.args.seller,
6501
6869
  bidder: settled.args.bidder,
@@ -6682,7 +7050,7 @@ async function approveNftContracts2(opts) {
6682
7050
  }
6683
7051
  const { walletClient, operator } = opts;
6684
7052
  return opts.nftAddresses.reduce(async (previous, nftAddress) => {
6685
- const hashes = await previous;
7053
+ const approvals = await previous;
6686
7054
  const txHash = await approveNftContract({
6687
7055
  publicClient: opts.publicClient,
6688
7056
  walletClient,
@@ -6692,7 +7060,7 @@ async function approveNftContracts2(opts) {
6692
7060
  nftAddress,
6693
7061
  autoApprove: opts.autoApprove
6694
7062
  });
6695
- return txHash === void 0 ? hashes : [...hashes, txHash];
7063
+ return txHash === void 0 ? approvals : [...approvals, { nftAddress, txHash }];
6696
7064
  }, Promise.resolve([]));
6697
7065
  }
6698
7066
  async function approveNftContract(opts) {
@@ -6764,7 +7132,7 @@ async function resolveRootContext(opts) {
6764
7132
 
6765
7133
  // src/sdk/batch-offer.ts
6766
7134
  import {
6767
- isAddressEqual as isAddressEqual13,
7135
+ isAddressEqual as isAddressEqual14,
6768
7136
  parseUnits as parseUnits4,
6769
7137
  parseEventLogs as parseEventLogs4
6770
7138
  } from "viem";
@@ -6871,7 +7239,7 @@ var batchOfferAbi = [
6871
7239
  ];
6872
7240
 
6873
7241
  // src/sdk/batch-offer-core.ts
6874
- import { isAddressEqual as isAddressEqual12 } from "viem";
7242
+ import { isAddressEqual as isAddressEqual13 } from "viem";
6875
7243
  var zeroAddress4 = ETH_ADDRESS;
6876
7244
  var zeroBytes322 = "0x0000000000000000000000000000000000000000000000000000000000000000";
6877
7245
  function planBatchOfferCreateLocalInputs(params, nowSeconds) {
@@ -6928,7 +7296,7 @@ function planBatchOfferAccept(params, accountAddress) {
6928
7296
  };
6929
7297
  }
6930
7298
  function shapeBatchOfferStatus(offer, expected, nowSeconds) {
6931
- const hasOffer = !isAddressEqual12(offer.creator, zeroAddress4) && offer.rootHash !== zeroBytes322 && offer.amount > 0n;
7299
+ const hasOffer = !isAddressEqual13(offer.creator, zeroAddress4) && offer.rootHash !== zeroBytes322 && offer.amount > 0n;
6932
7300
  const expired = hasOffer && offer.expiry <= nowSeconds;
6933
7301
  const state = !hasOffer ? "NONE" : expired ? "EXPIRED" : "ACTIVE";
6934
7302
  return {
@@ -6943,7 +7311,7 @@ function shapeBatchOfferStatus(offer, expected, nowSeconds) {
6943
7311
  revoked: hasOffer ? false : null,
6944
7312
  fillable: hasOffer && !expired,
6945
7313
  state,
6946
- isEth: isAddressEqual12(offer.currency, ETH_ADDRESS)
7314
+ isEth: isAddressEqual13(offer.currency, ETH_ADDRESS)
6947
7315
  };
6948
7316
  }
6949
7317
  function shapeBatchOfferRead(value) {
@@ -7032,25 +7400,37 @@ function createBatchOfferNamespace(publicClient, config, chain) {
7032
7400
  amount: plan.amount,
7033
7401
  autoApprove: params.autoApprove
7034
7402
  });
7035
- const txHash = await walletClient.writeContract({
7036
- address: batchOfferCreator,
7037
- abi: batchOfferAbi,
7038
- functionName: "createBatchOffer",
7039
- args: [plan.root, plan.amount, plan.currency, plan.expiry],
7040
- account,
7041
- chain: void 0,
7042
- value: payment.value
7043
- });
7044
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
7045
- const logs = parseEventLogs4({
7046
- abi: batchOfferAbi,
7047
- logs: receipt.logs,
7048
- eventName: "BatchOfferCreated"
7403
+ const { txHash, receipt, created } = await runWithApprovalSideEffectAlert({
7404
+ operation: "batch offer create",
7405
+ approvals: [{
7406
+ type: "erc20",
7407
+ approvalTxHash: payment.approvalTxHash,
7408
+ target: plan.currency,
7409
+ spender: batchOfferCreator
7410
+ }],
7411
+ run: async () => {
7412
+ const targetTxHash = await walletClient.writeContract({
7413
+ address: batchOfferCreator,
7414
+ abi: batchOfferAbi,
7415
+ functionName: "createBatchOffer",
7416
+ args: [plan.root, plan.amount, plan.currency, plan.expiry],
7417
+ account,
7418
+ chain: void 0,
7419
+ value: payment.value
7420
+ });
7421
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
7422
+ const logs = parseEventLogs4({
7423
+ abi: batchOfferAbi,
7424
+ logs: targetReceipt.logs,
7425
+ eventName: "BatchOfferCreated"
7426
+ });
7427
+ const [createdLog] = logs;
7428
+ if (!createdLog) {
7429
+ throw new Error("Batch offer create transaction succeeded but BatchOfferCreated was not found in logs.");
7430
+ }
7431
+ return { txHash: targetTxHash, receipt: targetReceipt, created: createdLog };
7432
+ }
7049
7433
  });
7050
- const [created] = logs;
7051
- if (!created) {
7052
- throw new Error("Batch offer create transaction succeeded but BatchOfferCreated was not found in logs.");
7053
- }
7054
7434
  return {
7055
7435
  txHash,
7056
7436
  receipt,
@@ -7076,7 +7456,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
7076
7456
  params
7077
7457
  });
7078
7458
  const plan = planBatchOfferRoot(resolvedParams);
7079
- const txHash = await walletClient.writeContract({
7459
+ const targetTxHash = await walletClient.writeContract({
7080
7460
  address: batchOfferCreator,
7081
7461
  abi: batchOfferAbi,
7082
7462
  functionName: "revokeBatchOffer",
@@ -7084,10 +7464,10 @@ function createBatchOfferNamespace(publicClient, config, chain) {
7084
7464
  account,
7085
7465
  chain: void 0
7086
7466
  });
7087
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
7467
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
7088
7468
  const logs = parseEventLogs4({
7089
7469
  abi: batchOfferAbi,
7090
- logs: receipt.logs,
7470
+ logs: targetReceipt.logs,
7091
7471
  eventName: "BatchOfferRevoked"
7092
7472
  });
7093
7473
  const [revoked] = logs;
@@ -7095,8 +7475,8 @@ function createBatchOfferNamespace(publicClient, config, chain) {
7095
7475
  throw new Error("Batch offer revoke transaction succeeded but BatchOfferRevoked was not found in logs.");
7096
7476
  }
7097
7477
  return {
7098
- txHash,
7099
- receipt,
7478
+ txHash: targetTxHash,
7479
+ receipt: targetReceipt,
7100
7480
  batchOfferCreator,
7101
7481
  creator: revoked.args.creator,
7102
7482
  root: revoked.args.rootHash,
@@ -7121,7 +7501,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
7121
7501
  functionName: "ownerOf",
7122
7502
  args: [plan.tokenId]
7123
7503
  });
7124
- if (!isAddressEqual13(owner, accountAddress)) {
7504
+ if (!isAddressEqual14(owner, accountAddress)) {
7125
7505
  throw new Error(`Connected wallet ${accountAddress} does not own token ${plan.contract} #${plan.tokenId.toString()}.`);
7126
7506
  }
7127
7507
  const approvalTxHash = await approveNftContractIfNeeded({
@@ -7133,32 +7513,44 @@ function createBatchOfferNamespace(publicClient, config, chain) {
7133
7513
  operator: batchOfferCreator,
7134
7514
  autoApprove: plan.autoApprove
7135
7515
  });
7136
- const txHash = await walletClient.writeContract({
7137
- address: batchOfferCreator,
7138
- abi: batchOfferAbi,
7139
- functionName: "acceptBatchOffer",
7140
- args: [
7141
- plan.creator,
7142
- plan.proof,
7143
- plan.root,
7144
- plan.contract,
7145
- plan.tokenId,
7146
- plan.splitAddresses,
7147
- plan.splitRatios
7148
- ],
7149
- account,
7150
- chain: void 0
7151
- });
7152
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
7153
- const logs = parseEventLogs4({
7154
- abi: batchOfferAbi,
7155
- logs: receipt.logs,
7156
- eventName: "BatchOfferAccepted"
7516
+ const { txHash, receipt, accepted } = await runWithApprovalSideEffectAlert({
7517
+ operation: "batch offer accept",
7518
+ approvals: [{
7519
+ type: "nft",
7520
+ approvalTxHash,
7521
+ target: plan.contract,
7522
+ operator: batchOfferCreator
7523
+ }],
7524
+ run: async () => {
7525
+ const targetTxHash = await walletClient.writeContract({
7526
+ address: batchOfferCreator,
7527
+ abi: batchOfferAbi,
7528
+ functionName: "acceptBatchOffer",
7529
+ args: [
7530
+ plan.creator,
7531
+ plan.proof,
7532
+ plan.root,
7533
+ plan.contract,
7534
+ plan.tokenId,
7535
+ plan.splitAddresses,
7536
+ plan.splitRatios
7537
+ ],
7538
+ account,
7539
+ chain: void 0
7540
+ });
7541
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
7542
+ const logs = parseEventLogs4({
7543
+ abi: batchOfferAbi,
7544
+ logs: targetReceipt.logs,
7545
+ eventName: "BatchOfferAccepted"
7546
+ });
7547
+ const [acceptedLog] = logs;
7548
+ if (!acceptedLog) {
7549
+ throw new Error("Batch offer accept transaction succeeded but BatchOfferAccepted was not found in logs.");
7550
+ }
7551
+ return { txHash: targetTxHash, receipt: targetReceipt, accepted: acceptedLog };
7552
+ }
7157
7553
  });
7158
- const [accepted] = logs;
7159
- if (!accepted) {
7160
- throw new Error("Batch offer accept transaction succeeded but BatchOfferAccepted was not found in logs.");
7161
- }
7162
7554
  return {
7163
7555
  txHash,
7164
7556
  receipt,
@@ -7779,6 +8171,7 @@ var liquidFactoryAbi = [
7779
8171
  var TICK_BASE = 1.0001;
7780
8172
  var TICK_LOG_BASE = Math.log(TICK_BASE);
7781
8173
  var TOKEN_BASE_UNITS = 1e18;
8174
+ var SHARE_SCALE_UNITS = 10n ** 18n;
7782
8175
  var RESERVE_TAIL_SHARES_PERCENT = 2;
7783
8176
  var RESERVE_TAIL_END_PRICE_MULTIPLE = 100;
7784
8177
  var SHARES_SUM_TOLERANCE = 1e-6;
@@ -7837,12 +8230,66 @@ function toValidNumber(value) {
7837
8230
  if (typeof value !== "number" || !Number.isFinite(value)) return null;
7838
8231
  return value;
7839
8232
  }
7840
- function toValidShareNumber(value) {
7841
- const numeric = typeof value === "string" ? Number(value) : toValidNumber(value);
7842
- if (numeric === null || numeric <= 0 || numeric > 1) {
8233
+ function toNormalizedShare(value) {
8234
+ if (typeof value === "number") {
8235
+ if (!Number.isFinite(value) || value <= 0 || value > 1) {
8236
+ return null;
8237
+ }
8238
+ return parseShareDecimalString(expandFiniteNumber(value));
8239
+ }
8240
+ if (typeof value !== "string") {
7843
8241
  return null;
7844
8242
  }
7845
- return numeric;
8243
+ return parseShareDecimalString(value);
8244
+ }
8245
+ function expandFiniteNumber(value) {
8246
+ const rawValue = value.toString();
8247
+ const [coefficient = "", exponentValue] = rawValue.toLowerCase().split("e");
8248
+ if (exponentValue === void 0) {
8249
+ return rawValue;
8250
+ }
8251
+ const exponent = Number(exponentValue);
8252
+ const [integerPart = "", fractionalPart = ""] = coefficient.split(".");
8253
+ const digits = `${integerPart}${fractionalPart}`;
8254
+ const decimalIndex = integerPart.length + exponent;
8255
+ if (decimalIndex <= 0) {
8256
+ return `0.${"0".repeat(Math.abs(decimalIndex))}${digits}`;
8257
+ }
8258
+ if (decimalIndex >= digits.length) {
8259
+ return `${digits}${"0".repeat(decimalIndex - digits.length)}`;
8260
+ }
8261
+ return `${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
8262
+ }
8263
+ function parseShareDecimalString(value) {
8264
+ const normalized = value.trim();
8265
+ if (!/^(?:\d+\.?\d*|\.\d+)$/.test(normalized)) {
8266
+ return null;
8267
+ }
8268
+ const shareParts = normalized.startsWith(".") ? ["0", normalized.slice(1)] : normalized.split(".");
8269
+ const integerPart = shareParts[0] ?? "";
8270
+ const fractionalDigits = shareParts[1] ?? "";
8271
+ const excessFractionalDigits = fractionalDigits.slice(18);
8272
+ if (/[1-9]/.test(excessFractionalDigits)) {
8273
+ return null;
8274
+ }
8275
+ const integerUnits = BigInt(integerPart === "" ? "0" : integerPart);
8276
+ const fractionalUnits = BigInt(fractionalDigits.slice(0, 18).padEnd(18, "0"));
8277
+ const scaledUnits = integerUnits * SHARE_SCALE_UNITS + fractionalUnits;
8278
+ if (scaledUnits <= 0n || scaledUnits > SHARE_SCALE_UNITS) {
8279
+ return null;
8280
+ }
8281
+ return {
8282
+ decimal: formatScaledShareDecimal(scaledUnits),
8283
+ scaledUnits
8284
+ };
8285
+ }
8286
+ function formatScaledShareDecimal(scaledUnits) {
8287
+ const integerUnits = scaledUnits / SHARE_SCALE_UNITS;
8288
+ const fractionalUnits = scaledUnits % SHARE_SCALE_UNITS;
8289
+ if (fractionalUnits === 0n) {
8290
+ return integerUnits.toString();
8291
+ }
8292
+ return `${integerUnits}.${fractionalUnits.toString().padStart(18, "0").replace(/0+$/, "")}`;
7846
8293
  }
7847
8294
  function toApproxTokenAmount(value, label) {
7848
8295
  const numeric = typeof value === "number" ? value : Number(value);
@@ -7991,8 +8438,8 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
7991
8438
  if (invalidResult !== void 0) {
7992
8439
  return invalidResult.result;
7993
8440
  }
7994
- const parsedSegments = normalizedResults.filter((result) => result.isValid).map((result) => result.segment);
7995
- const totalPositions = parsedSegments.reduce((sum, segment) => sum + segment.numPositions, 0);
8441
+ const parsedEntries = normalizedResults.filter((result) => result.isValid).map((result) => result.entry);
8442
+ const totalPositions = parsedEntries.reduce((sum, entry) => sum + entry.segment.numPositions, 0);
7996
8443
  if (totalPositions > MAX_TOTAL_POSITIONS) {
7997
8444
  return {
7998
8445
  isValid: false,
@@ -8000,8 +8447,8 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
8000
8447
  errorMessage: `Total positions across all curves must not exceed ${MAX_TOTAL_POSITIONS}`
8001
8448
  };
8002
8449
  }
8003
- const sortedSegments = [...parsedSegments].sort((a, b) => a.tickLower - b.tickLower);
8004
- const hasGapOrOverlap = sortedSegments.slice(1).some((current, index) => current.tickLower !== sortedSegments[index]?.tickUpper);
8450
+ const sortedEntries = [...parsedEntries].sort((a, b) => a.segment.tickLower - b.segment.tickLower);
8451
+ const hasGapOrOverlap = sortedEntries.slice(1).some((current, index) => current.segment.tickLower !== sortedEntries[index]?.segment.tickUpper);
8005
8452
  if (hasGapOrOverlap) {
8006
8453
  return {
8007
8454
  isValid: false,
@@ -8009,10 +8456,11 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
8009
8456
  errorMessage: "Curve segments must be contiguous (no overlap or gaps)"
8010
8457
  };
8011
8458
  }
8012
- const shareSum = sortedSegments.reduce((sum, segment) => sum + Number(segment.shares), 0);
8013
- if (Math.abs(shareSum - 1) > SHARES_SUM_TOLERANCE) {
8459
+ const shareSum = sortedEntries.reduce((sum, entry) => sum + entry.shareScaledUnits, 0n);
8460
+ if (shareSum !== SHARE_SCALE_UNITS) {
8014
8461
  return { isValid: false, error: "share-sum-invalid", errorMessage: "Curve share values must add up to 1" };
8015
8462
  }
8463
+ const sortedSegments = sortedEntries.map((entry) => entry.segment);
8016
8464
  const narrowSegment = sortedSegments.find((segment) => {
8017
8465
  const minSpan = segment.numPositions * tickSpacing;
8018
8466
  return segment.tickUpper - segment.tickLower < minSpan || computeGrossLiquidityAtFarTick(segment.tickLower, segment.tickUpper - segment.tickLower, segment.numPositions, Number(segment.shares), totalCurveSupplyTokens) > MAX_LIQUIDITY_PER_TICK;
@@ -8041,8 +8489,8 @@ function normalizeSegment(segment, tickSpacing) {
8041
8489
  const tickLower = toValidNumber(segment.tickLower);
8042
8490
  const tickUpper = toValidNumber(segment.tickUpper);
8043
8491
  const numPositions = toValidNumber(segment.numPositions);
8044
- const shares = toValidShareNumber(segment.shares);
8045
- if (tickLower === null || tickUpper === null || numPositions === null || shares === null) {
8492
+ const share = toNormalizedShare(segment.shares);
8493
+ if (tickLower === null || tickUpper === null || numPositions === null || share === null) {
8046
8494
  return invalidSegmentResult();
8047
8495
  }
8048
8496
  if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper) || !Number.isInteger(numPositions) || numPositions <= 0) {
@@ -8059,11 +8507,14 @@ function normalizeSegment(segment, tickSpacing) {
8059
8507
  }
8060
8508
  return {
8061
8509
  isValid: true,
8062
- segment: {
8063
- tickLower,
8064
- tickUpper,
8065
- numPositions,
8066
- shares: `${shares}`
8510
+ entry: {
8511
+ segment: {
8512
+ tickLower,
8513
+ tickUpper,
8514
+ numPositions,
8515
+ shares: share.decimal
8516
+ },
8517
+ shareScaledUnits: share.scaledUnits
8067
8518
  }
8068
8519
  };
8069
8520
  }
@@ -8430,9 +8881,23 @@ function missingLiquidEditionAddressError(txHash, receipt, cause) {
8430
8881
  const message = `Liquid Edition deploy transaction succeeded, but the deployed contract address could not be read from the LiquidTokenCreated event logs after ${LIQUID_EDITION_ADDRESS_LOG_RETRY_ATTEMPTS + 1} attempts. Transaction hash: ${txHash}. Block: ${receipt.blockNumber}. The connected RPC may be delayed or returning incomplete receipt logs; retry with a synced RPC or inspect the transaction hash.`;
8431
8882
  return cause instanceof Error ? new Error(message, { cause }) : new Error(message);
8432
8883
  }
8433
- function liquidEditionDeployRevertedError(txHash, receipt) {
8884
+ function liquidEditionRevertedReceiptError(message, txHash, receipt) {
8434
8885
  return new Error(
8435
- `Liquid Edition deploy transaction reverted before emitting LiquidTokenCreated. Transaction hash: ${txHash}. Block: ${receipt.blockNumber}.`
8886
+ `${message} Transaction hash: ${txHash}. Block: ${receipt.blockNumber}.`
8887
+ );
8888
+ }
8889
+ function liquidEditionDeployRevertedError(txHash, receipt) {
8890
+ return liquidEditionRevertedReceiptError(
8891
+ "Liquid Edition deploy transaction reverted before emitting LiquidTokenCreated.",
8892
+ txHash,
8893
+ receipt
8894
+ );
8895
+ }
8896
+ function liquidEditionSetRenderContractRevertedError(txHash, receipt) {
8897
+ return liquidEditionRevertedReceiptError(
8898
+ 'Liquid Edition setRenderContract transaction was confirmed with status "reverted".',
8899
+ txHash,
8900
+ receipt
8436
8901
  );
8437
8902
  }
8438
8903
  async function waitForLiquidEditionAddress(publicClient, txHash) {
@@ -8518,7 +8983,13 @@ function createLiquidNamespace(config, chain, addresses) {
8518
8983
  throw new Error(validation.errorMessage ?? "Invalid curve configuration");
8519
8984
  }
8520
8985
  const initialRareLiquidity = params.initialRareLiquidity !== void 0 ? await toTokenAmount(publicClient, factoryConfig.baseToken, params.initialRareLiquidity, "initialRareLiquidity") : 0n;
8521
- await ensureTokenAllowance(
8986
+ const curves = validation.curves.map((curve) => ({
8987
+ tickLower: curve.tickLower,
8988
+ tickUpper: curve.tickUpper,
8989
+ numPositions: curve.numPositions,
8990
+ shares: parseUnits6(curve.shares, 18)
8991
+ }));
8992
+ const approvalTxHash = await ensureTokenAllowance(
8522
8993
  publicClient,
8523
8994
  walletClient,
8524
8995
  account,
@@ -8527,43 +8998,49 @@ function createLiquidNamespace(config, chain, addresses) {
8527
8998
  liquidFactory,
8528
8999
  initialRareLiquidity
8529
9000
  );
8530
- const curves = validation.curves.map((curve) => ({
8531
- tickLower: curve.tickLower,
8532
- tickUpper: curve.tickUpper,
8533
- numPositions: curve.numPositions,
8534
- shares: parseUnits6(curve.shares, 18)
8535
- }));
8536
- const txHash = customMaxTotalSupply === void 0 ? await walletClient.writeContract({
8537
- address: liquidFactory,
8538
- abi: liquidFactoryAbi,
8539
- functionName: "createLiquidTokenMultiCurve",
8540
- args: [
8541
- accountAddress,
8542
- params.tokenUri,
8543
- params.name,
8544
- params.symbol,
8545
- initialRareLiquidity,
8546
- curves
8547
- ],
8548
- account,
8549
- chain: void 0
8550
- }) : await walletClient.writeContract({
8551
- address: liquidFactory,
8552
- abi: liquidFactoryAbi,
8553
- functionName: "createLiquidTokenMultiCurveWithSupply",
8554
- args: [
8555
- accountAddress,
8556
- params.tokenUri,
8557
- params.name,
8558
- params.symbol,
8559
- initialRareLiquidity,
8560
- curves,
8561
- customMaxTotalSupply
8562
- ],
8563
- account,
8564
- chain: void 0
9001
+ const { txHash, receipt, contract } = await runWithApprovalSideEffectAlert({
9002
+ operation: "liquid edition deploy",
9003
+ approvals: [{
9004
+ type: "erc20",
9005
+ approvalTxHash,
9006
+ target: factoryConfig.baseToken,
9007
+ spender: liquidFactory
9008
+ }],
9009
+ run: async () => {
9010
+ const targetTxHash = customMaxTotalSupply === void 0 ? await walletClient.writeContract({
9011
+ address: liquidFactory,
9012
+ abi: liquidFactoryAbi,
9013
+ functionName: "createLiquidTokenMultiCurve",
9014
+ args: [
9015
+ accountAddress,
9016
+ params.tokenUri,
9017
+ params.name,
9018
+ params.symbol,
9019
+ initialRareLiquidity,
9020
+ curves
9021
+ ],
9022
+ account,
9023
+ chain: void 0
9024
+ }) : await walletClient.writeContract({
9025
+ address: liquidFactory,
9026
+ abi: liquidFactoryAbi,
9027
+ functionName: "createLiquidTokenMultiCurveWithSupply",
9028
+ args: [
9029
+ accountAddress,
9030
+ params.tokenUri,
9031
+ params.name,
9032
+ params.symbol,
9033
+ initialRareLiquidity,
9034
+ curves,
9035
+ customMaxTotalSupply
9036
+ ],
9037
+ account,
9038
+ chain: void 0
9039
+ });
9040
+ const deployed = await waitForLiquidEditionAddress(publicClient, targetTxHash);
9041
+ return { txHash: targetTxHash, receipt: deployed.receipt, contract: deployed.contract };
9042
+ }
8565
9043
  });
8566
- const { receipt, contract } = await waitForLiquidEditionAddress(publicClient, txHash);
8567
9044
  return {
8568
9045
  txHash,
8569
9046
  receipt,
@@ -8598,6 +9075,9 @@ function createLiquidNamespace(config, chain, addresses) {
8598
9075
  chain: void 0
8599
9076
  });
8600
9077
  const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
9078
+ if (receipt.status === "reverted") {
9079
+ throw liquidEditionSetRenderContractRevertedError(txHash, receipt);
9080
+ }
8601
9081
  return {
8602
9082
  txHash,
8603
9083
  receipt,
@@ -8704,6 +9184,312 @@ function createLiquidNamespace(config, chain, addresses) {
8704
9184
  };
8705
9185
  }
8706
9186
 
9187
+ // src/sdk/bridge.ts
9188
+ import { encodeFunctionData } from "viem";
9189
+
9190
+ // src/contracts/abis/rare-bridge.ts
9191
+ var rareBridgeAbi = [
9192
+ {
9193
+ type: "function",
9194
+ name: "getFee",
9195
+ inputs: [
9196
+ {
9197
+ name: "_destinationChainSelector",
9198
+ type: "uint64",
9199
+ internalType: "uint64"
9200
+ },
9201
+ {
9202
+ name: "_destinationChainRecipient",
9203
+ type: "address",
9204
+ internalType: "address"
9205
+ },
9206
+ {
9207
+ name: "_distributionData",
9208
+ type: "bytes",
9209
+ internalType: "bytes"
9210
+ },
9211
+ {
9212
+ name: "_extraArgs",
9213
+ type: "bytes",
9214
+ internalType: "bytes"
9215
+ },
9216
+ {
9217
+ name: "_payFeesInLink",
9218
+ type: "bool",
9219
+ internalType: "bool"
9220
+ }
9221
+ ],
9222
+ outputs: [
9223
+ {
9224
+ name: "fee",
9225
+ type: "uint256",
9226
+ internalType: "uint256"
9227
+ }
9228
+ ],
9229
+ stateMutability: "view"
9230
+ },
9231
+ {
9232
+ type: "function",
9233
+ name: "send",
9234
+ inputs: [
9235
+ {
9236
+ name: "_destinationChainSelector",
9237
+ type: "uint64",
9238
+ internalType: "uint64"
9239
+ },
9240
+ {
9241
+ name: "_destinationChainRecipient",
9242
+ type: "address",
9243
+ internalType: "address"
9244
+ },
9245
+ {
9246
+ name: "_distributionData",
9247
+ type: "bytes",
9248
+ internalType: "bytes"
9249
+ },
9250
+ {
9251
+ name: "_extraArgs",
9252
+ type: "bytes",
9253
+ internalType: "bytes"
9254
+ },
9255
+ {
9256
+ name: "_payFeesInLink",
9257
+ type: "bool",
9258
+ internalType: "bool"
9259
+ }
9260
+ ],
9261
+ outputs: [],
9262
+ stateMutability: "payable"
9263
+ },
9264
+ {
9265
+ type: "event",
9266
+ name: "MessageSent",
9267
+ inputs: [
9268
+ {
9269
+ name: "messageId",
9270
+ type: "bytes32",
9271
+ indexed: true,
9272
+ internalType: "bytes32"
9273
+ },
9274
+ {
9275
+ name: "destinationChainSelector",
9276
+ type: "uint64",
9277
+ indexed: true,
9278
+ internalType: "uint64"
9279
+ },
9280
+ {
9281
+ name: "destinationChainRecipient",
9282
+ type: "address",
9283
+ indexed: true,
9284
+ internalType: "address"
9285
+ },
9286
+ {
9287
+ name: "fee",
9288
+ type: "uint256",
9289
+ indexed: false,
9290
+ internalType: "uint256"
9291
+ },
9292
+ {
9293
+ name: "payFeesInLink",
9294
+ type: "bool",
9295
+ indexed: false,
9296
+ internalType: "bool"
9297
+ }
9298
+ ],
9299
+ anonymous: false
9300
+ }
9301
+ ];
9302
+
9303
+ // src/sdk/bridge-core.ts
9304
+ import { encodeAbiParameters } from "viem";
9305
+ var allowedBridgePairs = [
9306
+ { sourceChain: "mainnet", destinationChain: "base" },
9307
+ { sourceChain: "base", destinationChain: "mainnet" },
9308
+ { sourceChain: "sepolia", destinationChain: "base-sepolia" },
9309
+ { sourceChain: "base-sepolia", destinationChain: "sepolia" }
9310
+ ];
9311
+ function validateBridgeRoute(route) {
9312
+ const supported = allowedBridgePairs.some(
9313
+ (pair) => pair.sourceChain === route.sourceChain && pair.destinationChain === route.destinationChain
9314
+ );
9315
+ if (supported) {
9316
+ return { isValid: true };
9317
+ }
9318
+ return {
9319
+ isValid: false,
9320
+ error: "unsupported_bridge_route",
9321
+ errorMessage: `Unsupported RARE bridge route "${route.sourceChain}" -> "${route.destinationChain}". Supported routes: mainnet <-> base, sepolia <-> base-sepolia.`
9322
+ };
9323
+ }
9324
+ function getBridgeInfo(chain) {
9325
+ return {
9326
+ chain,
9327
+ chainId: chainIds[chain],
9328
+ rareBridgeAddress: getRareBridgeAddress(chain),
9329
+ rareTokenAddress: resolveCurrency("rare", chain),
9330
+ ccipChainSelector: getCcipChainSelector(chain)
9331
+ };
9332
+ }
9333
+ function encodeBridgeDistribution(params) {
9334
+ return encodeAbiParameters(
9335
+ [
9336
+ { name: "recipients", type: "address[]" },
9337
+ { name: "amounts", type: "uint256[]" }
9338
+ ],
9339
+ [[params.recipient], [params.amount]]
9340
+ );
9341
+ }
9342
+ function buildBridgeSendArgs(params) {
9343
+ return [
9344
+ params.destinationBridgeInfo.ccipChainSelector,
9345
+ params.destinationBridgeInfo.rareBridgeAddress,
9346
+ params.distributionData,
9347
+ "0x",
9348
+ false
9349
+ ];
9350
+ }
9351
+ function buildCcipExplorerUrl(txHash) {
9352
+ return `https://ccip.chain.link/tx/${txHash}`;
9353
+ }
9354
+
9355
+ // src/sdk/bridge.ts
9356
+ function createBridgeNamespace(publicClient, config, sourceChain) {
9357
+ return {
9358
+ async quote(params) {
9359
+ return buildBridgeQuote(publicClient, config, sourceChain, params);
9360
+ },
9361
+ async send(params) {
9362
+ return executeBridge(publicClient, config, sourceChain, params);
9363
+ }
9364
+ };
9365
+ }
9366
+ async function executeBridge(publicClient, config, sourceChain, params) {
9367
+ const { walletClient, account, accountAddress } = requireWallet(config);
9368
+ const quote = await buildBridgeQuote(publicClient, config, sourceChain, {
9369
+ ...params,
9370
+ recipient: params.recipient ?? accountAddress
9371
+ }, {
9372
+ estimateGas: false
9373
+ });
9374
+ const approval = await preparePaymentAmountForSpender({
9375
+ publicClient,
9376
+ walletClient,
9377
+ account,
9378
+ accountAddress,
9379
+ spenderAddress: quote.sourceBridgeAddress,
9380
+ currency: quote.rareTokenAddress,
9381
+ requiredAmount: quote.amount,
9382
+ autoApprove: params.autoApprove
9383
+ });
9384
+ const sendArgs = buildBridgeSendArgs({
9385
+ destinationBridgeInfo: getBridgeInfo(quote.destinationChain),
9386
+ distributionData: quote.distributionData
9387
+ });
9388
+ const { txHash, receipt, estimatedGas } = await runWithApprovalSideEffectAlert({
9389
+ operation: "bridge send",
9390
+ approvals: [{
9391
+ type: "erc20",
9392
+ approvalTxHash: approval.approvalTxHash,
9393
+ target: quote.rareTokenAddress,
9394
+ spender: quote.sourceBridgeAddress
9395
+ }],
9396
+ run: async () => {
9397
+ const gas = await estimateBridgeGas(publicClient, {
9398
+ account: accountAddress,
9399
+ sourceBridgeAddress: quote.sourceBridgeAddress,
9400
+ args: sendArgs,
9401
+ nativeFee: quote.nativeFee
9402
+ });
9403
+ const targetTxHash = await walletClient.writeContract({
9404
+ address: quote.sourceBridgeAddress,
9405
+ abi: rareBridgeAbi,
9406
+ functionName: "send",
9407
+ args: sendArgs,
9408
+ value: quote.nativeFee,
9409
+ account,
9410
+ chain: void 0
9411
+ });
9412
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
9413
+ return { txHash: targetTxHash, receipt: targetReceipt, estimatedGas: gas };
9414
+ }
9415
+ });
9416
+ return {
9417
+ ...quote,
9418
+ estimatedGas,
9419
+ txHash,
9420
+ receipt,
9421
+ approvalTxHash: approval.approvalTxHash,
9422
+ ccipExplorerUrl: buildCcipExplorerUrl(txHash)
9423
+ };
9424
+ }
9425
+ async function buildBridgeQuote(publicClient, config, sourceChain, params, options = {}) {
9426
+ const routeValidation = validateBridgeRoute({
9427
+ sourceChain,
9428
+ destinationChain: params.destinationChain
9429
+ });
9430
+ if (!routeValidation.isValid) {
9431
+ throw new Error(routeValidation.errorMessage);
9432
+ }
9433
+ const sourceBridgeInfo = getBridgeInfo(sourceChain);
9434
+ const destinationBridgeInfo = getBridgeInfo(params.destinationChain);
9435
+ const recipient = resolveRecipient(params.recipient, config);
9436
+ const amount = toPositiveWei(params.amount, "amount");
9437
+ const distributionData = encodeBridgeDistribution({ recipient, amount });
9438
+ const args = buildBridgeSendArgs({
9439
+ destinationBridgeInfo,
9440
+ distributionData
9441
+ });
9442
+ const nativeFee = await publicClient.readContract({
9443
+ address: sourceBridgeInfo.rareBridgeAddress,
9444
+ abi: rareBridgeAbi,
9445
+ functionName: "getFee",
9446
+ args
9447
+ });
9448
+ const estimatedGas = options.estimateGas === false ? void 0 : await estimateBridgeGas(publicClient, {
9449
+ account: getConfiguredAccountAddress(config),
9450
+ sourceBridgeAddress: sourceBridgeInfo.rareBridgeAddress,
9451
+ args,
9452
+ nativeFee
9453
+ });
9454
+ return {
9455
+ sourceChain,
9456
+ sourceChainId: sourceBridgeInfo.chainId,
9457
+ destinationChain: params.destinationChain,
9458
+ destinationChainId: destinationBridgeInfo.chainId,
9459
+ sourceBridgeAddress: sourceBridgeInfo.rareBridgeAddress,
9460
+ destinationBridgeAddress: destinationBridgeInfo.rareBridgeAddress,
9461
+ rareTokenAddress: sourceBridgeInfo.rareTokenAddress,
9462
+ destinationCcipChainSelector: destinationBridgeInfo.ccipChainSelector,
9463
+ amount,
9464
+ recipient,
9465
+ distributionData,
9466
+ nativeFee,
9467
+ estimatedGas
9468
+ };
9469
+ }
9470
+ function resolveRecipient(recipient, config) {
9471
+ const resolved = recipient ?? getConfiguredAccountAddress(config);
9472
+ if (resolved === void 0) {
9473
+ throw new Error("No recipient available for bridge quote. Pass params.recipient or provide config.account/walletClient with an account.");
9474
+ }
9475
+ return resolved;
9476
+ }
9477
+ async function estimateBridgeGas(publicClient, params) {
9478
+ if (params.account === void 0) {
9479
+ return void 0;
9480
+ }
9481
+ return publicClient.estimateGas({
9482
+ account: params.account,
9483
+ to: params.sourceBridgeAddress,
9484
+ data: encodeFunctionData({
9485
+ abi: rareBridgeAbi,
9486
+ functionName: "send",
9487
+ args: params.args
9488
+ }),
9489
+ value: params.nativeFee
9490
+ });
9491
+ }
9492
+
8707
9493
  // src/contracts/abis/liquid-router.ts
8708
9494
  var liquidRouterAbi = [
8709
9495
  {
@@ -8754,7 +9540,7 @@ var liquidRouterAbi = [
8754
9540
  ];
8755
9541
 
8756
9542
  // src/swap/known-pools.ts
8757
- import { getAddress as getAddress6 } from "viem";
9543
+ import { getAddress as getAddress7 } from "viem";
8758
9544
 
8759
9545
  // src/swap/pool-core.ts
8760
9546
  function normalizeAddress(value) {
@@ -8773,10 +9559,10 @@ function inferBaseCurrencyAddress(poolKey, token) {
8773
9559
 
8774
9560
  // src/swap/known-pools.ts
8775
9561
  var wrappedEthAddresses = {
8776
- mainnet: getAddress6("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
8777
- sepolia: getAddress6("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"),
8778
- base: getAddress6("0x4200000000000000000000000000000000000006"),
8779
- "base-sepolia": getAddress6("0x4200000000000000000000000000000000000006")
9562
+ mainnet: getAddress7("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
9563
+ sepolia: getAddress7("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"),
9564
+ base: getAddress7("0x4200000000000000000000000000000000000006"),
9565
+ "base-sepolia": getAddress7("0x4200000000000000000000000000000000000006")
8780
9566
  };
8781
9567
  function poolToKey(pool) {
8782
9568
  return {
@@ -9090,9 +9876,9 @@ async function quoteRouteSteps(publicClient, quoterAddress, routeSteps, currentA
9090
9876
 
9091
9877
  // src/swap/route-encoding.ts
9092
9878
  import {
9093
- encodeAbiParameters,
9094
- encodePacked as encodePacked2,
9095
- getAddress as getAddress7,
9879
+ encodeAbiParameters as encodeAbiParameters2,
9880
+ encodePacked as encodePacked3,
9881
+ getAddress as getAddress8,
9096
9882
  parseAbiParameters
9097
9883
  } from "viem";
9098
9884
  var ROUTER_COMMANDS = {
@@ -9109,8 +9895,8 @@ var V4_ACTIONS = {
9109
9895
  TAKE_ALL: 15
9110
9896
  };
9111
9897
  var ROUTER_RECIPIENTS = {
9112
- msgSender: getAddress7("0x0000000000000000000000000000000000000001"),
9113
- addressThis: getAddress7("0x0000000000000000000000000000000000000002")
9898
+ msgSender: getAddress8("0x0000000000000000000000000000000000000001"),
9899
+ addressThis: getAddress8("0x0000000000000000000000000000000000000002")
9114
9900
  };
9115
9901
  var ROUTER_AMOUNT_CONSTANTS = {
9116
9902
  openDelta: 0n,
@@ -9122,7 +9908,7 @@ function encodeRoute(quote, amountIn, currencyIn, currencyOut) {
9122
9908
  }
9123
9909
  const { commandBytes, inputs } = encodeRouteParts(quote, amountIn, currencyIn, currencyOut, 0);
9124
9910
  return {
9125
- commands: encodePacked2(commandBytes.map(() => "uint8"), [...commandBytes]),
9911
+ commands: encodePacked3(commandBytes.map(() => "uint8"), [...commandBytes]),
9126
9912
  inputs
9127
9913
  };
9128
9914
  }
@@ -9202,13 +9988,13 @@ function getV4ExecutionMode(v4BlockStartIndex, nextIndex, routeLength) {
9202
9988
  };
9203
9989
  }
9204
9990
  function encodeWrapEth(recipient, amount) {
9205
- return encodeAbiParameters(
9991
+ return encodeAbiParameters2(
9206
9992
  parseAbiParameters("address recipient, uint256 amount"),
9207
9993
  [recipient, amount]
9208
9994
  );
9209
9995
  }
9210
9996
  function encodeUnwrapWeth(recipient, amountMinimum) {
9211
- return encodeAbiParameters(
9997
+ return encodeAbiParameters2(
9212
9998
  parseAbiParameters("address recipient, uint256 amountMinimum"),
9213
9999
  [recipient, amountMinimum]
9214
10000
  );
@@ -9228,23 +10014,23 @@ function encodeV4ExactIn({
9228
10014
  step.poolKey.hooks,
9229
10015
  "0x"
9230
10016
  ]);
9231
- const swapParams = encodeAbiParameters(
10017
+ const swapParams = encodeAbiParameters2(
9232
10018
  parseAbiParameters("(address,(address,uint24,int24,address,bytes)[],uint128,uint128)"),
9233
10019
  [[currencyIn, pathKeysArray, amountIn, minAmountOut]]
9234
10020
  );
9235
10021
  const settleAction = executionMode.inputSource === "user" ? V4_ACTIONS.SETTLE_ALL : V4_ACTIONS.SETTLE;
9236
- const settleParams = executionMode.inputSource === "user" ? encodeAbiParameters(
10022
+ const settleParams = executionMode.inputSource === "user" ? encodeAbiParameters2(
9237
10023
  parseAbiParameters("address currency, uint128 maxAmount"),
9238
10024
  [currencyIn, amountIn]
9239
- ) : encodeAbiParameters(
10025
+ ) : encodeAbiParameters2(
9240
10026
  parseAbiParameters("address currency, uint256 amount, bool payerIsUser"),
9241
10027
  [currencyIn, ROUTER_AMOUNT_CONSTANTS.contractBalance, false]
9242
10028
  );
9243
10029
  const takeAction = executionMode.outputTarget === "user" ? V4_ACTIONS.TAKE_ALL : V4_ACTIONS.TAKE;
9244
- const takeParams = executionMode.outputTarget === "user" ? encodeAbiParameters(
10030
+ const takeParams = executionMode.outputTarget === "user" ? encodeAbiParameters2(
9245
10031
  parseAbiParameters("address currency, uint128 minAmount"),
9246
10032
  [currencyOut, minAmountOut]
9247
- ) : encodeAbiParameters(
10033
+ ) : encodeAbiParameters2(
9248
10034
  parseAbiParameters("address currency, address recipient, uint256 amount"),
9249
10035
  [currencyOut, ROUTER_RECIPIENTS.addressThis, ROUTER_AMOUNT_CONSTANTS.openDelta]
9250
10036
  );
@@ -9253,11 +10039,11 @@ function encodeV4ExactIn({
9253
10039
  if (singleStep === void 0) {
9254
10040
  throw new Error("Missing V4 exact input single step.");
9255
10041
  }
9256
- const actions2 = encodePacked2(
10042
+ const actions2 = encodePacked3(
9257
10043
  ["uint8", "uint8", "uint8"],
9258
10044
  [settleAction, V4_ACTIONS.SWAP_EXACT_IN_SINGLE, takeAction]
9259
10045
  );
9260
- return encodeAbiParameters(
10046
+ return encodeAbiParameters2(
9261
10047
  parseAbiParameters("bytes actions, bytes[] params"),
9262
10048
  [
9263
10049
  actions2,
@@ -9269,11 +10055,11 @@ function encodeV4ExactIn({
9269
10055
  ]
9270
10056
  );
9271
10057
  }
9272
- const actions = encodePacked2(
10058
+ const actions = encodePacked3(
9273
10059
  ["uint8", "uint8", "uint8"],
9274
10060
  [V4_ACTIONS.SWAP_EXACT_IN, settleAction, takeAction]
9275
10061
  );
9276
- return encodeAbiParameters(
10062
+ return encodeAbiParameters2(
9277
10063
  parseAbiParameters("bytes actions, bytes[] params"),
9278
10064
  [actions, [swapParams, settleParams, takeParams]]
9279
10065
  );
@@ -9292,17 +10078,17 @@ function encodeV4ExactInSingle(step, amountIn, minAmountOut) {
9292
10078
  minAmountOut,
9293
10079
  "0x"
9294
10080
  ];
9295
- return encodeAbiParameters(
10081
+ return encodeAbiParameters2(
9296
10082
  parseAbiParameters("((address,address,uint24,int24,address),bool,uint128,uint128,bytes)"),
9297
10083
  [swapExactInSingleTuple]
9298
10084
  );
9299
10085
  }
9300
10086
 
9301
10087
  // src/swap/uniswap-api.ts
9302
- import { getAddress as getAddress8, isHex as isHex3 } from "viem";
10088
+ import { getAddress as getAddress9, isHex as isHex4 } from "viem";
9303
10089
 
9304
10090
  // src/swap/trade-core.ts
9305
- import { isAddressEqual as isAddressEqual14 } from "viem";
10091
+ import { isAddressEqual as isAddressEqual15 } from "viem";
9306
10092
  function toTradeInteger(value, field) {
9307
10093
  if (typeof value === "bigint") return value;
9308
10094
  if (typeof value === "number") {
@@ -9370,7 +10156,7 @@ function buildLiquidRouterTradeQuote(params) {
9370
10156
  }
9371
10157
  function getQuotedRecipientAmount(quote, recipient) {
9372
10158
  const recipientOutput = quote.aggregatedOutputs?.find(
9373
- (output) => isAddressEqual14(output.recipient, recipient)
10159
+ (output) => isAddressEqual15(output.recipient, recipient)
9374
10160
  );
9375
10161
  if (recipientOutput) {
9376
10162
  return {
@@ -9389,7 +10175,7 @@ function assertSupportedUniswapRouting(routing) {
9389
10175
  }
9390
10176
  }
9391
10177
  function assertRecipientSupportedForUniswapFallback(recipient, accountAddress) {
9392
- if (recipient !== void 0 && !isAddressEqual14(recipient, accountAddress)) {
10178
+ if (recipient !== void 0 && !isAddressEqual15(recipient, accountAddress)) {
9393
10179
  throw new Error("recipient override is not supported for Uniswap API fallback routes.");
9394
10180
  }
9395
10181
  }
@@ -9469,7 +10255,7 @@ function parseNumber(value, field) {
9469
10255
  function parseAddress2(value, field) {
9470
10256
  const raw = parseString(value, field);
9471
10257
  try {
9472
- return getAddress8(raw);
10258
+ return getAddress9(raw);
9473
10259
  } catch {
9474
10260
  throw new Error(`Uniswap API response field "${field}" must be a valid EVM address.`);
9475
10261
  }
@@ -9479,7 +10265,7 @@ function parseOptionalAddress(value, field) {
9479
10265
  }
9480
10266
  function parseHex(value, field) {
9481
10267
  const raw = parseString(value, field);
9482
- if (!isHex3(raw)) {
10268
+ if (!isHex4(raw)) {
9483
10269
  throw new Error(`Uniswap API response field "${field}" must be a hex string.`);
9484
10270
  }
9485
10271
  return raw;
@@ -9899,7 +10685,7 @@ async function executeRawRouterBuy(params) {
9899
10685
  const minAmountOutInput = requireInput(params.minAmountOut, "minAmountOut");
9900
10686
  const ethAmount = toWei(amountIn);
9901
10687
  const minTokensOut = await toTokenAmount(params.publicClient, params.token, minAmountOutInput, "minAmountOut");
9902
- const txHash = await walletClient.writeContract({
10688
+ const targetTxHash = await walletClient.writeContract({
9903
10689
  address: router,
9904
10690
  abi: liquidRouterAbi,
9905
10691
  functionName: "buy",
@@ -9908,8 +10694,8 @@ async function executeRawRouterBuy(params) {
9908
10694
  chain: void 0,
9909
10695
  value: ethAmount
9910
10696
  });
9911
- const receipt = await params.publicClient.waitForTransactionReceipt({ hash: txHash });
9912
- return { txHash, receipt, minAmountOut: minTokensOut };
10697
+ const targetReceipt = await params.publicClient.waitForTransactionReceipt({ hash: targetTxHash });
10698
+ return { txHash: targetTxHash, receipt: targetReceipt, minAmountOut: minTokensOut };
9913
10699
  }
9914
10700
  async function executeRawRouterSell(params) {
9915
10701
  const { walletClient, account, accountAddress } = requireWallet(params.config);
@@ -9919,25 +10705,37 @@ async function executeRawRouterSell(params) {
9919
10705
  const minAmountOutInput = requireInput(params.minAmountOut, "minAmountOut");
9920
10706
  const tokenAmount = await toTokenAmount(params.publicClient, params.token, amountIn, "amountIn");
9921
10707
  const minEthOut = toWei(minAmountOutInput);
9922
- await ensureTokenAllowance(params.publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
9923
- const txHash = await walletClient.writeContract({
9924
- address: router,
9925
- abi: liquidRouterAbi,
9926
- functionName: "sell",
9927
- args: [
9928
- params.token,
9929
- tokenAmount,
9930
- params.recipient ?? accountAddress,
9931
- minEthOut,
9932
- params.commands,
9933
- [...params.inputs],
9934
- resolveDeadline(params.deadline)
9935
- ],
9936
- account,
9937
- chain: void 0
10708
+ const approvalTxHash = await ensureTokenAllowance(params.publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
10709
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
10710
+ operation: "swap sell",
10711
+ approvals: [{
10712
+ type: "erc20",
10713
+ approvalTxHash,
10714
+ target: params.token,
10715
+ spender: router
10716
+ }],
10717
+ run: async () => {
10718
+ const targetTxHash = await walletClient.writeContract({
10719
+ address: router,
10720
+ abi: liquidRouterAbi,
10721
+ functionName: "sell",
10722
+ args: [
10723
+ params.token,
10724
+ tokenAmount,
10725
+ params.recipient ?? accountAddress,
10726
+ minEthOut,
10727
+ params.commands,
10728
+ [...params.inputs],
10729
+ resolveDeadline(params.deadline)
10730
+ ],
10731
+ account,
10732
+ chain: void 0
10733
+ });
10734
+ const targetReceipt = await params.publicClient.waitForTransactionReceipt({ hash: targetTxHash });
10735
+ return { txHash: targetTxHash, receipt: targetReceipt };
10736
+ }
9938
10737
  });
9939
- const receipt = await params.publicClient.waitForTransactionReceipt({ hash: txHash });
9940
- return { txHash, receipt, minAmountOut: minEthOut, tokenAmount };
10738
+ return { txHash, receipt, minAmountOut: minEthOut, tokenAmount, approvalTxHash };
9941
10739
  }
9942
10740
  function isRawTokenTradeParams(params) {
9943
10741
  return params.route === "raw";
@@ -9981,28 +10779,38 @@ function createSwapNamespace(config, chain, chainId, addresses) {
9981
10779
  validateRouterPayload(params.commands, params.inputs);
9982
10780
  const amountIn = await toTokenAmount(publicClient, params.tokenIn, params.amountIn, "amountIn");
9983
10781
  const minAmountOut = await toTokenAmount(publicClient, params.tokenOut, params.minAmountOut, "minAmountOut");
9984
- if (params.tokenIn !== ETH_ADDRESS) {
9985
- await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.tokenIn, router, amountIn);
9986
- }
9987
- const txHash = await walletClient.writeContract({
9988
- address: router,
9989
- abi: liquidRouterAbi,
9990
- functionName: "swap",
9991
- args: [
9992
- params.tokenIn,
9993
- amountIn,
9994
- params.tokenOut,
9995
- params.recipient ?? accountAddress,
9996
- minAmountOut,
9997
- params.commands,
9998
- [...params.inputs],
9999
- resolveDeadline(params.deadline)
10000
- ],
10001
- account,
10002
- chain: void 0,
10003
- value: params.tokenIn === ETH_ADDRESS ? amountIn : void 0
10782
+ const approvalTxHash = params.tokenIn === ETH_ADDRESS ? void 0 : await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.tokenIn, router, amountIn);
10783
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
10784
+ operation: "swap tokens",
10785
+ approvals: [{
10786
+ type: "erc20",
10787
+ approvalTxHash,
10788
+ target: params.tokenIn,
10789
+ spender: router
10790
+ }],
10791
+ run: async () => {
10792
+ const targetTxHash = await walletClient.writeContract({
10793
+ address: router,
10794
+ abi: liquidRouterAbi,
10795
+ functionName: "swap",
10796
+ args: [
10797
+ params.tokenIn,
10798
+ amountIn,
10799
+ params.tokenOut,
10800
+ params.recipient ?? accountAddress,
10801
+ minAmountOut,
10802
+ params.commands,
10803
+ [...params.inputs],
10804
+ resolveDeadline(params.deadline)
10805
+ ],
10806
+ account,
10807
+ chain: void 0,
10808
+ value: params.tokenIn === ETH_ADDRESS ? amountIn : void 0
10809
+ });
10810
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
10811
+ return { txHash: targetTxHash, receipt: targetReceipt };
10812
+ }
10004
10813
  });
10005
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
10006
10814
  return { txHash, receipt };
10007
10815
  },
10008
10816
  async quoteBuyToken(params) {
@@ -10069,7 +10877,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10069
10877
  });
10070
10878
  if (quoteDetails.kind === "local") {
10071
10879
  const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
10072
- const txHash = await walletClient.writeContract({
10880
+ const targetTxHash = await walletClient.writeContract({
10073
10881
  address: router,
10074
10882
  abi: liquidRouterAbi,
10075
10883
  functionName: "buy",
@@ -10085,10 +10893,10 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10085
10893
  chain: void 0,
10086
10894
  value: quoteDetails.quote.amountIn
10087
10895
  });
10088
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
10896
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
10089
10897
  return {
10090
- txHash,
10091
- receipt,
10898
+ txHash: targetTxHash,
10899
+ receipt: targetReceipt,
10092
10900
  estimatedAmountOut: quoteDetails.quote.estimatedAmountOut,
10093
10901
  minAmountOut: quoteDetails.quote.minAmountOut,
10094
10902
  routeSource: quoteDetails.quote.routeSource,
@@ -10180,24 +10988,36 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10180
10988
  const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
10181
10989
  const amountIn = requireInput(params.amountIn, "amountIn");
10182
10990
  const tokenAmount = await toTokenAmount(publicClient, params.token, amountIn, "amountIn");
10183
- await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
10184
- const txHash = await walletClient.writeContract({
10185
- address: router,
10186
- abi: liquidRouterAbi,
10187
- functionName: "sell",
10188
- args: [
10189
- params.token,
10190
- tokenAmount,
10191
- params.recipient ?? accountAddress,
10192
- quoteDetails.quote.minAmountOut,
10193
- quoteDetails.quote.commands,
10194
- [...quoteDetails.quote.inputs],
10195
- resolveDeadline(params.deadline)
10196
- ],
10197
- account,
10198
- chain: void 0
10991
+ const approvalTxHash2 = await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
10992
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
10993
+ operation: "sell token",
10994
+ approvals: [{
10995
+ type: "erc20",
10996
+ approvalTxHash: approvalTxHash2,
10997
+ target: params.token,
10998
+ spender: router
10999
+ }],
11000
+ run: async () => {
11001
+ const targetTxHash = await walletClient.writeContract({
11002
+ address: router,
11003
+ abi: liquidRouterAbi,
11004
+ functionName: "sell",
11005
+ args: [
11006
+ params.token,
11007
+ tokenAmount,
11008
+ params.recipient ?? accountAddress,
11009
+ quoteDetails.quote.minAmountOut,
11010
+ quoteDetails.quote.commands,
11011
+ [...quoteDetails.quote.inputs],
11012
+ resolveDeadline(params.deadline)
11013
+ ],
11014
+ account,
11015
+ chain: void 0
11016
+ });
11017
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
11018
+ return { txHash: targetTxHash, receipt: targetReceipt };
11019
+ }
10199
11020
  });
10200
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
10201
11021
  return {
10202
11022
  txHash,
10203
11023
  receipt,
@@ -10206,7 +11026,8 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10206
11026
  routeSource: quoteDetails.quote.routeSource,
10207
11027
  execution: quoteDetails.quote.execution,
10208
11028
  commands: quoteDetails.quote.commands,
10209
- inputs: quoteDetails.quote.inputs
11029
+ inputs: quoteDetails.quote.inputs,
11030
+ approvalTxHash: approvalTxHash2
10210
11031
  };
10211
11032
  }
10212
11033
  const approval = await requestUniswapApproval({
@@ -10225,14 +11046,33 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10225
11046
  accountAddress,
10226
11047
  chainId
10227
11048
  })).txHash : void 0;
10228
- const swapResponse = await requestUniswapSwap({
10229
- apiKey: quoteDetails.apiKey,
10230
- quote: quoteDetails.rawQuote,
10231
- deadline: uniswapDeadline
10232
- });
10233
- const sent = await sendPreparedTransaction(publicClient, walletClient, account, swapResponse.swap, {
10234
- accountAddress,
10235
- chainId
11049
+ const sent = await runWithApprovalSideEffectAlert({
11050
+ operation: "sell token",
11051
+ approvals: [
11052
+ {
11053
+ type: "erc20-reset",
11054
+ approvalTxHash: approvalResetTxHash,
11055
+ target: params.token,
11056
+ spender: approval.cancel?.to
11057
+ },
11058
+ {
11059
+ type: "erc20",
11060
+ approvalTxHash,
11061
+ target: params.token,
11062
+ spender: approval.approval?.to
11063
+ }
11064
+ ],
11065
+ run: async () => {
11066
+ const swapResponse = await requestUniswapSwap({
11067
+ apiKey: quoteDetails.apiKey,
11068
+ quote: quoteDetails.rawQuote,
11069
+ deadline: uniswapDeadline
11070
+ });
11071
+ return sendPreparedTransaction(publicClient, walletClient, account, swapResponse.swap, {
11072
+ accountAddress,
11073
+ chainId
11074
+ });
11075
+ }
10236
11076
  });
10237
11077
  return {
10238
11078
  ...sent,
@@ -10251,7 +11091,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10251
11091
  const { walletClient, account, accountAddress } = requireWallet(config);
10252
11092
  const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
10253
11093
  const quote = await buildBuyRareQuote(publicClient, chain, addresses, params);
10254
- const txHash = await walletClient.writeContract({
11094
+ const targetTxHash = await walletClient.writeContract({
10255
11095
  address: router,
10256
11096
  abi: liquidRouterAbi,
10257
11097
  functionName: "buy",
@@ -10260,10 +11100,10 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10260
11100
  chain: void 0,
10261
11101
  value: quote.ethAmount
10262
11102
  });
10263
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
11103
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
10264
11104
  return {
10265
- txHash,
10266
- receipt,
11105
+ txHash: targetTxHash,
11106
+ receipt: targetReceipt,
10267
11107
  estimatedRareOut: quote.estimatedRareOut,
10268
11108
  minRareOut: quote.minRareOut,
10269
11109
  commands: quote.commands,
@@ -10277,7 +11117,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
10277
11117
  import {
10278
11118
  erc20Abi as erc20Abi2,
10279
11119
  hexToBigInt as hexToBigInt2,
10280
- isAddressEqual as isAddressEqual16,
11120
+ isAddressEqual as isAddressEqual17,
10281
11121
  parseEventLogs as parseEventLogs6
10282
11122
  } from "viem";
10283
11123
 
@@ -10599,9 +11439,32 @@ var rareMinterAbi = [
10599
11439
  ];
10600
11440
 
10601
11441
  // src/sdk/collection-core.ts
11442
+ var lazySovereignCollectionContractTypes = [
11443
+ "lazy",
11444
+ "lazy-royalty-guard",
11445
+ "lazy-deadman-royalty-guard"
11446
+ ];
10602
11447
  var defaultRoyaltyInfoSalePrice = 10000n;
11448
+ function normalizeLazySovereignCollectionContractType(input) {
11449
+ if (input === void 0) {
11450
+ return void 0;
11451
+ }
11452
+ const normalized = input.trim().toLowerCase();
11453
+ if (normalized === "lazy" || normalized === "standard" || normalized === "lazy-sovereign" || normalized === "lazy-sovereign-nft") {
11454
+ return "lazy";
11455
+ }
11456
+ if (normalized === "lazy-royalty-guard" || normalized === "royalty-guard") {
11457
+ return "lazy-royalty-guard";
11458
+ }
11459
+ if (normalized === "lazy-deadman-royalty-guard" || normalized === "lazy-royalty-guard-deadman" || normalized === "deadman-royalty-guard" || normalized === "royalty-guard-deadman" || normalized === "deadman") {
11460
+ return "lazy-deadman-royalty-guard";
11461
+ }
11462
+ throw new Error(
11463
+ `Unsupported Lazy Sovereign collection contract type "${input}". Supported: ${lazySovereignCollectionContractTypes.join(", ")}.`
11464
+ );
11465
+ }
10603
11466
  function planCreateLazySovereignCollection(params) {
10604
- const contractType = params.contractType ?? "lazy";
11467
+ const contractType = normalizeLazySovereignCollectionContractType(params.contractType) ?? "lazy";
10605
11468
  return {
10606
11469
  name: params.name,
10607
11470
  symbol: params.symbol,
@@ -10759,11 +11622,11 @@ function toRoyaltyPercentage(value) {
10759
11622
 
10760
11623
  // src/sdk/release-core.ts
10761
11624
  import {
10762
- getAddress as getAddress9,
10763
- isAddress as isAddress5,
10764
- isAddressEqual as isAddressEqual15,
10765
- isHex as isHex4,
10766
- keccak256 as keccak2562,
11625
+ getAddress as getAddress10,
11626
+ isAddress as isAddress6,
11627
+ isAddressEqual as isAddressEqual16,
11628
+ isHex as isHex5,
11629
+ keccak256 as keccak2563,
10767
11630
  parseEther as parseEther2,
10768
11631
  parseUnits as parseUnits7
10769
11632
  } from "viem";
@@ -10780,7 +11643,7 @@ function requireRareMinterAddress(address) {
10780
11643
  }
10781
11644
  function assertReleaseContractOwner(opts) {
10782
11645
  const { contract, accountAddress, owner } = opts;
10783
- if (!isAddressEqual15(owner, accountAddress)) {
11646
+ if (!isAddressEqual16(owner, accountAddress)) {
10784
11647
  throw new Error(
10785
11648
  `Connected wallet ${accountAddress} is not the owner of collection ${contract}. Contract owner is ${owner}.`
10786
11649
  );
@@ -10969,7 +11832,7 @@ function parseReleaseAllowlistCsv(input) {
10969
11832
  throw new Error("CSV allowlist is empty.");
10970
11833
  }
10971
11834
  const headerColumn = findAllowlistAddressColumn(firstRow.fields);
10972
- if (headerColumn === -1 && !isAddress5(firstRow.fields[0]?.trim() ?? "")) {
11835
+ if (headerColumn === -1 && !isAddress6(firstRow.fields[0]?.trim() ?? "")) {
10973
11836
  throw new Error("CSV allowlist must put wallet addresses in the first column or include an address/wallet header.");
10974
11837
  }
10975
11838
  const addressColumn = headerColumn === -1 ? 0 : headerColumn;
@@ -11028,27 +11891,27 @@ function buildReleaseAllowlistArtifact(wallets) {
11028
11891
  };
11029
11892
  }
11030
11893
  function getReleaseAllowlistProof(opts) {
11031
- const address = getAddress9(opts.address);
11894
+ const address = getAddress10(opts.address);
11032
11895
  return opts.artifact.wallets.find((entry) => addressesEqual(entry.address, address)) ?? null;
11033
11896
  }
11034
11897
  function verifyReleaseAllowlistProof(opts) {
11035
11898
  const root = normalizeBytes322(opts.root, "allowlist root");
11036
11899
  const hash = opts.proof.reduce(
11037
11900
  (current, sibling) => hashMerklePair(current, normalizeBytes322(sibling, "allowlist proof item")),
11038
- hashAllowlistAddress(getAddress9(opts.address))
11901
+ hashAllowlistAddress(getAddress10(opts.address))
11039
11902
  );
11040
11903
  return hexEquals(hash, root);
11041
11904
  }
11042
11905
  function preflightReleaseDirectSaleMint(params) {
11043
11906
  const { status, plan, buyer, nowSeconds } = params;
11044
11907
  const quantity = BigInt(plan.quantity);
11045
- if (!isAddressEqual15(status.contract, plan.contract)) {
11908
+ if (!isAddressEqual16(status.contract, plan.contract)) {
11046
11909
  throw new Error(`Release status is for ${status.contract}, but mint plan is for ${plan.contract}.`);
11047
11910
  }
11048
11911
  if (!status.configured) {
11049
11912
  throw new Error("RareMinter direct sale is not configured for this contract.");
11050
11913
  }
11051
- if (plan.recipient !== void 0 && !isAddressEqual15(plan.recipient, buyer)) {
11914
+ if (plan.recipient !== void 0 && !isAddressEqual16(plan.recipient, buyer)) {
11052
11915
  throw new Error("RareMinter direct sale mint does not support a separate recipient; it mints to the connected wallet.");
11053
11916
  }
11054
11917
  if (status.startTime > nowSeconds) {
@@ -11072,7 +11935,7 @@ function preflightReleaseDirectSaleMint(params) {
11072
11935
  throw new Error("buyer has reached the per-wallet transaction limit.");
11073
11936
  }
11074
11937
  }
11075
- if (plan.currency !== void 0 && !isAddressEqual15(plan.currency, status.currencyAddress)) {
11938
+ if (plan.currency !== void 0 && !isAddressEqual16(plan.currency, status.currencyAddress)) {
11076
11939
  throw new Error(`expected currency ${plan.currency} does not match configured currency ${status.currencyAddress}.`);
11077
11940
  }
11078
11941
  const price = plan.price === void 0 ? status.price : normalizeReleasePrice({
@@ -11206,11 +12069,11 @@ function requireReleaseAccountCounter(value, label) {
11206
12069
  return value;
11207
12070
  }
11208
12071
  function normalizeBytes322(value, field) {
11209
- if (typeof value !== "string" || !isHex4(value) || value.length !== 66) {
12072
+ if (typeof value !== "string" || !isHex5(value) || value.length !== 66) {
11210
12073
  throw new Error(`${field} must be a 32-byte hex string.`);
11211
12074
  }
11212
12075
  const normalized = value.toLocaleLowerCase();
11213
- if (!isHex4(normalized) || normalized.length !== 66) {
12076
+ if (!isHex5(normalized) || normalized.length !== 66) {
11214
12077
  throw new Error(`${field} must be a 32-byte hex string.`);
11215
12078
  }
11216
12079
  return normalized;
@@ -11280,11 +12143,11 @@ function normalizeAllowlistRows(rows) {
11280
12143
  throw new Error(`Invalid allowlist address at ${row.label}: expected a string.`);
11281
12144
  }
11282
12145
  const raw = row.value.trim();
11283
- if (!isAddress5(raw)) {
12146
+ if (!isAddress6(raw)) {
11284
12147
  throw new Error(`Invalid allowlist address at ${row.label}: "${raw}".`);
11285
12148
  }
11286
- const address = getAddress9(raw);
11287
- const duplicate = state.seen.find((seen) => isAddressEqual15(seen.address, address));
12149
+ const address = getAddress10(raw);
12150
+ const duplicate = state.seen.find((seen) => isAddressEqual16(seen.address, address));
11288
12151
  if (duplicate !== void 0) {
11289
12152
  throw new Error(`Duplicate allowlist address at ${row.label}: "${address}" duplicates ${duplicate.label}.`);
11290
12153
  }
@@ -11340,11 +12203,11 @@ function getMerkleRoot(layers) {
11340
12203
  return root;
11341
12204
  }
11342
12205
  function hashAllowlistAddress(address) {
11343
- return keccak2562(address);
12206
+ return keccak2563(address);
11344
12207
  }
11345
12208
  function hashMerklePair(a, b) {
11346
12209
  const [left, right] = compareHex(a, b) <= 0 ? [a, b] : [b, a];
11347
- return keccak2562(`0x${left.slice(2)}${right.slice(2)}`);
12210
+ return keccak2563(`0x${left.slice(2)}${right.slice(2)}`);
11348
12211
  }
11349
12212
  function compareAddress(a, b) {
11350
12213
  return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
@@ -11353,7 +12216,7 @@ function compareHex(a, b) {
11353
12216
  return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
11354
12217
  }
11355
12218
  function addressesEqual(a, b) {
11356
- return isAddressEqual15(a, b);
12219
+ return isAddressEqual16(a, b);
11357
12220
  }
11358
12221
  function hexEquals(a, b) {
11359
12222
  return a.toLocaleLowerCase() === b.toLocaleLowerCase();
@@ -11428,10 +12291,8 @@ async function readReleaseCollectionOwner(publicClient, contract) {
11428
12291
  );
11429
12292
  }
11430
12293
  }
11431
- async function assertConfigurableReleaseContract(opts) {
12294
+ async function assertReleaseMinterCanMint(opts) {
11432
12295
  const { publicClient, contract, accountAddress, rareMinter } = opts;
11433
- const owner = await readReleaseCollectionOwner(publicClient, contract);
11434
- assertReleaseContractOwner({ contract, accountAddress, owner });
11435
12296
  try {
11436
12297
  await publicClient.simulateContract({
11437
12298
  address: contract,
@@ -11610,7 +12471,7 @@ function readMintDirectSaleTokenRange(opts) {
11610
12471
  eventName: "MintDirectSale",
11611
12472
  logs: opts.receipt.logs
11612
12473
  }).filter(
11613
- (log) => isAddressEqual16(log.args._contractAddress, opts.contract) && isAddressEqual16(log.args._buyer, opts.buyer)
12474
+ (log) => isAddressEqual17(log.args._contractAddress, opts.contract) && isAddressEqual17(log.args._buyer, opts.buyer)
11614
12475
  );
11615
12476
  if (event === void 0) {
11616
12477
  throw new Error(`MintDirectSale event was not found for ${opts.contract} and buyer ${opts.buyer}.`);
@@ -11797,6 +12658,11 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
11797
12658
  currencyDecimals: currencyDecimals2,
11798
12659
  nowSeconds: currentUnixTimestamp3()
11799
12660
  });
12661
+ await assertCollectionOwnerForReleaseWrite({
12662
+ publicClient,
12663
+ contract: plan.contract,
12664
+ accountAddress
12665
+ });
11800
12666
  const approvalTxHash = await approveReleaseMinterIfNeeded({
11801
12667
  publicClient,
11802
12668
  walletClient,
@@ -11805,29 +12671,41 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
11805
12671
  minter: rareMinter,
11806
12672
  autoApprove: params.autoApprove
11807
12673
  });
11808
- await assertConfigurableReleaseContract({
11809
- publicClient,
11810
- contract: plan.contract,
11811
- accountAddress,
11812
- rareMinter
11813
- });
11814
- const txHash = await walletClient.writeContract({
11815
- address: rareMinter,
11816
- abi: rareMinterAbi,
11817
- functionName: "prepareMintDirectSale",
11818
- args: [
11819
- plan.contract,
11820
- plan.currencyAddress,
11821
- plan.price,
11822
- plan.startTime,
11823
- plan.maxMints,
11824
- plan.splitRecipients,
11825
- plan.splitRatios
11826
- ],
11827
- account,
11828
- chain: void 0
12674
+ const { txHash, receipt } = await runWithApprovalSideEffectAlert({
12675
+ operation: "release configure",
12676
+ approvals: [{
12677
+ type: "minter",
12678
+ approvalTxHash,
12679
+ target: plan.contract,
12680
+ minter: rareMinter
12681
+ }],
12682
+ run: async () => {
12683
+ await assertReleaseMinterCanMint({
12684
+ publicClient,
12685
+ contract: plan.contract,
12686
+ accountAddress,
12687
+ rareMinter
12688
+ });
12689
+ const configureTxHash = await walletClient.writeContract({
12690
+ address: rareMinter,
12691
+ abi: rareMinterAbi,
12692
+ functionName: "prepareMintDirectSale",
12693
+ args: [
12694
+ plan.contract,
12695
+ plan.currencyAddress,
12696
+ plan.price,
12697
+ plan.startTime,
12698
+ plan.maxMints,
12699
+ plan.splitRecipients,
12700
+ plan.splitRatios
12701
+ ],
12702
+ account,
12703
+ chain: void 0
12704
+ });
12705
+ const configureReceipt = await publicClient.waitForTransactionReceipt({ hash: configureTxHash });
12706
+ return { txHash: configureTxHash, receipt: configureReceipt };
12707
+ }
11829
12708
  });
11830
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
11831
12709
  return {
11832
12710
  txHash,
11833
12711
  receipt,
@@ -11876,26 +12754,38 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
11876
12754
  amount: mint.totalPrice,
11877
12755
  autoApprove: plan.autoApprove
11878
12756
  });
11879
- const txHash = await walletClient.writeContract({
11880
- address: rareMinter,
11881
- abi: rareMinterAbi,
11882
- functionName: "mintDirectSale",
11883
- args: [
11884
- mint.contract,
11885
- mint.currency,
11886
- mint.price,
11887
- mint.quantity,
11888
- mint.proof
11889
- ],
11890
- account,
11891
- chain: void 0,
11892
- value: payment.value
11893
- });
11894
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
11895
- const tokenRange = readMintDirectSaleTokenRange({
11896
- receipt,
11897
- contract: mint.contract,
11898
- buyer: accountAddress
12757
+ const { txHash, receipt, tokenRange } = await runWithApprovalSideEffectAlert({
12758
+ operation: "release mint",
12759
+ approvals: [{
12760
+ type: "erc20",
12761
+ approvalTxHash: payment.approvalTxHash,
12762
+ target: mint.currency,
12763
+ spender: rareMinter
12764
+ }],
12765
+ run: async () => {
12766
+ const targetTxHash = await walletClient.writeContract({
12767
+ address: rareMinter,
12768
+ abi: rareMinterAbi,
12769
+ functionName: "mintDirectSale",
12770
+ args: [
12771
+ mint.contract,
12772
+ mint.currency,
12773
+ mint.price,
12774
+ mint.quantity,
12775
+ mint.proof
12776
+ ],
12777
+ account,
12778
+ chain: void 0,
12779
+ value: payment.value
12780
+ });
12781
+ const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
12782
+ const mintedTokenRange = readMintDirectSaleTokenRange({
12783
+ receipt: targetReceipt,
12784
+ contract: mint.contract,
12785
+ buyer: accountAddress
12786
+ });
12787
+ return { txHash: targetTxHash, receipt: targetReceipt, tokenRange: mintedTokenRange };
12788
+ }
11899
12789
  });
11900
12790
  return {
11901
12791
  txHash,
@@ -12949,146 +13839,6 @@ function contractSupportError(operation, contract, cause) {
12949
13839
  );
12950
13840
  }
12951
13841
 
12952
- // src/sdk/merkle-core.ts
12953
- import { Buffer } from "buffer";
12954
- import { MerkleTree } from "merkletreejs";
12955
- import {
12956
- encodePacked as encodePacked3,
12957
- getAddress as getAddress10,
12958
- isAddress as isAddress6,
12959
- isAddressEqual as isAddressEqual17,
12960
- isHex as isHex5,
12961
- keccak256 as keccak2563
12962
- } from "viem";
12963
- function hexBuffer(hex) {
12964
- return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
12965
- }
12966
- function tokenLeaf(contract, tokenId) {
12967
- const packed = encodePacked3(["address", "uint256"], [contract, tokenId]);
12968
- return hexBuffer(keccak2563(packed));
12969
- }
12970
- function addressLeaf(address) {
12971
- return hexBuffer(keccak2563(address));
12972
- }
12973
- function parseBytes32(value, field) {
12974
- if (!isHex5(value) || value.length !== 66) {
12975
- throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
12976
- }
12977
- return value;
12978
- }
12979
- function parseBytes32Array(values, field) {
12980
- return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
12981
- }
12982
- function compareTokenEntries(a, b) {
12983
- if (!isAddressEqual17(a.contract, b.contract)) {
12984
- return a.contract.localeCompare(b.contract);
12985
- }
12986
- return a.tokenId.localeCompare(b.tokenId);
12987
- }
12988
- function normalizeTokenEntry(token) {
12989
- if (!isAddress6(token.contract)) {
12990
- throw new Error(`Invalid token contract address: ${token.contract}`);
12991
- }
12992
- return {
12993
- contract: getAddress10(token.contract),
12994
- tokenId: String(token.tokenId),
12995
- tokenIdBigInt: toInteger(token.tokenId, "tokenId")
12996
- };
12997
- }
12998
- function buildBatchListingTree(tokens) {
12999
- if (tokens.length < 2) {
13000
- throw new Error("buildBatchListingTree requires at least two tokens");
13001
- }
13002
- const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
13003
- const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
13004
- const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2563(data)), {
13005
- sortPairs: true
13006
- });
13007
- return {
13008
- root: parseBytes32(tree.getHexRoot(), "root"),
13009
- tree,
13010
- sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
13011
- };
13012
- }
13013
- function buildAllowListTree(addresses) {
13014
- if (addresses.length < 2) {
13015
- throw new Error("buildAllowListTree requires at least two addresses");
13016
- }
13017
- const sorted = addresses.map((address) => {
13018
- if (!isAddress6(address)) throw new Error(`Invalid allowlist address: ${address}`);
13019
- return getAddress10(address);
13020
- }).sort((a, b) => a.localeCompare(b));
13021
- const leaves = sorted.map(addressLeaf);
13022
- const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2563(data)), {
13023
- sortPairs: true
13024
- });
13025
- return {
13026
- root: parseBytes32(tree.getHexRoot(), "root"),
13027
- tree,
13028
- sortedAddresses: sorted
13029
- };
13030
- }
13031
- function getTokenProof(tree, contract, tokenId) {
13032
- const leaf = tokenLeaf(getAddress10(contract), tokenId);
13033
- return parseBytes32Array(tree.getHexProof(leaf), "proof");
13034
- }
13035
- function getAddressProof(tree, address) {
13036
- const leaf = addressLeaf(getAddress10(address));
13037
- return parseBytes32Array(tree.getHexProof(leaf), "proof");
13038
- }
13039
- function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
13040
- const tokenIdBig = toInteger(tokenId, "tokenId");
13041
- const contractChecksum = getAddress10(contract);
13042
- const found = artifact.tokens.find(
13043
- (token) => isAddressEqual17(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
13044
- );
13045
- if (found === void 0) {
13046
- throw new Error(
13047
- `Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
13048
- );
13049
- }
13050
- const { tree, root } = buildBatchListingTree(
13051
- artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
13052
- );
13053
- if (root !== artifact.root) {
13054
- throw new Error(
13055
- `Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
13056
- );
13057
- }
13058
- const allowListProofFields = buildAllowListProofFields(artifact, buyer);
13059
- return {
13060
- root: artifact.root,
13061
- contract: contractChecksum,
13062
- tokenId: tokenIdBig.toString(),
13063
- proof: getTokenProof(tree, contractChecksum, tokenIdBig),
13064
- ...allowListProofFields ?? {}
13065
- };
13066
- }
13067
- function buildAllowListProofFields(artifact, buyer) {
13068
- if (artifact.allowList === void 0) return void 0;
13069
- if (buyer === void 0) {
13070
- throw new Error(
13071
- "This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
13072
- );
13073
- }
13074
- if (!isAddress6(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
13075
- const buyerChecksum = getAddress10(buyer);
13076
- const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual17(address, buyerChecksum));
13077
- if (!inAllowList) {
13078
- throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
13079
- }
13080
- const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
13081
- if (root !== artifact.allowList.root) {
13082
- throw new Error(
13083
- `Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
13084
- );
13085
- }
13086
- return {
13087
- allowListProof: getAddressProof(tree, buyerChecksum),
13088
- allowListAddress: buyerChecksum
13089
- };
13090
- }
13091
-
13092
13842
  // src/sdk/utils.ts
13093
13843
  function createUtilsNamespace() {
13094
13844
  return {
@@ -13179,6 +13929,7 @@ function createRareClient(config) {
13179
13929
  contracts: {
13180
13930
  factory: addresses.factory,
13181
13931
  auction: addresses.auction,
13932
+ rareBridge: addresses.rareBridge,
13182
13933
  sovereignFactory: addresses.sovereignFactory,
13183
13934
  lazySovereignFactory: addresses.lazySovereignFactory,
13184
13935
  rareMinter: addresses.rareMinter,
@@ -13194,6 +13945,7 @@ function createRareClient(config) {
13194
13945
  v4Quoter: addresses.v4Quoter
13195
13946
  },
13196
13947
  liquidEdition: createLiquidNamespace(config, chain, addresses),
13948
+ bridge: createBridgeNamespace(publicClient, config, chain),
13197
13949
  swap: createSwapNamespace(config, chain, chainId, addresses),
13198
13950
  auction,
13199
13951
  offer,
@@ -13277,6 +14029,7 @@ function isRecord5(value) {
13277
14029
  return typeof value === "object" && value !== null;
13278
14030
  }
13279
14031
  export {
14032
+ ApprovalSideEffectError,
13280
14033
  NftApprovalRequiredError,
13281
14034
  PaymentApprovalRequiredError,
13282
14035
  createRareClient