@rareprotocol/rare-cli 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{addresses-BE3luaB3.d.ts → addresses-CcGI_7v1.d.ts} +5 -1
- package/dist/{batch-listing-Cu5Hoqxs.d.ts → batch-listing-C1CtPTD5.d.ts} +1 -1
- package/dist/client.d.ts +56 -5
- package/dist/client.js +1213 -462
- package/dist/contracts.d.ts +90 -2
- package/dist/contracts.js +140 -3
- package/dist/index.js +1396 -496
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +11 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -292,7 +292,7 @@ Error: ${message}`);
|
|
|
292
292
|
|
|
293
293
|
// src/program.ts
|
|
294
294
|
import { createInterface as createInterface7 } from "readline/promises";
|
|
295
|
-
import { Command as
|
|
295
|
+
import { Command as Command23 } from "commander";
|
|
296
296
|
|
|
297
297
|
// src/commands/configure.ts
|
|
298
298
|
import { text } from "stream/consumers";
|
|
@@ -338,6 +338,7 @@ var contractAddresses = {
|
|
|
338
338
|
sepolia: {
|
|
339
339
|
factory: getAddress("0x3c7526a0975156299ceef369b8ff3c01cc670523"),
|
|
340
340
|
auction: getAddress("0xC8Edc7049b233641ad3723D6C60019D1c8771612"),
|
|
341
|
+
rareBridge: getAddress("0xdC168291658f6C5F1D0b33E573c4d289DCA9dD08"),
|
|
341
342
|
sovereignFactory: getAddress("0x46B2850ba7787734F648A6848b5eDE0815C1F8Bf"),
|
|
342
343
|
lazySovereignFactory: getAddress("0xc5B8Ad9003673a23d005A6448C74d8955a1a38fA"),
|
|
343
344
|
rareMinter: getAddress("0xd28Dc0B89104d7BBd902F338a0193fF063617ccE"),
|
|
@@ -355,6 +356,7 @@ var contractAddresses = {
|
|
|
355
356
|
mainnet: {
|
|
356
357
|
factory: getAddress("0xAe8E375a268Ed6442bEaC66C6254d6De5AeD4aB1"),
|
|
357
358
|
auction: getAddress("0x6D7c44773C52D396F43c2D511B81aa168E9a7a42"),
|
|
359
|
+
rareBridge: getAddress("0x88135dd0e7a8a2e42272dda89849a997ce2e83f7"),
|
|
358
360
|
sovereignFactory: getAddress("0xe980ec62378529d95ba446433f4deb6324129c59"),
|
|
359
361
|
lazySovereignFactory: getAddress("0xba798BD606d86D207ca2751510173532899117a1"),
|
|
360
362
|
rareMinter: getAddress("0x5fa112EFeD8297bec0010b312208d223E0cE891E"),
|
|
@@ -365,19 +367,27 @@ var contractAddresses = {
|
|
|
365
367
|
marketplaceSettings: getAddress("0x61DBF87164d33FD3695256DC8Ba74D3B1d304170"),
|
|
366
368
|
erc20ApprovalManager: getAddress("0xa837a7eAff154Ab837617Cf7250648D3Ec0A4436"),
|
|
367
369
|
erc721ApprovalManager: getAddress("0x4bb0Deea6d1A30C601338aAB776d394C2AE5c0F8"),
|
|
368
|
-
liquidFactory: getAddress("
|
|
370
|
+
liquidFactory: getAddress("0x25f993C222fE5e891128a782A5168f1C78629540"),
|
|
369
371
|
swapRouter: getAddress("0xEBd58EdA8408d9EA409f2c2bE8898BD9738f3583"),
|
|
370
372
|
v4Quoter: getAddress("0x52F0E24D1c21C8A0cB1e5a5dD6198556BD9E1203")
|
|
371
373
|
},
|
|
372
374
|
base: {
|
|
373
375
|
factory: getAddress("0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd"),
|
|
374
|
-
auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2")
|
|
376
|
+
auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2"),
|
|
377
|
+
rareBridge: getAddress("0x3b41e21094611d152a08d3691a70837f1a077dae")
|
|
375
378
|
},
|
|
376
379
|
"base-sepolia": {
|
|
377
380
|
factory: getAddress("0x2b181ae0f1aea6fed75591b04991b1a3f9868d51"),
|
|
378
|
-
auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2")
|
|
381
|
+
auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2"),
|
|
382
|
+
rareBridge: getAddress("0xca491bb62A7730E97F500510132C47633DDD0229")
|
|
379
383
|
}
|
|
380
384
|
};
|
|
385
|
+
var ccipChainSelectors = {
|
|
386
|
+
mainnet: 5009297550715157269n,
|
|
387
|
+
sepolia: 16015286601757825753n,
|
|
388
|
+
base: 15971525489660198786n,
|
|
389
|
+
"base-sepolia": 10344971235874465080n
|
|
390
|
+
};
|
|
381
391
|
var canonicalV4Pools = {
|
|
382
392
|
sepolia: {
|
|
383
393
|
rareEthPool: {
|
|
@@ -527,6 +537,16 @@ function getCanonicalV4Pools(chain) {
|
|
|
527
537
|
}
|
|
528
538
|
return pools;
|
|
529
539
|
}
|
|
540
|
+
function getRareBridgeAddress(chain) {
|
|
541
|
+
const address = getContractAddresses(chain).rareBridge;
|
|
542
|
+
if (!address) {
|
|
543
|
+
throw new Error(`RareBridge is not configured on "${chain}". Supported RareBridge chains: mainnet, sepolia, base, base-sepolia.`);
|
|
544
|
+
}
|
|
545
|
+
return address;
|
|
546
|
+
}
|
|
547
|
+
function getCcipChainSelector(chain) {
|
|
548
|
+
return ccipChainSelectors[chain];
|
|
549
|
+
}
|
|
530
550
|
function isSupportedChain(value) {
|
|
531
551
|
return supportedChains.some((chain) => chain === value);
|
|
532
552
|
}
|
|
@@ -1176,8 +1196,12 @@ import createClient from "openapi-fetch";
|
|
|
1176
1196
|
|
|
1177
1197
|
// src/data-access/base-url.ts
|
|
1178
1198
|
var DEFAULT_RARE_API_BASE_URL = "https://api.superrare.com";
|
|
1199
|
+
function normalizeRareApiBaseUrlCandidate(baseUrl) {
|
|
1200
|
+
const trimmedBaseUrl = baseUrl?.trim();
|
|
1201
|
+
return trimmedBaseUrl === "" ? void 0 : trimmedBaseUrl;
|
|
1202
|
+
}
|
|
1179
1203
|
function resolveRareApiBaseUrl(baseUrl) {
|
|
1180
|
-
return process.env.RARE_API_BASE_URL ?? baseUrl ?? DEFAULT_RARE_API_BASE_URL;
|
|
1204
|
+
return normalizeRareApiBaseUrlCandidate(process.env.RARE_API_BASE_URL) ?? normalizeRareApiBaseUrlCandidate(baseUrl) ?? DEFAULT_RARE_API_BASE_URL;
|
|
1181
1205
|
}
|
|
1182
1206
|
|
|
1183
1207
|
// src/data-access/client.ts
|
|
@@ -4418,6 +4442,50 @@ var auctionAbi = [
|
|
|
4418
4442
|
];
|
|
4419
4443
|
|
|
4420
4444
|
// src/sdk/approvals-shell.ts
|
|
4445
|
+
var ApprovalSideEffectError = class extends Error {
|
|
4446
|
+
operation;
|
|
4447
|
+
approvals;
|
|
4448
|
+
constructor(params) {
|
|
4449
|
+
super(
|
|
4450
|
+
`${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.`,
|
|
4451
|
+
{ cause: params.cause }
|
|
4452
|
+
);
|
|
4453
|
+
this.name = "ApprovalSideEffectError";
|
|
4454
|
+
this.operation = params.operation;
|
|
4455
|
+
this.approvals = params.approvals;
|
|
4456
|
+
}
|
|
4457
|
+
};
|
|
4458
|
+
async function runWithApprovalSideEffectAlert(params) {
|
|
4459
|
+
try {
|
|
4460
|
+
return await params.run();
|
|
4461
|
+
} catch (error) {
|
|
4462
|
+
const approvals = params.approvals.filter(hasApprovalTxHash);
|
|
4463
|
+
if (approvals.length === 0) {
|
|
4464
|
+
throw error;
|
|
4465
|
+
}
|
|
4466
|
+
throw new ApprovalSideEffectError({
|
|
4467
|
+
operation: params.operation,
|
|
4468
|
+
approvals,
|
|
4469
|
+
cause: error
|
|
4470
|
+
});
|
|
4471
|
+
}
|
|
4472
|
+
}
|
|
4473
|
+
function hasApprovalTxHash(approval) {
|
|
4474
|
+
return approval.approvalTxHash !== void 0;
|
|
4475
|
+
}
|
|
4476
|
+
function approvalSummary(approvals) {
|
|
4477
|
+
const [approval] = approvals;
|
|
4478
|
+
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(", ")}`;
|
|
4479
|
+
}
|
|
4480
|
+
function approvalDetails(approval) {
|
|
4481
|
+
if (approval.type === "erc20" || approval.type === "erc20-reset") {
|
|
4482
|
+
return `${approval.type}; token ${approval.target}; spender ${approval.spender ?? "unknown"}`;
|
|
4483
|
+
}
|
|
4484
|
+
if (approval.type === "minter") {
|
|
4485
|
+
return `minter; collection ${approval.target}; minter ${approval.minter ?? "unknown"}`;
|
|
4486
|
+
}
|
|
4487
|
+
return `nft; contract ${approval.target}; operator ${approval.operator ?? "unknown"}`;
|
|
4488
|
+
}
|
|
4421
4489
|
var approvalAbi = [
|
|
4422
4490
|
{
|
|
4423
4491
|
inputs: [{ name: "owner", type: "address" }, { name: "operator", type: "address" }],
|
|
@@ -4570,7 +4638,7 @@ async function toTokenAmount(publicClient, token, value, field) {
|
|
|
4570
4638
|
}
|
|
4571
4639
|
async function ensureTokenAllowance(publicClient, walletClient, account, owner, token, spender, amount) {
|
|
4572
4640
|
if (isAddressEqual5(token, ETH_ADDRESS) || amount === 0n) {
|
|
4573
|
-
return;
|
|
4641
|
+
return void 0;
|
|
4574
4642
|
}
|
|
4575
4643
|
const allowance = await publicClient.readContract({
|
|
4576
4644
|
address: token,
|
|
@@ -4579,7 +4647,7 @@ async function ensureTokenAllowance(publicClient, walletClient, account, owner,
|
|
|
4579
4647
|
args: [owner, spender]
|
|
4580
4648
|
});
|
|
4581
4649
|
if (allowance >= amount) {
|
|
4582
|
-
return;
|
|
4650
|
+
return void 0;
|
|
4583
4651
|
}
|
|
4584
4652
|
const approveTx = await walletClient.writeContract({
|
|
4585
4653
|
address: token,
|
|
@@ -4589,7 +4657,14 @@ async function ensureTokenAllowance(publicClient, walletClient, account, owner,
|
|
|
4589
4657
|
account,
|
|
4590
4658
|
chain: void 0
|
|
4591
4659
|
});
|
|
4592
|
-
await publicClient
|
|
4660
|
+
await confirmErc20Approval(publicClient, {
|
|
4661
|
+
approvalTxHash: approveTx,
|
|
4662
|
+
currency: token,
|
|
4663
|
+
accountAddress: owner,
|
|
4664
|
+
spenderAddress: spender,
|
|
4665
|
+
requiredAmount: amount
|
|
4666
|
+
});
|
|
4667
|
+
return approveTx;
|
|
4593
4668
|
}
|
|
4594
4669
|
var PaymentApprovalRequiredError = class extends Error {
|
|
4595
4670
|
requiredAmount;
|
|
@@ -4662,7 +4737,13 @@ async function preparePaymentAmountForSpender(opts) {
|
|
|
4662
4737
|
account,
|
|
4663
4738
|
chain: void 0
|
|
4664
4739
|
});
|
|
4665
|
-
await publicClient
|
|
4740
|
+
await confirmErc20Approval(publicClient, {
|
|
4741
|
+
approvalTxHash,
|
|
4742
|
+
currency,
|
|
4743
|
+
accountAddress,
|
|
4744
|
+
spenderAddress,
|
|
4745
|
+
requiredAmount
|
|
4746
|
+
});
|
|
4666
4747
|
return {
|
|
4667
4748
|
value: 0n,
|
|
4668
4749
|
requiredAmount,
|
|
@@ -4700,6 +4781,23 @@ async function readAllowance(publicClient, currency, accountAddress, spenderAddr
|
|
|
4700
4781
|
args: [accountAddress, spenderAddress]
|
|
4701
4782
|
});
|
|
4702
4783
|
}
|
|
4784
|
+
async function confirmErc20Approval(publicClient, params) {
|
|
4785
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: params.approvalTxHash });
|
|
4786
|
+
if (receipt.status !== "success") {
|
|
4787
|
+
throw new Error(`ERC20 approval transaction ${params.approvalTxHash} did not succeed.`);
|
|
4788
|
+
}
|
|
4789
|
+
const allowance = await readAllowance(
|
|
4790
|
+
publicClient,
|
|
4791
|
+
params.currency,
|
|
4792
|
+
params.accountAddress,
|
|
4793
|
+
params.spenderAddress
|
|
4794
|
+
);
|
|
4795
|
+
if (allowance < params.requiredAmount) {
|
|
4796
|
+
throw new Error(
|
|
4797
|
+
`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.`
|
|
4798
|
+
);
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4703
4801
|
|
|
4704
4802
|
// src/sdk/validation-core.ts
|
|
4705
4803
|
import { isHex } from "viem";
|
|
@@ -5133,6 +5231,11 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
5133
5231
|
accountAddress,
|
|
5134
5232
|
currentUnixTimestamp()
|
|
5135
5233
|
);
|
|
5234
|
+
const auctionType = await publicClient.readContract({
|
|
5235
|
+
address: addresses.auction,
|
|
5236
|
+
abi: auctionAbi,
|
|
5237
|
+
functionName: plan.auctionType === "scheduled" ? "SCHEDULED_AUCTION" : "COLDIE_AUCTION"
|
|
5238
|
+
});
|
|
5136
5239
|
const approvalTxHash = await approveNftContractIfNeeded({
|
|
5137
5240
|
publicClient,
|
|
5138
5241
|
walletClient,
|
|
@@ -5142,30 +5245,37 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
5142
5245
|
operator: addresses.auction,
|
|
5143
5246
|
autoApprove: params.autoApprove
|
|
5144
5247
|
});
|
|
5145
|
-
const
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5248
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5249
|
+
operation: "auction create",
|
|
5250
|
+
approvals: [{
|
|
5251
|
+
type: "nft",
|
|
5252
|
+
approvalTxHash,
|
|
5253
|
+
target: plan.nftAddress,
|
|
5254
|
+
operator: addresses.auction
|
|
5255
|
+
}],
|
|
5256
|
+
run: async () => {
|
|
5257
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5258
|
+
address: addresses.auction,
|
|
5259
|
+
abi: auctionAbi,
|
|
5260
|
+
functionName: "configureAuction",
|
|
5261
|
+
args: [
|
|
5262
|
+
auctionType,
|
|
5263
|
+
plan.nftAddress,
|
|
5264
|
+
plan.tokenId,
|
|
5265
|
+
plan.startingPrice,
|
|
5266
|
+
plan.currency,
|
|
5267
|
+
plan.duration,
|
|
5268
|
+
plan.startTime,
|
|
5269
|
+
plan.splitAddresses,
|
|
5270
|
+
plan.splitRatios
|
|
5271
|
+
],
|
|
5272
|
+
account,
|
|
5273
|
+
chain: void 0
|
|
5274
|
+
});
|
|
5275
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5276
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5277
|
+
}
|
|
5167
5278
|
});
|
|
5168
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5169
5279
|
return {
|
|
5170
5280
|
txHash,
|
|
5171
5281
|
receipt,
|
|
@@ -5191,22 +5301,34 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
5191
5301
|
amount: plan.amount,
|
|
5192
5302
|
autoApprove: params.autoApprove
|
|
5193
5303
|
});
|
|
5194
|
-
const txHash = await
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5304
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5305
|
+
operation: "auction bid",
|
|
5306
|
+
approvals: [{
|
|
5307
|
+
type: "erc20",
|
|
5308
|
+
approvalTxHash: payment.approvalTxHash,
|
|
5309
|
+
target: plan.currency,
|
|
5310
|
+
spender: addresses.auction
|
|
5311
|
+
}],
|
|
5312
|
+
run: async () => {
|
|
5313
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5314
|
+
address: addresses.auction,
|
|
5315
|
+
abi: auctionAbi,
|
|
5316
|
+
functionName: "bid",
|
|
5317
|
+
args: [params.contract, plan.tokenId, plan.currency, plan.amount],
|
|
5318
|
+
account,
|
|
5319
|
+
chain: void 0,
|
|
5320
|
+
value: payment.value
|
|
5321
|
+
});
|
|
5322
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5323
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5324
|
+
}
|
|
5202
5325
|
});
|
|
5203
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5204
5326
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
5205
5327
|
},
|
|
5206
5328
|
async settle(params) {
|
|
5207
5329
|
const { walletClient, account } = requireWallet(config);
|
|
5208
5330
|
const plan = planAuctionTokenAction(params);
|
|
5209
|
-
const
|
|
5331
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5210
5332
|
address: addresses.auction,
|
|
5211
5333
|
abi: auctionAbi,
|
|
5212
5334
|
functionName: "settleAuction",
|
|
@@ -5214,13 +5336,13 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
5214
5336
|
account,
|
|
5215
5337
|
chain: void 0
|
|
5216
5338
|
});
|
|
5217
|
-
const
|
|
5218
|
-
return { txHash, receipt };
|
|
5339
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5340
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5219
5341
|
},
|
|
5220
5342
|
async cancel(params) {
|
|
5221
5343
|
const { walletClient, account } = requireWallet(config);
|
|
5222
5344
|
const plan = planAuctionTokenAction(params);
|
|
5223
|
-
const
|
|
5345
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5224
5346
|
address: addresses.auction,
|
|
5225
5347
|
abi: auctionAbi,
|
|
5226
5348
|
functionName: "cancelAuction",
|
|
@@ -5228,8 +5350,8 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
5228
5350
|
account,
|
|
5229
5351
|
chain: void 0
|
|
5230
5352
|
});
|
|
5231
|
-
const
|
|
5232
|
-
return { txHash, receipt };
|
|
5353
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5354
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5233
5355
|
},
|
|
5234
5356
|
async status(params) {
|
|
5235
5357
|
const plan = planAuctionTokenAction(params);
|
|
@@ -5306,23 +5428,35 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
|
|
|
5306
5428
|
amount: plan.amount,
|
|
5307
5429
|
autoApprove: params.autoApprove
|
|
5308
5430
|
});
|
|
5309
|
-
const txHash = await
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5431
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5432
|
+
operation: "offer create",
|
|
5433
|
+
approvals: [{
|
|
5434
|
+
type: "erc20",
|
|
5435
|
+
approvalTxHash: payment.approvalTxHash,
|
|
5436
|
+
target: plan.currency,
|
|
5437
|
+
spender: addresses.auction
|
|
5438
|
+
}],
|
|
5439
|
+
run: async () => {
|
|
5440
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5441
|
+
address: addresses.auction,
|
|
5442
|
+
abi: auctionAbi,
|
|
5443
|
+
functionName: "offer",
|
|
5444
|
+
args: [params.contract, plan.tokenId, plan.currency, plan.amount, false],
|
|
5445
|
+
account,
|
|
5446
|
+
chain: void 0,
|
|
5447
|
+
value: payment.value
|
|
5448
|
+
});
|
|
5449
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5450
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5451
|
+
}
|
|
5317
5452
|
});
|
|
5318
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5319
5453
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
5320
5454
|
},
|
|
5321
5455
|
async cancel(params) {
|
|
5322
5456
|
const { walletClient, account } = requireWallet(config);
|
|
5323
5457
|
const currency = params.currency === void 0 ? ETH_ADDRESS : resolveCurrencyForSdk(params.currency, chain).address;
|
|
5324
5458
|
const plan = planOfferCancel({ ...params, currency });
|
|
5325
|
-
const
|
|
5459
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5326
5460
|
address: addresses.auction,
|
|
5327
5461
|
abi: auctionAbi,
|
|
5328
5462
|
functionName: "cancelOffer",
|
|
@@ -5330,8 +5464,8 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
|
|
|
5330
5464
|
account,
|
|
5331
5465
|
chain: void 0
|
|
5332
5466
|
});
|
|
5333
|
-
const
|
|
5334
|
-
return { txHash, receipt };
|
|
5467
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5468
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5335
5469
|
},
|
|
5336
5470
|
async accept(params) {
|
|
5337
5471
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
@@ -5348,22 +5482,34 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
|
|
|
5348
5482
|
operator: addresses.auction,
|
|
5349
5483
|
autoApprove: params.autoApprove
|
|
5350
5484
|
});
|
|
5351
|
-
const txHash = await
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
params.contract,
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5485
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5486
|
+
operation: "offer accept",
|
|
5487
|
+
approvals: [{
|
|
5488
|
+
type: "nft",
|
|
5489
|
+
approvalTxHash,
|
|
5490
|
+
target: params.contract,
|
|
5491
|
+
operator: addresses.auction
|
|
5492
|
+
}],
|
|
5493
|
+
run: async () => {
|
|
5494
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5495
|
+
address: addresses.auction,
|
|
5496
|
+
abi: auctionAbi,
|
|
5497
|
+
functionName: "acceptOffer",
|
|
5498
|
+
args: [
|
|
5499
|
+
params.contract,
|
|
5500
|
+
plan.tokenId,
|
|
5501
|
+
plan.currency,
|
|
5502
|
+
plan.amount,
|
|
5503
|
+
plan.splitAddresses,
|
|
5504
|
+
plan.splitRatios
|
|
5505
|
+
],
|
|
5506
|
+
account,
|
|
5507
|
+
chain: void 0
|
|
5508
|
+
});
|
|
5509
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5510
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5511
|
+
}
|
|
5365
5512
|
});
|
|
5366
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5367
5513
|
return { txHash, receipt, approvalTxHash };
|
|
5368
5514
|
},
|
|
5369
5515
|
async status(params) {
|
|
@@ -5428,29 +5574,41 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
5428
5574
|
operator: addresses.auction,
|
|
5429
5575
|
autoApprove: params.autoApprove
|
|
5430
5576
|
});
|
|
5431
|
-
const txHash = await
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
plan.nftAddress,
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5577
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5578
|
+
operation: "listing create",
|
|
5579
|
+
approvals: [{
|
|
5580
|
+
type: "nft",
|
|
5581
|
+
approvalTxHash,
|
|
5582
|
+
target: plan.nftAddress,
|
|
5583
|
+
operator: addresses.auction
|
|
5584
|
+
}],
|
|
5585
|
+
run: async () => {
|
|
5586
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5587
|
+
address: addresses.auction,
|
|
5588
|
+
abi: auctionAbi,
|
|
5589
|
+
functionName: "setSalePrice",
|
|
5590
|
+
args: [
|
|
5591
|
+
plan.nftAddress,
|
|
5592
|
+
plan.tokenId,
|
|
5593
|
+
plan.currency,
|
|
5594
|
+
plan.price,
|
|
5595
|
+
plan.target,
|
|
5596
|
+
plan.splitAddresses,
|
|
5597
|
+
plan.splitRatios
|
|
5598
|
+
],
|
|
5599
|
+
account,
|
|
5600
|
+
chain: void 0
|
|
5601
|
+
});
|
|
5602
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5603
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5604
|
+
}
|
|
5446
5605
|
});
|
|
5447
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5448
5606
|
return { txHash, receipt, approvalTxHash };
|
|
5449
5607
|
},
|
|
5450
5608
|
async cancel(params) {
|
|
5451
5609
|
const { walletClient, account } = requireWallet(config);
|
|
5452
5610
|
const plan = planListingCancel(params);
|
|
5453
|
-
const
|
|
5611
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5454
5612
|
address: addresses.auction,
|
|
5455
5613
|
abi: auctionAbi,
|
|
5456
5614
|
functionName: "removeSalePrice",
|
|
@@ -5458,8 +5616,8 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
5458
5616
|
account,
|
|
5459
5617
|
chain: void 0
|
|
5460
5618
|
});
|
|
5461
|
-
const
|
|
5462
|
-
return { txHash, receipt };
|
|
5619
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5620
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5463
5621
|
},
|
|
5464
5622
|
async buy(params) {
|
|
5465
5623
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
@@ -5478,16 +5636,28 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
5478
5636
|
amount: plan.amount,
|
|
5479
5637
|
autoApprove: params.autoApprove
|
|
5480
5638
|
});
|
|
5481
|
-
const txHash = await
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5639
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5640
|
+
operation: "listing buy",
|
|
5641
|
+
approvals: [{
|
|
5642
|
+
type: "erc20",
|
|
5643
|
+
approvalTxHash: payment.approvalTxHash,
|
|
5644
|
+
target: plan.currency,
|
|
5645
|
+
spender: addresses.auction
|
|
5646
|
+
}],
|
|
5647
|
+
run: async () => {
|
|
5648
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5649
|
+
address: addresses.auction,
|
|
5650
|
+
abi: auctionAbi,
|
|
5651
|
+
functionName: "buy",
|
|
5652
|
+
args: [params.contract, plan.tokenId, plan.currency, plan.amount],
|
|
5653
|
+
account,
|
|
5654
|
+
chain: void 0,
|
|
5655
|
+
value: payment.value
|
|
5656
|
+
});
|
|
5657
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5658
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5659
|
+
}
|
|
5489
5660
|
});
|
|
5490
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5491
5661
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
5492
5662
|
},
|
|
5493
5663
|
async status(params) {
|
|
@@ -6449,7 +6619,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6449
6619
|
);
|
|
6450
6620
|
}
|
|
6451
6621
|
}
|
|
6452
|
-
const
|
|
6622
|
+
const nftApprovals = await approveNftContracts({
|
|
6453
6623
|
publicClient,
|
|
6454
6624
|
walletClient,
|
|
6455
6625
|
account,
|
|
@@ -6458,26 +6628,38 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6458
6628
|
nftAddresses: uniqueContracts,
|
|
6459
6629
|
autoApprove: params.autoApprove
|
|
6460
6630
|
});
|
|
6461
|
-
const txHash = await
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6631
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
6632
|
+
operation: "batch listing create",
|
|
6633
|
+
approvals: nftApprovals.map((approval) => ({
|
|
6634
|
+
type: "nft",
|
|
6635
|
+
approvalTxHash: approval.txHash,
|
|
6636
|
+
target: approval.nftAddress,
|
|
6637
|
+
operator: addresses.erc721ApprovalManager
|
|
6638
|
+
})),
|
|
6639
|
+
run: async () => {
|
|
6640
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6641
|
+
address: addresses.batchListing,
|
|
6642
|
+
abi: batchListingAbi,
|
|
6643
|
+
functionName: "registerSalePriceMerkleRoot",
|
|
6644
|
+
args: [
|
|
6645
|
+
artifact.root,
|
|
6646
|
+
artifact.currency,
|
|
6647
|
+
BigInt(artifact.amount),
|
|
6648
|
+
splitConfig.splitAddresses,
|
|
6649
|
+
splitConfig.splitRatios
|
|
6650
|
+
],
|
|
6651
|
+
account,
|
|
6652
|
+
chain: void 0
|
|
6653
|
+
});
|
|
6654
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6655
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
6656
|
+
}
|
|
6474
6657
|
});
|
|
6475
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
6476
6658
|
return {
|
|
6477
6659
|
txHash,
|
|
6478
6660
|
receipt,
|
|
6479
6661
|
root: artifact.root,
|
|
6480
|
-
approvalTxHashes:
|
|
6662
|
+
approvalTxHashes: nftApprovals.length > 0 ? nftApprovals.map((approval) => approval.txHash) : void 0
|
|
6481
6663
|
};
|
|
6482
6664
|
},
|
|
6483
6665
|
async cancel(params) {
|
|
@@ -6490,7 +6672,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6490
6672
|
creator: accountAddress,
|
|
6491
6673
|
params
|
|
6492
6674
|
});
|
|
6493
|
-
const
|
|
6675
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6494
6676
|
address: addresses.batchListing,
|
|
6495
6677
|
abi: batchListingAbi,
|
|
6496
6678
|
functionName: "cancelSalePriceMerkleRoot",
|
|
@@ -6498,8 +6680,8 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6498
6680
|
account,
|
|
6499
6681
|
chain: void 0
|
|
6500
6682
|
});
|
|
6501
|
-
const
|
|
6502
|
-
return { txHash, receipt, root };
|
|
6683
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6684
|
+
return { txHash: targetTxHash, receipt: targetReceipt, root };
|
|
6503
6685
|
},
|
|
6504
6686
|
async buy(params) {
|
|
6505
6687
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
@@ -6530,25 +6712,37 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6530
6712
|
amount,
|
|
6531
6713
|
autoApprove: params.autoApprove
|
|
6532
6714
|
});
|
|
6533
|
-
const txHash = await
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6715
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
6716
|
+
operation: "batch listing buy",
|
|
6717
|
+
approvals: [{
|
|
6718
|
+
type: "erc20",
|
|
6719
|
+
approvalTxHash: payment.approvalTxHash,
|
|
6720
|
+
target: currency,
|
|
6721
|
+
spender: addresses.erc20ApprovalManager
|
|
6722
|
+
}],
|
|
6723
|
+
run: async () => {
|
|
6724
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6725
|
+
address: addresses.batchListing,
|
|
6726
|
+
abi: batchListingAbi,
|
|
6727
|
+
functionName: "buyWithMerkleProof",
|
|
6728
|
+
args: [
|
|
6729
|
+
proofArtifact.contract,
|
|
6730
|
+
tokenIdBig,
|
|
6731
|
+
currency,
|
|
6732
|
+
amount,
|
|
6733
|
+
params.creator,
|
|
6734
|
+
proofArtifact.root,
|
|
6735
|
+
proofArtifact.proof,
|
|
6736
|
+
allowListProof
|
|
6737
|
+
],
|
|
6738
|
+
account,
|
|
6739
|
+
chain: void 0,
|
|
6740
|
+
value: payment.value
|
|
6741
|
+
});
|
|
6742
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6743
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
6744
|
+
}
|
|
6550
6745
|
});
|
|
6551
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
6552
6746
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
6553
6747
|
},
|
|
6554
6748
|
async setAllowlist(params) {
|
|
@@ -6566,7 +6760,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6566
6760
|
requireInput(params.endTime ?? params.artifact?.allowList?.endTimestamp, "endTime"),
|
|
6567
6761
|
"endTime"
|
|
6568
6762
|
);
|
|
6569
|
-
const
|
|
6763
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6570
6764
|
address: addresses.batchListing,
|
|
6571
6765
|
abi: batchListingAbi,
|
|
6572
6766
|
functionName: "setAllowListConfig",
|
|
@@ -6574,8 +6768,8 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6574
6768
|
account,
|
|
6575
6769
|
chain: void 0
|
|
6576
6770
|
});
|
|
6577
|
-
const
|
|
6578
|
-
return { txHash, receipt, root, allowListRoot, endTime };
|
|
6771
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6772
|
+
return { txHash: targetTxHash, receipt: targetReceipt, root, allowListRoot, endTime };
|
|
6579
6773
|
},
|
|
6580
6774
|
async status(params) {
|
|
6581
6775
|
const resolvedParams = await resolveBatchListingStatusParams({
|
|
@@ -6804,7 +6998,7 @@ function isHash(value) {
|
|
|
6804
6998
|
}
|
|
6805
6999
|
async function approveNftContracts(opts) {
|
|
6806
7000
|
return opts.nftAddresses.reduce(async (previous, nftAddress) => {
|
|
6807
|
-
const
|
|
7001
|
+
const approvals = await previous;
|
|
6808
7002
|
const txHash = await approveNftContractIfNeeded({
|
|
6809
7003
|
publicClient: opts.publicClient,
|
|
6810
7004
|
walletClient: opts.walletClient,
|
|
@@ -6814,7 +7008,7 @@ async function approveNftContracts(opts) {
|
|
|
6814
7008
|
operator: opts.operator,
|
|
6815
7009
|
autoApprove: opts.autoApprove
|
|
6816
7010
|
});
|
|
6817
|
-
return isHash(txHash) ? [...
|
|
7011
|
+
return isHash(txHash) ? [...approvals, { nftAddress, txHash }] : approvals;
|
|
6818
7012
|
}, Promise.resolve([]));
|
|
6819
7013
|
}
|
|
6820
7014
|
async function prepareBatchListingPayment(opts) {
|
|
@@ -7191,16 +7385,18 @@ function planBatchAuctionStatus(params) {
|
|
|
7191
7385
|
}
|
|
7192
7386
|
function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
7193
7387
|
const hasAuction = details.startingTime > 0n && !isAddressEqual11(details.seller, zeroAddress3);
|
|
7194
|
-
const
|
|
7195
|
-
const
|
|
7388
|
+
const hasCurrentRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n && rootContext.rootNonce === rootContext.config.nonce;
|
|
7389
|
+
const currentRootConfig = hasCurrentRootConfig ? rootContext.config : void 0;
|
|
7390
|
+
const hasRootConfig = currentRootConfig !== void 0;
|
|
7391
|
+
const duration = hasAuction ? details.duration : currentRootConfig?.duration ?? 0n;
|
|
7196
7392
|
const startingTime = hasAuction ? details.startingTime : 0n;
|
|
7197
7393
|
const endTime = hasAuction ? startingTime + duration : null;
|
|
7198
7394
|
const ended = endTime !== null && nowSeconds >= endTime;
|
|
7199
7395
|
const currentBidder = currentBid.amount > 0n && !isAddressEqual11(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
|
|
7200
7396
|
const seller = hasAuction ? details.seller : rootContext?.creator ?? zeroAddress3;
|
|
7201
|
-
const currency = hasAuction ? details.currency :
|
|
7202
|
-
const reserveAmount = hasAuction ? details.reserveAmount :
|
|
7203
|
-
const tokenNonceConsumed = rootContext === void 0 ? null : rootContext.tokenNonce >= rootContext.config.nonce;
|
|
7397
|
+
const currency = hasAuction ? details.currency : currentRootConfig?.currency ?? ETH_ADDRESS;
|
|
7398
|
+
const reserveAmount = hasAuction ? details.reserveAmount : currentRootConfig?.reserveAmount ?? 0n;
|
|
7399
|
+
const tokenNonceConsumed = rootContext === void 0 ? null : !hasCurrentRootConfig || rootContext.tokenNonce >= rootContext.config.nonce;
|
|
7204
7400
|
return {
|
|
7205
7401
|
seller,
|
|
7206
7402
|
root: rootContext?.root ?? null,
|
|
@@ -7210,8 +7406,8 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
7210
7406
|
creationBlock: details.creationBlock,
|
|
7211
7407
|
startingTime,
|
|
7212
7408
|
endTime,
|
|
7213
|
-
splitAddresses: resolveStatusSplitAddresses(hasAuction, details,
|
|
7214
|
-
splitRatios: resolveStatusSplitRatios(hasAuction, details,
|
|
7409
|
+
splitAddresses: resolveStatusSplitAddresses(hasAuction, details, currentRootConfig),
|
|
7410
|
+
splitRatios: resolveStatusSplitRatios(hasAuction, details, currentRootConfig),
|
|
7215
7411
|
hasRootConfig,
|
|
7216
7412
|
rootNonce: rootContext?.rootNonce ?? null,
|
|
7217
7413
|
tokenNonce: rootContext?.tokenNonce ?? null,
|
|
@@ -7347,23 +7543,23 @@ function uniqueAddresses2(addresses) {
|
|
|
7347
7543
|
function addMinimumBidIncrease(amount) {
|
|
7348
7544
|
return amount + amount * marketplaceFeePercentage / 100n;
|
|
7349
7545
|
}
|
|
7350
|
-
function resolveStatusSplitAddresses(hasAuction, details,
|
|
7546
|
+
function resolveStatusSplitAddresses(hasAuction, details, rootConfig) {
|
|
7351
7547
|
if (hasAuction) {
|
|
7352
7548
|
return [...details.splitAddresses];
|
|
7353
7549
|
}
|
|
7354
|
-
if (
|
|
7550
|
+
if (rootConfig === void 0) {
|
|
7355
7551
|
return [];
|
|
7356
7552
|
}
|
|
7357
|
-
return [...
|
|
7553
|
+
return [...rootConfig.splitAddresses];
|
|
7358
7554
|
}
|
|
7359
|
-
function resolveStatusSplitRatios(hasAuction, details,
|
|
7555
|
+
function resolveStatusSplitRatios(hasAuction, details, rootConfig) {
|
|
7360
7556
|
if (hasAuction) {
|
|
7361
7557
|
return [...details.splitRatios];
|
|
7362
7558
|
}
|
|
7363
|
-
if (
|
|
7559
|
+
if (rootConfig === void 0) {
|
|
7364
7560
|
return [];
|
|
7365
7561
|
}
|
|
7366
|
-
return [...
|
|
7562
|
+
return [...rootConfig.splitRatios];
|
|
7367
7563
|
}
|
|
7368
7564
|
function resolveBatchAuctionState(params) {
|
|
7369
7565
|
if (params.hasAuction) {
|
|
@@ -7397,7 +7593,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7397
7593
|
currentUnixTimestamp2()
|
|
7398
7594
|
);
|
|
7399
7595
|
const erc721ApprovalManager = plan.approvalContracts.length === 0 ? void 0 : requireContractAddress(chain, "erc721ApprovalManager");
|
|
7400
|
-
const
|
|
7596
|
+
const nftApprovals = await approveNftContracts2({
|
|
7401
7597
|
publicClient,
|
|
7402
7598
|
account,
|
|
7403
7599
|
accountAddress,
|
|
@@ -7406,31 +7602,43 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7406
7602
|
nftAddresses: plan.approvalContracts,
|
|
7407
7603
|
autoApprove: params.autoApprove
|
|
7408
7604
|
});
|
|
7409
|
-
const txHash = await
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7605
|
+
const { txHash, receipt, registered } = await runWithApprovalSideEffectAlert({
|
|
7606
|
+
operation: "batch auction create",
|
|
7607
|
+
approvals: nftApprovals.map((approval) => ({
|
|
7608
|
+
type: "nft",
|
|
7609
|
+
approvalTxHash: approval.txHash,
|
|
7610
|
+
target: approval.nftAddress,
|
|
7611
|
+
operator: erc721ApprovalManager
|
|
7612
|
+
})),
|
|
7613
|
+
run: async () => {
|
|
7614
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7615
|
+
address: batchAuctionHouse,
|
|
7616
|
+
abi: batchAuctionHouseAbi,
|
|
7617
|
+
functionName: "registerAuctionMerkleRoot",
|
|
7618
|
+
args: [
|
|
7619
|
+
plan.root,
|
|
7620
|
+
plan.currency,
|
|
7621
|
+
plan.reserveAmount,
|
|
7622
|
+
plan.duration,
|
|
7623
|
+
plan.splitAddresses,
|
|
7624
|
+
plan.splitRatios
|
|
7625
|
+
],
|
|
7626
|
+
account,
|
|
7627
|
+
chain: void 0
|
|
7628
|
+
});
|
|
7629
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7630
|
+
const logs = parseEventLogs3({
|
|
7631
|
+
abi: batchAuctionHouseAbi,
|
|
7632
|
+
logs: targetReceipt.logs,
|
|
7633
|
+
eventName: "AuctionMerkleRootRegistered"
|
|
7634
|
+
});
|
|
7635
|
+
const [registeredLog] = logs;
|
|
7636
|
+
if (!registeredLog) {
|
|
7637
|
+
throw new Error("Batch auction create transaction succeeded but AuctionMerkleRootRegistered was not found in logs.");
|
|
7638
|
+
}
|
|
7639
|
+
return { txHash: targetTxHash, receipt: targetReceipt, registered: registeredLog };
|
|
7640
|
+
}
|
|
7429
7641
|
});
|
|
7430
|
-
const [registered] = logs;
|
|
7431
|
-
if (!registered) {
|
|
7432
|
-
throw new Error("Batch auction create transaction succeeded but AuctionMerkleRootRegistered was not found in logs.");
|
|
7433
|
-
}
|
|
7434
7642
|
return {
|
|
7435
7643
|
txHash,
|
|
7436
7644
|
receipt,
|
|
@@ -7441,7 +7649,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7441
7649
|
reserveAmount: registered.args.startingAmount,
|
|
7442
7650
|
duration: registered.args.duration,
|
|
7443
7651
|
nonce: registered.args.nonce,
|
|
7444
|
-
approvalTxHashes
|
|
7652
|
+
approvalTxHashes: nftApprovals.map((approval) => approval.txHash)
|
|
7445
7653
|
};
|
|
7446
7654
|
},
|
|
7447
7655
|
async cancel(params) {
|
|
@@ -7454,7 +7662,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7454
7662
|
params
|
|
7455
7663
|
);
|
|
7456
7664
|
const plan = planBatchAuctionRoot(resolvedParams);
|
|
7457
|
-
const
|
|
7665
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7458
7666
|
address: batchAuctionHouse,
|
|
7459
7667
|
abi: batchAuctionHouseAbi,
|
|
7460
7668
|
functionName: "cancelAuctionMerkleRoot",
|
|
@@ -7462,10 +7670,10 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7462
7670
|
account,
|
|
7463
7671
|
chain: void 0
|
|
7464
7672
|
});
|
|
7465
|
-
const
|
|
7673
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7466
7674
|
const logs = parseEventLogs3({
|
|
7467
7675
|
abi: batchAuctionHouseAbi,
|
|
7468
|
-
logs:
|
|
7676
|
+
logs: targetReceipt.logs,
|
|
7469
7677
|
eventName: "AuctionMerkleRootCancelled"
|
|
7470
7678
|
});
|
|
7471
7679
|
const [cancelled] = logs;
|
|
@@ -7473,8 +7681,8 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7473
7681
|
throw new Error("Batch auction cancel transaction succeeded but AuctionMerkleRootCancelled was not found in logs.");
|
|
7474
7682
|
}
|
|
7475
7683
|
return {
|
|
7476
|
-
txHash,
|
|
7477
|
-
receipt,
|
|
7684
|
+
txHash: targetTxHash,
|
|
7685
|
+
receipt: targetReceipt,
|
|
7478
7686
|
batchAuctionHouse,
|
|
7479
7687
|
creator: cancelled.args.creator,
|
|
7480
7688
|
root: cancelled.args.merkleRoot
|
|
@@ -7515,33 +7723,45 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7515
7723
|
requiredAmount: plan.requiredPayment,
|
|
7516
7724
|
autoApprove: params.autoApprove
|
|
7517
7725
|
});
|
|
7518
|
-
const txHash = await
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
plan.currency,
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7726
|
+
const { txHash, receipt, bid } = await runWithApprovalSideEffectAlert({
|
|
7727
|
+
operation: "batch auction bid",
|
|
7728
|
+
approvals: [{
|
|
7729
|
+
type: "erc20",
|
|
7730
|
+
approvalTxHash: payment.approvalTxHash,
|
|
7731
|
+
target: plan.currency,
|
|
7732
|
+
spender: erc20ApprovalManager
|
|
7733
|
+
}],
|
|
7734
|
+
run: async () => {
|
|
7735
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7736
|
+
address: batchAuctionHouse,
|
|
7737
|
+
abi: batchAuctionHouseAbi,
|
|
7738
|
+
functionName: "bidWithAuctionMerkleProof",
|
|
7739
|
+
args: [
|
|
7740
|
+
plan.currency,
|
|
7741
|
+
plan.contract,
|
|
7742
|
+
plan.tokenId,
|
|
7743
|
+
plan.creator,
|
|
7744
|
+
plan.root,
|
|
7745
|
+
plan.amount,
|
|
7746
|
+
plan.proof
|
|
7747
|
+
],
|
|
7748
|
+
account,
|
|
7749
|
+
chain: void 0,
|
|
7750
|
+
value: payment.value
|
|
7751
|
+
});
|
|
7752
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7753
|
+
const logs = parseEventLogs3({
|
|
7754
|
+
abi: batchAuctionHouseAbi,
|
|
7755
|
+
logs: targetReceipt.logs,
|
|
7756
|
+
eventName: "AuctionMerkleBid"
|
|
7757
|
+
});
|
|
7758
|
+
const [bidLog] = logs;
|
|
7759
|
+
if (!bidLog) {
|
|
7760
|
+
throw new Error("Batch auction bid transaction succeeded but AuctionMerkleBid was not found in logs.");
|
|
7761
|
+
}
|
|
7762
|
+
return { txHash: targetTxHash, receipt: targetReceipt, bid: bidLog };
|
|
7763
|
+
}
|
|
7540
7764
|
});
|
|
7541
|
-
const [bid] = logs;
|
|
7542
|
-
if (!bid) {
|
|
7543
|
-
throw new Error("Batch auction bid transaction succeeded but AuctionMerkleBid was not found in logs.");
|
|
7544
|
-
}
|
|
7545
7765
|
return {
|
|
7546
7766
|
txHash,
|
|
7547
7767
|
receipt,
|
|
@@ -7562,7 +7782,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7562
7782
|
const batchAuctionHouse = requireContractAddress(chain, "batchAuctionHouse");
|
|
7563
7783
|
const { walletClient, account } = requireWallet(config);
|
|
7564
7784
|
const plan = planBatchAuctionStatus(params);
|
|
7565
|
-
const
|
|
7785
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7566
7786
|
address: batchAuctionHouse,
|
|
7567
7787
|
abi: batchAuctionHouseAbi,
|
|
7568
7788
|
functionName: "settleAuction",
|
|
@@ -7570,10 +7790,10 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7570
7790
|
account,
|
|
7571
7791
|
chain: void 0
|
|
7572
7792
|
});
|
|
7573
|
-
const
|
|
7793
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7574
7794
|
const logs = parseEventLogs3({
|
|
7575
7795
|
abi: batchAuctionHouseAbi,
|
|
7576
|
-
logs:
|
|
7796
|
+
logs: targetReceipt.logs,
|
|
7577
7797
|
eventName: "AuctionSettled"
|
|
7578
7798
|
});
|
|
7579
7799
|
const [settled] = logs;
|
|
@@ -7581,8 +7801,8 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7581
7801
|
throw new Error("Batch auction settle transaction succeeded but AuctionSettled was not found in logs.");
|
|
7582
7802
|
}
|
|
7583
7803
|
return {
|
|
7584
|
-
txHash,
|
|
7585
|
-
receipt,
|
|
7804
|
+
txHash: targetTxHash,
|
|
7805
|
+
receipt: targetReceipt,
|
|
7586
7806
|
batchAuctionHouse,
|
|
7587
7807
|
seller: settled.args.seller,
|
|
7588
7808
|
bidder: settled.args.bidder,
|
|
@@ -7769,7 +7989,7 @@ async function approveNftContracts2(opts) {
|
|
|
7769
7989
|
}
|
|
7770
7990
|
const { walletClient, operator } = opts;
|
|
7771
7991
|
return opts.nftAddresses.reduce(async (previous, nftAddress) => {
|
|
7772
|
-
const
|
|
7992
|
+
const approvals = await previous;
|
|
7773
7993
|
const txHash = await approveNftContract({
|
|
7774
7994
|
publicClient: opts.publicClient,
|
|
7775
7995
|
walletClient,
|
|
@@ -7779,7 +7999,7 @@ async function approveNftContracts2(opts) {
|
|
|
7779
7999
|
nftAddress,
|
|
7780
8000
|
autoApprove: opts.autoApprove
|
|
7781
8001
|
});
|
|
7782
|
-
return txHash === void 0 ?
|
|
8002
|
+
return txHash === void 0 ? approvals : [...approvals, { nftAddress, txHash }];
|
|
7783
8003
|
}, Promise.resolve([]));
|
|
7784
8004
|
}
|
|
7785
8005
|
async function approveNftContract(opts) {
|
|
@@ -8119,25 +8339,37 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8119
8339
|
amount: plan.amount,
|
|
8120
8340
|
autoApprove: params.autoApprove
|
|
8121
8341
|
});
|
|
8122
|
-
const txHash = await
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8342
|
+
const { txHash, receipt, created } = await runWithApprovalSideEffectAlert({
|
|
8343
|
+
operation: "batch offer create",
|
|
8344
|
+
approvals: [{
|
|
8345
|
+
type: "erc20",
|
|
8346
|
+
approvalTxHash: payment.approvalTxHash,
|
|
8347
|
+
target: plan.currency,
|
|
8348
|
+
spender: batchOfferCreator
|
|
8349
|
+
}],
|
|
8350
|
+
run: async () => {
|
|
8351
|
+
const targetTxHash = await walletClient.writeContract({
|
|
8352
|
+
address: batchOfferCreator,
|
|
8353
|
+
abi: batchOfferAbi,
|
|
8354
|
+
functionName: "createBatchOffer",
|
|
8355
|
+
args: [plan.root, plan.amount, plan.currency, plan.expiry],
|
|
8356
|
+
account,
|
|
8357
|
+
chain: void 0,
|
|
8358
|
+
value: payment.value
|
|
8359
|
+
});
|
|
8360
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
8361
|
+
const logs = parseEventLogs4({
|
|
8362
|
+
abi: batchOfferAbi,
|
|
8363
|
+
logs: targetReceipt.logs,
|
|
8364
|
+
eventName: "BatchOfferCreated"
|
|
8365
|
+
});
|
|
8366
|
+
const [createdLog] = logs;
|
|
8367
|
+
if (!createdLog) {
|
|
8368
|
+
throw new Error("Batch offer create transaction succeeded but BatchOfferCreated was not found in logs.");
|
|
8369
|
+
}
|
|
8370
|
+
return { txHash: targetTxHash, receipt: targetReceipt, created: createdLog };
|
|
8371
|
+
}
|
|
8136
8372
|
});
|
|
8137
|
-
const [created] = logs;
|
|
8138
|
-
if (!created) {
|
|
8139
|
-
throw new Error("Batch offer create transaction succeeded but BatchOfferCreated was not found in logs.");
|
|
8140
|
-
}
|
|
8141
8373
|
return {
|
|
8142
8374
|
txHash,
|
|
8143
8375
|
receipt,
|
|
@@ -8163,7 +8395,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8163
8395
|
params
|
|
8164
8396
|
});
|
|
8165
8397
|
const plan = planBatchOfferRoot(resolvedParams);
|
|
8166
|
-
const
|
|
8398
|
+
const targetTxHash = await walletClient.writeContract({
|
|
8167
8399
|
address: batchOfferCreator,
|
|
8168
8400
|
abi: batchOfferAbi,
|
|
8169
8401
|
functionName: "revokeBatchOffer",
|
|
@@ -8171,10 +8403,10 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8171
8403
|
account,
|
|
8172
8404
|
chain: void 0
|
|
8173
8405
|
});
|
|
8174
|
-
const
|
|
8406
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
8175
8407
|
const logs = parseEventLogs4({
|
|
8176
8408
|
abi: batchOfferAbi,
|
|
8177
|
-
logs:
|
|
8409
|
+
logs: targetReceipt.logs,
|
|
8178
8410
|
eventName: "BatchOfferRevoked"
|
|
8179
8411
|
});
|
|
8180
8412
|
const [revoked] = logs;
|
|
@@ -8182,8 +8414,8 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8182
8414
|
throw new Error("Batch offer revoke transaction succeeded but BatchOfferRevoked was not found in logs.");
|
|
8183
8415
|
}
|
|
8184
8416
|
return {
|
|
8185
|
-
txHash,
|
|
8186
|
-
receipt,
|
|
8417
|
+
txHash: targetTxHash,
|
|
8418
|
+
receipt: targetReceipt,
|
|
8187
8419
|
batchOfferCreator,
|
|
8188
8420
|
creator: revoked.args.creator,
|
|
8189
8421
|
root: revoked.args.rootHash,
|
|
@@ -8220,32 +8452,44 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8220
8452
|
operator: batchOfferCreator,
|
|
8221
8453
|
autoApprove: plan.autoApprove
|
|
8222
8454
|
});
|
|
8223
|
-
const txHash = await
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
plan.
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8455
|
+
const { txHash, receipt, accepted } = await runWithApprovalSideEffectAlert({
|
|
8456
|
+
operation: "batch offer accept",
|
|
8457
|
+
approvals: [{
|
|
8458
|
+
type: "nft",
|
|
8459
|
+
approvalTxHash,
|
|
8460
|
+
target: plan.contract,
|
|
8461
|
+
operator: batchOfferCreator
|
|
8462
|
+
}],
|
|
8463
|
+
run: async () => {
|
|
8464
|
+
const targetTxHash = await walletClient.writeContract({
|
|
8465
|
+
address: batchOfferCreator,
|
|
8466
|
+
abi: batchOfferAbi,
|
|
8467
|
+
functionName: "acceptBatchOffer",
|
|
8468
|
+
args: [
|
|
8469
|
+
plan.creator,
|
|
8470
|
+
plan.proof,
|
|
8471
|
+
plan.root,
|
|
8472
|
+
plan.contract,
|
|
8473
|
+
plan.tokenId,
|
|
8474
|
+
plan.splitAddresses,
|
|
8475
|
+
plan.splitRatios
|
|
8476
|
+
],
|
|
8477
|
+
account,
|
|
8478
|
+
chain: void 0
|
|
8479
|
+
});
|
|
8480
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
8481
|
+
const logs = parseEventLogs4({
|
|
8482
|
+
abi: batchOfferAbi,
|
|
8483
|
+
logs: targetReceipt.logs,
|
|
8484
|
+
eventName: "BatchOfferAccepted"
|
|
8485
|
+
});
|
|
8486
|
+
const [acceptedLog] = logs;
|
|
8487
|
+
if (!acceptedLog) {
|
|
8488
|
+
throw new Error("Batch offer accept transaction succeeded but BatchOfferAccepted was not found in logs.");
|
|
8489
|
+
}
|
|
8490
|
+
return { txHash: targetTxHash, receipt: targetReceipt, accepted: acceptedLog };
|
|
8491
|
+
}
|
|
8244
8492
|
});
|
|
8245
|
-
const [accepted] = logs;
|
|
8246
|
-
if (!accepted) {
|
|
8247
|
-
throw new Error("Batch offer accept transaction succeeded but BatchOfferAccepted was not found in logs.");
|
|
8248
|
-
}
|
|
8249
8493
|
return {
|
|
8250
8494
|
txHash,
|
|
8251
8495
|
receipt,
|
|
@@ -8866,6 +9110,7 @@ var liquidFactoryAbi = [
|
|
|
8866
9110
|
var TICK_BASE = 1.0001;
|
|
8867
9111
|
var TICK_LOG_BASE = Math.log(TICK_BASE);
|
|
8868
9112
|
var TOKEN_BASE_UNITS = 1e18;
|
|
9113
|
+
var SHARE_SCALE_UNITS = 10n ** 18n;
|
|
8869
9114
|
var RESERVE_TAIL_SHARES_PERCENT = 2;
|
|
8870
9115
|
var RESERVE_TAIL_END_PRICE_MULTIPLE = 100;
|
|
8871
9116
|
var SHARES_SUM_TOLERANCE = 1e-6;
|
|
@@ -8924,12 +9169,66 @@ function toValidNumber(value) {
|
|
|
8924
9169
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
8925
9170
|
return value;
|
|
8926
9171
|
}
|
|
8927
|
-
function
|
|
8928
|
-
|
|
8929
|
-
|
|
9172
|
+
function toNormalizedShare(value) {
|
|
9173
|
+
if (typeof value === "number") {
|
|
9174
|
+
if (!Number.isFinite(value) || value <= 0 || value > 1) {
|
|
9175
|
+
return null;
|
|
9176
|
+
}
|
|
9177
|
+
return parseShareDecimalString(expandFiniteNumber(value));
|
|
9178
|
+
}
|
|
9179
|
+
if (typeof value !== "string") {
|
|
8930
9180
|
return null;
|
|
8931
9181
|
}
|
|
8932
|
-
return
|
|
9182
|
+
return parseShareDecimalString(value);
|
|
9183
|
+
}
|
|
9184
|
+
function expandFiniteNumber(value) {
|
|
9185
|
+
const rawValue = value.toString();
|
|
9186
|
+
const [coefficient = "", exponentValue] = rawValue.toLowerCase().split("e");
|
|
9187
|
+
if (exponentValue === void 0) {
|
|
9188
|
+
return rawValue;
|
|
9189
|
+
}
|
|
9190
|
+
const exponent = Number(exponentValue);
|
|
9191
|
+
const [integerPart = "", fractionalPart = ""] = coefficient.split(".");
|
|
9192
|
+
const digits = `${integerPart}${fractionalPart}`;
|
|
9193
|
+
const decimalIndex = integerPart.length + exponent;
|
|
9194
|
+
if (decimalIndex <= 0) {
|
|
9195
|
+
return `0.${"0".repeat(Math.abs(decimalIndex))}${digits}`;
|
|
9196
|
+
}
|
|
9197
|
+
if (decimalIndex >= digits.length) {
|
|
9198
|
+
return `${digits}${"0".repeat(decimalIndex - digits.length)}`;
|
|
9199
|
+
}
|
|
9200
|
+
return `${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
|
|
9201
|
+
}
|
|
9202
|
+
function parseShareDecimalString(value) {
|
|
9203
|
+
const normalized = value.trim();
|
|
9204
|
+
if (!/^(?:\d+\.?\d*|\.\d+)$/.test(normalized)) {
|
|
9205
|
+
return null;
|
|
9206
|
+
}
|
|
9207
|
+
const shareParts = normalized.startsWith(".") ? ["0", normalized.slice(1)] : normalized.split(".");
|
|
9208
|
+
const integerPart = shareParts[0] ?? "";
|
|
9209
|
+
const fractionalDigits = shareParts[1] ?? "";
|
|
9210
|
+
const excessFractionalDigits = fractionalDigits.slice(18);
|
|
9211
|
+
if (/[1-9]/.test(excessFractionalDigits)) {
|
|
9212
|
+
return null;
|
|
9213
|
+
}
|
|
9214
|
+
const integerUnits = BigInt(integerPart === "" ? "0" : integerPart);
|
|
9215
|
+
const fractionalUnits = BigInt(fractionalDigits.slice(0, 18).padEnd(18, "0"));
|
|
9216
|
+
const scaledUnits = integerUnits * SHARE_SCALE_UNITS + fractionalUnits;
|
|
9217
|
+
if (scaledUnits <= 0n || scaledUnits > SHARE_SCALE_UNITS) {
|
|
9218
|
+
return null;
|
|
9219
|
+
}
|
|
9220
|
+
return {
|
|
9221
|
+
decimal: formatScaledShareDecimal(scaledUnits),
|
|
9222
|
+
scaledUnits
|
|
9223
|
+
};
|
|
9224
|
+
}
|
|
9225
|
+
function formatScaledShareDecimal(scaledUnits) {
|
|
9226
|
+
const integerUnits = scaledUnits / SHARE_SCALE_UNITS;
|
|
9227
|
+
const fractionalUnits = scaledUnits % SHARE_SCALE_UNITS;
|
|
9228
|
+
if (fractionalUnits === 0n) {
|
|
9229
|
+
return integerUnits.toString();
|
|
9230
|
+
}
|
|
9231
|
+
return `${integerUnits}.${fractionalUnits.toString().padStart(18, "0").replace(/0+$/, "")}`;
|
|
8933
9232
|
}
|
|
8934
9233
|
function toApproxTokenAmount(value, label) {
|
|
8935
9234
|
const numeric = typeof value === "number" ? value : Number(value);
|
|
@@ -9078,8 +9377,8 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
9078
9377
|
if (invalidResult !== void 0) {
|
|
9079
9378
|
return invalidResult.result;
|
|
9080
9379
|
}
|
|
9081
|
-
const
|
|
9082
|
-
const totalPositions =
|
|
9380
|
+
const parsedEntries = normalizedResults.filter((result) => result.isValid).map((result) => result.entry);
|
|
9381
|
+
const totalPositions = parsedEntries.reduce((sum, entry) => sum + entry.segment.numPositions, 0);
|
|
9083
9382
|
if (totalPositions > MAX_TOTAL_POSITIONS) {
|
|
9084
9383
|
return {
|
|
9085
9384
|
isValid: false,
|
|
@@ -9087,8 +9386,8 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
9087
9386
|
errorMessage: `Total positions across all curves must not exceed ${MAX_TOTAL_POSITIONS}`
|
|
9088
9387
|
};
|
|
9089
9388
|
}
|
|
9090
|
-
const
|
|
9091
|
-
const hasGapOrOverlap =
|
|
9389
|
+
const sortedEntries = [...parsedEntries].sort((a, b) => a.segment.tickLower - b.segment.tickLower);
|
|
9390
|
+
const hasGapOrOverlap = sortedEntries.slice(1).some((current, index) => current.segment.tickLower !== sortedEntries[index]?.segment.tickUpper);
|
|
9092
9391
|
if (hasGapOrOverlap) {
|
|
9093
9392
|
return {
|
|
9094
9393
|
isValid: false,
|
|
@@ -9096,10 +9395,11 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
9096
9395
|
errorMessage: "Curve segments must be contiguous (no overlap or gaps)"
|
|
9097
9396
|
};
|
|
9098
9397
|
}
|
|
9099
|
-
const shareSum =
|
|
9100
|
-
if (
|
|
9398
|
+
const shareSum = sortedEntries.reduce((sum, entry) => sum + entry.shareScaledUnits, 0n);
|
|
9399
|
+
if (shareSum !== SHARE_SCALE_UNITS) {
|
|
9101
9400
|
return { isValid: false, error: "share-sum-invalid", errorMessage: "Curve share values must add up to 1" };
|
|
9102
9401
|
}
|
|
9402
|
+
const sortedSegments = sortedEntries.map((entry) => entry.segment);
|
|
9103
9403
|
const narrowSegment = sortedSegments.find((segment) => {
|
|
9104
9404
|
const minSpan = segment.numPositions * tickSpacing;
|
|
9105
9405
|
return segment.tickUpper - segment.tickLower < minSpan || computeGrossLiquidityAtFarTick(segment.tickLower, segment.tickUpper - segment.tickLower, segment.numPositions, Number(segment.shares), totalCurveSupplyTokens) > MAX_LIQUIDITY_PER_TICK;
|
|
@@ -9128,8 +9428,8 @@ function normalizeSegment(segment, tickSpacing) {
|
|
|
9128
9428
|
const tickLower = toValidNumber(segment.tickLower);
|
|
9129
9429
|
const tickUpper = toValidNumber(segment.tickUpper);
|
|
9130
9430
|
const numPositions = toValidNumber(segment.numPositions);
|
|
9131
|
-
const
|
|
9132
|
-
if (tickLower === null || tickUpper === null || numPositions === null ||
|
|
9431
|
+
const share = toNormalizedShare(segment.shares);
|
|
9432
|
+
if (tickLower === null || tickUpper === null || numPositions === null || share === null) {
|
|
9133
9433
|
return invalidSegmentResult();
|
|
9134
9434
|
}
|
|
9135
9435
|
if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper) || !Number.isInteger(numPositions) || numPositions <= 0) {
|
|
@@ -9146,11 +9446,14 @@ function normalizeSegment(segment, tickSpacing) {
|
|
|
9146
9446
|
}
|
|
9147
9447
|
return {
|
|
9148
9448
|
isValid: true,
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9449
|
+
entry: {
|
|
9450
|
+
segment: {
|
|
9451
|
+
tickLower,
|
|
9452
|
+
tickUpper,
|
|
9453
|
+
numPositions,
|
|
9454
|
+
shares: share.decimal
|
|
9455
|
+
},
|
|
9456
|
+
shareScaledUnits: share.scaledUnits
|
|
9154
9457
|
}
|
|
9155
9458
|
};
|
|
9156
9459
|
}
|
|
@@ -9521,9 +9824,23 @@ function missingLiquidEditionAddressError(txHash, receipt, cause) {
|
|
|
9521
9824
|
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.`;
|
|
9522
9825
|
return cause instanceof Error ? new Error(message, { cause }) : new Error(message);
|
|
9523
9826
|
}
|
|
9524
|
-
function
|
|
9827
|
+
function liquidEditionRevertedReceiptError(message, txHash, receipt) {
|
|
9525
9828
|
return new Error(
|
|
9526
|
-
|
|
9829
|
+
`${message} Transaction hash: ${txHash}. Block: ${receipt.blockNumber}.`
|
|
9830
|
+
);
|
|
9831
|
+
}
|
|
9832
|
+
function liquidEditionDeployRevertedError(txHash, receipt) {
|
|
9833
|
+
return liquidEditionRevertedReceiptError(
|
|
9834
|
+
"Liquid Edition deploy transaction reverted before emitting LiquidTokenCreated.",
|
|
9835
|
+
txHash,
|
|
9836
|
+
receipt
|
|
9837
|
+
);
|
|
9838
|
+
}
|
|
9839
|
+
function liquidEditionSetRenderContractRevertedError(txHash, receipt) {
|
|
9840
|
+
return liquidEditionRevertedReceiptError(
|
|
9841
|
+
'Liquid Edition setRenderContract transaction was confirmed with status "reverted".',
|
|
9842
|
+
txHash,
|
|
9843
|
+
receipt
|
|
9527
9844
|
);
|
|
9528
9845
|
}
|
|
9529
9846
|
async function waitForLiquidEditionAddress(publicClient, txHash) {
|
|
@@ -9609,7 +9926,13 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
9609
9926
|
throw new Error(validation.errorMessage ?? "Invalid curve configuration");
|
|
9610
9927
|
}
|
|
9611
9928
|
const initialRareLiquidity = params.initialRareLiquidity !== void 0 ? await toTokenAmount(publicClient, factoryConfig.baseToken, params.initialRareLiquidity, "initialRareLiquidity") : 0n;
|
|
9612
|
-
|
|
9929
|
+
const curves = validation.curves.map((curve) => ({
|
|
9930
|
+
tickLower: curve.tickLower,
|
|
9931
|
+
tickUpper: curve.tickUpper,
|
|
9932
|
+
numPositions: curve.numPositions,
|
|
9933
|
+
shares: parseUnits6(curve.shares, 18)
|
|
9934
|
+
}));
|
|
9935
|
+
const approvalTxHash = await ensureTokenAllowance(
|
|
9613
9936
|
publicClient,
|
|
9614
9937
|
walletClient,
|
|
9615
9938
|
account,
|
|
@@ -9618,43 +9941,49 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
9618
9941
|
liquidFactory,
|
|
9619
9942
|
initialRareLiquidity
|
|
9620
9943
|
);
|
|
9621
|
-
const
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9944
|
+
const { txHash, receipt, contract } = await runWithApprovalSideEffectAlert({
|
|
9945
|
+
operation: "liquid edition deploy",
|
|
9946
|
+
approvals: [{
|
|
9947
|
+
type: "erc20",
|
|
9948
|
+
approvalTxHash,
|
|
9949
|
+
target: factoryConfig.baseToken,
|
|
9950
|
+
spender: liquidFactory
|
|
9951
|
+
}],
|
|
9952
|
+
run: async () => {
|
|
9953
|
+
const targetTxHash = customMaxTotalSupply === void 0 ? await walletClient.writeContract({
|
|
9954
|
+
address: liquidFactory,
|
|
9955
|
+
abi: liquidFactoryAbi,
|
|
9956
|
+
functionName: "createLiquidTokenMultiCurve",
|
|
9957
|
+
args: [
|
|
9958
|
+
accountAddress,
|
|
9959
|
+
params.tokenUri,
|
|
9960
|
+
params.name,
|
|
9961
|
+
params.symbol,
|
|
9962
|
+
initialRareLiquidity,
|
|
9963
|
+
curves
|
|
9964
|
+
],
|
|
9965
|
+
account,
|
|
9966
|
+
chain: void 0
|
|
9967
|
+
}) : await walletClient.writeContract({
|
|
9968
|
+
address: liquidFactory,
|
|
9969
|
+
abi: liquidFactoryAbi,
|
|
9970
|
+
functionName: "createLiquidTokenMultiCurveWithSupply",
|
|
9971
|
+
args: [
|
|
9972
|
+
accountAddress,
|
|
9973
|
+
params.tokenUri,
|
|
9974
|
+
params.name,
|
|
9975
|
+
params.symbol,
|
|
9976
|
+
initialRareLiquidity,
|
|
9977
|
+
curves,
|
|
9978
|
+
customMaxTotalSupply
|
|
9979
|
+
],
|
|
9980
|
+
account,
|
|
9981
|
+
chain: void 0
|
|
9982
|
+
});
|
|
9983
|
+
const deployed = await waitForLiquidEditionAddress(publicClient, targetTxHash);
|
|
9984
|
+
return { txHash: targetTxHash, receipt: deployed.receipt, contract: deployed.contract };
|
|
9985
|
+
}
|
|
9656
9986
|
});
|
|
9657
|
-
const { receipt, contract } = await waitForLiquidEditionAddress(publicClient, txHash);
|
|
9658
9987
|
return {
|
|
9659
9988
|
txHash,
|
|
9660
9989
|
receipt,
|
|
@@ -9689,6 +10018,9 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
9689
10018
|
chain: void 0
|
|
9690
10019
|
});
|
|
9691
10020
|
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
10021
|
+
if (receipt.status === "reverted") {
|
|
10022
|
+
throw liquidEditionSetRenderContractRevertedError(txHash, receipt);
|
|
10023
|
+
}
|
|
9692
10024
|
return {
|
|
9693
10025
|
txHash,
|
|
9694
10026
|
receipt,
|
|
@@ -9795,6 +10127,312 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
9795
10127
|
};
|
|
9796
10128
|
}
|
|
9797
10129
|
|
|
10130
|
+
// src/sdk/bridge.ts
|
|
10131
|
+
import { encodeFunctionData } from "viem";
|
|
10132
|
+
|
|
10133
|
+
// src/contracts/abis/rare-bridge.ts
|
|
10134
|
+
var rareBridgeAbi = [
|
|
10135
|
+
{
|
|
10136
|
+
type: "function",
|
|
10137
|
+
name: "getFee",
|
|
10138
|
+
inputs: [
|
|
10139
|
+
{
|
|
10140
|
+
name: "_destinationChainSelector",
|
|
10141
|
+
type: "uint64",
|
|
10142
|
+
internalType: "uint64"
|
|
10143
|
+
},
|
|
10144
|
+
{
|
|
10145
|
+
name: "_destinationChainRecipient",
|
|
10146
|
+
type: "address",
|
|
10147
|
+
internalType: "address"
|
|
10148
|
+
},
|
|
10149
|
+
{
|
|
10150
|
+
name: "_distributionData",
|
|
10151
|
+
type: "bytes",
|
|
10152
|
+
internalType: "bytes"
|
|
10153
|
+
},
|
|
10154
|
+
{
|
|
10155
|
+
name: "_extraArgs",
|
|
10156
|
+
type: "bytes",
|
|
10157
|
+
internalType: "bytes"
|
|
10158
|
+
},
|
|
10159
|
+
{
|
|
10160
|
+
name: "_payFeesInLink",
|
|
10161
|
+
type: "bool",
|
|
10162
|
+
internalType: "bool"
|
|
10163
|
+
}
|
|
10164
|
+
],
|
|
10165
|
+
outputs: [
|
|
10166
|
+
{
|
|
10167
|
+
name: "fee",
|
|
10168
|
+
type: "uint256",
|
|
10169
|
+
internalType: "uint256"
|
|
10170
|
+
}
|
|
10171
|
+
],
|
|
10172
|
+
stateMutability: "view"
|
|
10173
|
+
},
|
|
10174
|
+
{
|
|
10175
|
+
type: "function",
|
|
10176
|
+
name: "send",
|
|
10177
|
+
inputs: [
|
|
10178
|
+
{
|
|
10179
|
+
name: "_destinationChainSelector",
|
|
10180
|
+
type: "uint64",
|
|
10181
|
+
internalType: "uint64"
|
|
10182
|
+
},
|
|
10183
|
+
{
|
|
10184
|
+
name: "_destinationChainRecipient",
|
|
10185
|
+
type: "address",
|
|
10186
|
+
internalType: "address"
|
|
10187
|
+
},
|
|
10188
|
+
{
|
|
10189
|
+
name: "_distributionData",
|
|
10190
|
+
type: "bytes",
|
|
10191
|
+
internalType: "bytes"
|
|
10192
|
+
},
|
|
10193
|
+
{
|
|
10194
|
+
name: "_extraArgs",
|
|
10195
|
+
type: "bytes",
|
|
10196
|
+
internalType: "bytes"
|
|
10197
|
+
},
|
|
10198
|
+
{
|
|
10199
|
+
name: "_payFeesInLink",
|
|
10200
|
+
type: "bool",
|
|
10201
|
+
internalType: "bool"
|
|
10202
|
+
}
|
|
10203
|
+
],
|
|
10204
|
+
outputs: [],
|
|
10205
|
+
stateMutability: "payable"
|
|
10206
|
+
},
|
|
10207
|
+
{
|
|
10208
|
+
type: "event",
|
|
10209
|
+
name: "MessageSent",
|
|
10210
|
+
inputs: [
|
|
10211
|
+
{
|
|
10212
|
+
name: "messageId",
|
|
10213
|
+
type: "bytes32",
|
|
10214
|
+
indexed: true,
|
|
10215
|
+
internalType: "bytes32"
|
|
10216
|
+
},
|
|
10217
|
+
{
|
|
10218
|
+
name: "destinationChainSelector",
|
|
10219
|
+
type: "uint64",
|
|
10220
|
+
indexed: true,
|
|
10221
|
+
internalType: "uint64"
|
|
10222
|
+
},
|
|
10223
|
+
{
|
|
10224
|
+
name: "destinationChainRecipient",
|
|
10225
|
+
type: "address",
|
|
10226
|
+
indexed: true,
|
|
10227
|
+
internalType: "address"
|
|
10228
|
+
},
|
|
10229
|
+
{
|
|
10230
|
+
name: "fee",
|
|
10231
|
+
type: "uint256",
|
|
10232
|
+
indexed: false,
|
|
10233
|
+
internalType: "uint256"
|
|
10234
|
+
},
|
|
10235
|
+
{
|
|
10236
|
+
name: "payFeesInLink",
|
|
10237
|
+
type: "bool",
|
|
10238
|
+
indexed: false,
|
|
10239
|
+
internalType: "bool"
|
|
10240
|
+
}
|
|
10241
|
+
],
|
|
10242
|
+
anonymous: false
|
|
10243
|
+
}
|
|
10244
|
+
];
|
|
10245
|
+
|
|
10246
|
+
// src/sdk/bridge-core.ts
|
|
10247
|
+
import { encodeAbiParameters } from "viem";
|
|
10248
|
+
var allowedBridgePairs = [
|
|
10249
|
+
{ sourceChain: "mainnet", destinationChain: "base" },
|
|
10250
|
+
{ sourceChain: "base", destinationChain: "mainnet" },
|
|
10251
|
+
{ sourceChain: "sepolia", destinationChain: "base-sepolia" },
|
|
10252
|
+
{ sourceChain: "base-sepolia", destinationChain: "sepolia" }
|
|
10253
|
+
];
|
|
10254
|
+
function validateBridgeRoute(route) {
|
|
10255
|
+
const supported = allowedBridgePairs.some(
|
|
10256
|
+
(pair) => pair.sourceChain === route.sourceChain && pair.destinationChain === route.destinationChain
|
|
10257
|
+
);
|
|
10258
|
+
if (supported) {
|
|
10259
|
+
return { isValid: true };
|
|
10260
|
+
}
|
|
10261
|
+
return {
|
|
10262
|
+
isValid: false,
|
|
10263
|
+
error: "unsupported_bridge_route",
|
|
10264
|
+
errorMessage: `Unsupported RARE bridge route "${route.sourceChain}" -> "${route.destinationChain}". Supported routes: mainnet <-> base, sepolia <-> base-sepolia.`
|
|
10265
|
+
};
|
|
10266
|
+
}
|
|
10267
|
+
function getBridgeInfo(chain) {
|
|
10268
|
+
return {
|
|
10269
|
+
chain,
|
|
10270
|
+
chainId: chainIds[chain],
|
|
10271
|
+
rareBridgeAddress: getRareBridgeAddress(chain),
|
|
10272
|
+
rareTokenAddress: resolveCurrency("rare", chain),
|
|
10273
|
+
ccipChainSelector: getCcipChainSelector(chain)
|
|
10274
|
+
};
|
|
10275
|
+
}
|
|
10276
|
+
function encodeBridgeDistribution(params) {
|
|
10277
|
+
return encodeAbiParameters(
|
|
10278
|
+
[
|
|
10279
|
+
{ name: "recipients", type: "address[]" },
|
|
10280
|
+
{ name: "amounts", type: "uint256[]" }
|
|
10281
|
+
],
|
|
10282
|
+
[[params.recipient], [params.amount]]
|
|
10283
|
+
);
|
|
10284
|
+
}
|
|
10285
|
+
function buildBridgeSendArgs(params) {
|
|
10286
|
+
return [
|
|
10287
|
+
params.destinationBridgeInfo.ccipChainSelector,
|
|
10288
|
+
params.destinationBridgeInfo.rareBridgeAddress,
|
|
10289
|
+
params.distributionData,
|
|
10290
|
+
"0x",
|
|
10291
|
+
false
|
|
10292
|
+
];
|
|
10293
|
+
}
|
|
10294
|
+
function buildCcipExplorerUrl(txHash) {
|
|
10295
|
+
return `https://ccip.chain.link/tx/${txHash}`;
|
|
10296
|
+
}
|
|
10297
|
+
|
|
10298
|
+
// src/sdk/bridge.ts
|
|
10299
|
+
function createBridgeNamespace(publicClient, config, sourceChain) {
|
|
10300
|
+
return {
|
|
10301
|
+
async quote(params) {
|
|
10302
|
+
return buildBridgeQuote(publicClient, config, sourceChain, params);
|
|
10303
|
+
},
|
|
10304
|
+
async send(params) {
|
|
10305
|
+
return executeBridge(publicClient, config, sourceChain, params);
|
|
10306
|
+
}
|
|
10307
|
+
};
|
|
10308
|
+
}
|
|
10309
|
+
async function executeBridge(publicClient, config, sourceChain, params) {
|
|
10310
|
+
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
10311
|
+
const quote = await buildBridgeQuote(publicClient, config, sourceChain, {
|
|
10312
|
+
...params,
|
|
10313
|
+
recipient: params.recipient ?? accountAddress
|
|
10314
|
+
}, {
|
|
10315
|
+
estimateGas: false
|
|
10316
|
+
});
|
|
10317
|
+
const approval = await preparePaymentAmountForSpender({
|
|
10318
|
+
publicClient,
|
|
10319
|
+
walletClient,
|
|
10320
|
+
account,
|
|
10321
|
+
accountAddress,
|
|
10322
|
+
spenderAddress: quote.sourceBridgeAddress,
|
|
10323
|
+
currency: quote.rareTokenAddress,
|
|
10324
|
+
requiredAmount: quote.amount,
|
|
10325
|
+
autoApprove: params.autoApprove
|
|
10326
|
+
});
|
|
10327
|
+
const sendArgs = buildBridgeSendArgs({
|
|
10328
|
+
destinationBridgeInfo: getBridgeInfo(quote.destinationChain),
|
|
10329
|
+
distributionData: quote.distributionData
|
|
10330
|
+
});
|
|
10331
|
+
const { txHash, receipt, estimatedGas } = await runWithApprovalSideEffectAlert({
|
|
10332
|
+
operation: "bridge send",
|
|
10333
|
+
approvals: [{
|
|
10334
|
+
type: "erc20",
|
|
10335
|
+
approvalTxHash: approval.approvalTxHash,
|
|
10336
|
+
target: quote.rareTokenAddress,
|
|
10337
|
+
spender: quote.sourceBridgeAddress
|
|
10338
|
+
}],
|
|
10339
|
+
run: async () => {
|
|
10340
|
+
const gas = await estimateBridgeGas(publicClient, {
|
|
10341
|
+
account: accountAddress,
|
|
10342
|
+
sourceBridgeAddress: quote.sourceBridgeAddress,
|
|
10343
|
+
args: sendArgs,
|
|
10344
|
+
nativeFee: quote.nativeFee
|
|
10345
|
+
});
|
|
10346
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10347
|
+
address: quote.sourceBridgeAddress,
|
|
10348
|
+
abi: rareBridgeAbi,
|
|
10349
|
+
functionName: "send",
|
|
10350
|
+
args: sendArgs,
|
|
10351
|
+
value: quote.nativeFee,
|
|
10352
|
+
account,
|
|
10353
|
+
chain: void 0
|
|
10354
|
+
});
|
|
10355
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10356
|
+
return { txHash: targetTxHash, receipt: targetReceipt, estimatedGas: gas };
|
|
10357
|
+
}
|
|
10358
|
+
});
|
|
10359
|
+
return {
|
|
10360
|
+
...quote,
|
|
10361
|
+
estimatedGas,
|
|
10362
|
+
txHash,
|
|
10363
|
+
receipt,
|
|
10364
|
+
approvalTxHash: approval.approvalTxHash,
|
|
10365
|
+
ccipExplorerUrl: buildCcipExplorerUrl(txHash)
|
|
10366
|
+
};
|
|
10367
|
+
}
|
|
10368
|
+
async function buildBridgeQuote(publicClient, config, sourceChain, params, options = {}) {
|
|
10369
|
+
const routeValidation = validateBridgeRoute({
|
|
10370
|
+
sourceChain,
|
|
10371
|
+
destinationChain: params.destinationChain
|
|
10372
|
+
});
|
|
10373
|
+
if (!routeValidation.isValid) {
|
|
10374
|
+
throw new Error(routeValidation.errorMessage);
|
|
10375
|
+
}
|
|
10376
|
+
const sourceBridgeInfo = getBridgeInfo(sourceChain);
|
|
10377
|
+
const destinationBridgeInfo = getBridgeInfo(params.destinationChain);
|
|
10378
|
+
const recipient = resolveRecipient(params.recipient, config);
|
|
10379
|
+
const amount = toPositiveWei(params.amount, "amount");
|
|
10380
|
+
const distributionData = encodeBridgeDistribution({ recipient, amount });
|
|
10381
|
+
const args = buildBridgeSendArgs({
|
|
10382
|
+
destinationBridgeInfo,
|
|
10383
|
+
distributionData
|
|
10384
|
+
});
|
|
10385
|
+
const nativeFee = await publicClient.readContract({
|
|
10386
|
+
address: sourceBridgeInfo.rareBridgeAddress,
|
|
10387
|
+
abi: rareBridgeAbi,
|
|
10388
|
+
functionName: "getFee",
|
|
10389
|
+
args
|
|
10390
|
+
});
|
|
10391
|
+
const estimatedGas = options.estimateGas === false ? void 0 : await estimateBridgeGas(publicClient, {
|
|
10392
|
+
account: getConfiguredAccountAddress2(config),
|
|
10393
|
+
sourceBridgeAddress: sourceBridgeInfo.rareBridgeAddress,
|
|
10394
|
+
args,
|
|
10395
|
+
nativeFee
|
|
10396
|
+
});
|
|
10397
|
+
return {
|
|
10398
|
+
sourceChain,
|
|
10399
|
+
sourceChainId: sourceBridgeInfo.chainId,
|
|
10400
|
+
destinationChain: params.destinationChain,
|
|
10401
|
+
destinationChainId: destinationBridgeInfo.chainId,
|
|
10402
|
+
sourceBridgeAddress: sourceBridgeInfo.rareBridgeAddress,
|
|
10403
|
+
destinationBridgeAddress: destinationBridgeInfo.rareBridgeAddress,
|
|
10404
|
+
rareTokenAddress: sourceBridgeInfo.rareTokenAddress,
|
|
10405
|
+
destinationCcipChainSelector: destinationBridgeInfo.ccipChainSelector,
|
|
10406
|
+
amount,
|
|
10407
|
+
recipient,
|
|
10408
|
+
distributionData,
|
|
10409
|
+
nativeFee,
|
|
10410
|
+
estimatedGas
|
|
10411
|
+
};
|
|
10412
|
+
}
|
|
10413
|
+
function resolveRecipient(recipient, config) {
|
|
10414
|
+
const resolved = recipient ?? getConfiguredAccountAddress2(config);
|
|
10415
|
+
if (resolved === void 0) {
|
|
10416
|
+
throw new Error("No recipient available for bridge quote. Pass params.recipient or provide config.account/walletClient with an account.");
|
|
10417
|
+
}
|
|
10418
|
+
return resolved;
|
|
10419
|
+
}
|
|
10420
|
+
async function estimateBridgeGas(publicClient, params) {
|
|
10421
|
+
if (params.account === void 0) {
|
|
10422
|
+
return void 0;
|
|
10423
|
+
}
|
|
10424
|
+
return publicClient.estimateGas({
|
|
10425
|
+
account: params.account,
|
|
10426
|
+
to: params.sourceBridgeAddress,
|
|
10427
|
+
data: encodeFunctionData({
|
|
10428
|
+
abi: rareBridgeAbi,
|
|
10429
|
+
functionName: "send",
|
|
10430
|
+
args: params.args
|
|
10431
|
+
}),
|
|
10432
|
+
value: params.nativeFee
|
|
10433
|
+
});
|
|
10434
|
+
}
|
|
10435
|
+
|
|
9798
10436
|
// src/contracts/abis/liquid-router.ts
|
|
9799
10437
|
var liquidRouterAbi = [
|
|
9800
10438
|
{
|
|
@@ -10181,7 +10819,7 @@ async function quoteRouteSteps(publicClient, quoterAddress, routeSteps, currentA
|
|
|
10181
10819
|
|
|
10182
10820
|
// src/swap/route-encoding.ts
|
|
10183
10821
|
import {
|
|
10184
|
-
encodeAbiParameters,
|
|
10822
|
+
encodeAbiParameters as encodeAbiParameters2,
|
|
10185
10823
|
encodePacked as encodePacked2,
|
|
10186
10824
|
getAddress as getAddress8,
|
|
10187
10825
|
parseAbiParameters
|
|
@@ -10293,13 +10931,13 @@ function getV4ExecutionMode(v4BlockStartIndex, nextIndex, routeLength) {
|
|
|
10293
10931
|
};
|
|
10294
10932
|
}
|
|
10295
10933
|
function encodeWrapEth(recipient, amount) {
|
|
10296
|
-
return
|
|
10934
|
+
return encodeAbiParameters2(
|
|
10297
10935
|
parseAbiParameters("address recipient, uint256 amount"),
|
|
10298
10936
|
[recipient, amount]
|
|
10299
10937
|
);
|
|
10300
10938
|
}
|
|
10301
10939
|
function encodeUnwrapWeth(recipient, amountMinimum) {
|
|
10302
|
-
return
|
|
10940
|
+
return encodeAbiParameters2(
|
|
10303
10941
|
parseAbiParameters("address recipient, uint256 amountMinimum"),
|
|
10304
10942
|
[recipient, amountMinimum]
|
|
10305
10943
|
);
|
|
@@ -10319,23 +10957,23 @@ function encodeV4ExactIn({
|
|
|
10319
10957
|
step.poolKey.hooks,
|
|
10320
10958
|
"0x"
|
|
10321
10959
|
]);
|
|
10322
|
-
const swapParams =
|
|
10960
|
+
const swapParams = encodeAbiParameters2(
|
|
10323
10961
|
parseAbiParameters("(address,(address,uint24,int24,address,bytes)[],uint128,uint128)"),
|
|
10324
10962
|
[[currencyIn, pathKeysArray, amountIn, minAmountOut]]
|
|
10325
10963
|
);
|
|
10326
10964
|
const settleAction = executionMode.inputSource === "user" ? V4_ACTIONS.SETTLE_ALL : V4_ACTIONS.SETTLE;
|
|
10327
|
-
const settleParams = executionMode.inputSource === "user" ?
|
|
10965
|
+
const settleParams = executionMode.inputSource === "user" ? encodeAbiParameters2(
|
|
10328
10966
|
parseAbiParameters("address currency, uint128 maxAmount"),
|
|
10329
10967
|
[currencyIn, amountIn]
|
|
10330
|
-
) :
|
|
10968
|
+
) : encodeAbiParameters2(
|
|
10331
10969
|
parseAbiParameters("address currency, uint256 amount, bool payerIsUser"),
|
|
10332
10970
|
[currencyIn, ROUTER_AMOUNT_CONSTANTS.contractBalance, false]
|
|
10333
10971
|
);
|
|
10334
10972
|
const takeAction = executionMode.outputTarget === "user" ? V4_ACTIONS.TAKE_ALL : V4_ACTIONS.TAKE;
|
|
10335
|
-
const takeParams = executionMode.outputTarget === "user" ?
|
|
10973
|
+
const takeParams = executionMode.outputTarget === "user" ? encodeAbiParameters2(
|
|
10336
10974
|
parseAbiParameters("address currency, uint128 minAmount"),
|
|
10337
10975
|
[currencyOut, minAmountOut]
|
|
10338
|
-
) :
|
|
10976
|
+
) : encodeAbiParameters2(
|
|
10339
10977
|
parseAbiParameters("address currency, address recipient, uint256 amount"),
|
|
10340
10978
|
[currencyOut, ROUTER_RECIPIENTS.addressThis, ROUTER_AMOUNT_CONSTANTS.openDelta]
|
|
10341
10979
|
);
|
|
@@ -10348,7 +10986,7 @@ function encodeV4ExactIn({
|
|
|
10348
10986
|
["uint8", "uint8", "uint8"],
|
|
10349
10987
|
[settleAction, V4_ACTIONS.SWAP_EXACT_IN_SINGLE, takeAction]
|
|
10350
10988
|
);
|
|
10351
|
-
return
|
|
10989
|
+
return encodeAbiParameters2(
|
|
10352
10990
|
parseAbiParameters("bytes actions, bytes[] params"),
|
|
10353
10991
|
[
|
|
10354
10992
|
actions2,
|
|
@@ -10364,7 +11002,7 @@ function encodeV4ExactIn({
|
|
|
10364
11002
|
["uint8", "uint8", "uint8"],
|
|
10365
11003
|
[V4_ACTIONS.SWAP_EXACT_IN, settleAction, takeAction]
|
|
10366
11004
|
);
|
|
10367
|
-
return
|
|
11005
|
+
return encodeAbiParameters2(
|
|
10368
11006
|
parseAbiParameters("bytes actions, bytes[] params"),
|
|
10369
11007
|
[actions, [swapParams, settleParams, takeParams]]
|
|
10370
11008
|
);
|
|
@@ -10383,7 +11021,7 @@ function encodeV4ExactInSingle(step, amountIn, minAmountOut) {
|
|
|
10383
11021
|
minAmountOut,
|
|
10384
11022
|
"0x"
|
|
10385
11023
|
];
|
|
10386
|
-
return
|
|
11024
|
+
return encodeAbiParameters2(
|
|
10387
11025
|
parseAbiParameters("((address,address,uint24,int24,address),bool,uint128,uint128,bytes)"),
|
|
10388
11026
|
[swapExactInSingleTuple]
|
|
10389
11027
|
);
|
|
@@ -10990,7 +11628,7 @@ async function executeRawRouterBuy(params) {
|
|
|
10990
11628
|
const minAmountOutInput = requireInput(params.minAmountOut, "minAmountOut");
|
|
10991
11629
|
const ethAmount = toWei(amountIn);
|
|
10992
11630
|
const minTokensOut = await toTokenAmount(params.publicClient, params.token, minAmountOutInput, "minAmountOut");
|
|
10993
|
-
const
|
|
11631
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10994
11632
|
address: router,
|
|
10995
11633
|
abi: liquidRouterAbi,
|
|
10996
11634
|
functionName: "buy",
|
|
@@ -10999,8 +11637,8 @@ async function executeRawRouterBuy(params) {
|
|
|
10999
11637
|
chain: void 0,
|
|
11000
11638
|
value: ethAmount
|
|
11001
11639
|
});
|
|
11002
|
-
const
|
|
11003
|
-
return { txHash, receipt, minAmountOut: minTokensOut };
|
|
11640
|
+
const targetReceipt = await params.publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
11641
|
+
return { txHash: targetTxHash, receipt: targetReceipt, minAmountOut: minTokensOut };
|
|
11004
11642
|
}
|
|
11005
11643
|
async function executeRawRouterSell(params) {
|
|
11006
11644
|
const { walletClient, account, accountAddress } = requireWallet(params.config);
|
|
@@ -11010,25 +11648,37 @@ async function executeRawRouterSell(params) {
|
|
|
11010
11648
|
const minAmountOutInput = requireInput(params.minAmountOut, "minAmountOut");
|
|
11011
11649
|
const tokenAmount = await toTokenAmount(params.publicClient, params.token, amountIn, "amountIn");
|
|
11012
11650
|
const minEthOut = toWei(minAmountOutInput);
|
|
11013
|
-
await ensureTokenAllowance(params.publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
11014
|
-
const txHash = await
|
|
11015
|
-
|
|
11016
|
-
|
|
11017
|
-
|
|
11018
|
-
|
|
11019
|
-
params.token,
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
11651
|
+
const approvalTxHash = await ensureTokenAllowance(params.publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
11652
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
11653
|
+
operation: "swap sell",
|
|
11654
|
+
approvals: [{
|
|
11655
|
+
type: "erc20",
|
|
11656
|
+
approvalTxHash,
|
|
11657
|
+
target: params.token,
|
|
11658
|
+
spender: router
|
|
11659
|
+
}],
|
|
11660
|
+
run: async () => {
|
|
11661
|
+
const targetTxHash = await walletClient.writeContract({
|
|
11662
|
+
address: router,
|
|
11663
|
+
abi: liquidRouterAbi,
|
|
11664
|
+
functionName: "sell",
|
|
11665
|
+
args: [
|
|
11666
|
+
params.token,
|
|
11667
|
+
tokenAmount,
|
|
11668
|
+
params.recipient ?? accountAddress,
|
|
11669
|
+
minEthOut,
|
|
11670
|
+
params.commands,
|
|
11671
|
+
[...params.inputs],
|
|
11672
|
+
resolveDeadline(params.deadline)
|
|
11673
|
+
],
|
|
11674
|
+
account,
|
|
11675
|
+
chain: void 0
|
|
11676
|
+
});
|
|
11677
|
+
const targetReceipt = await params.publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
11678
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
11679
|
+
}
|
|
11029
11680
|
});
|
|
11030
|
-
|
|
11031
|
-
return { txHash, receipt, minAmountOut: minEthOut, tokenAmount };
|
|
11681
|
+
return { txHash, receipt, minAmountOut: minEthOut, tokenAmount, approvalTxHash };
|
|
11032
11682
|
}
|
|
11033
11683
|
function isRawTokenTradeParams(params) {
|
|
11034
11684
|
return params.route === "raw";
|
|
@@ -11072,28 +11722,38 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11072
11722
|
validateRouterPayload(params.commands, params.inputs);
|
|
11073
11723
|
const amountIn = await toTokenAmount(publicClient, params.tokenIn, params.amountIn, "amountIn");
|
|
11074
11724
|
const minAmountOut = await toTokenAmount(publicClient, params.tokenOut, params.minAmountOut, "minAmountOut");
|
|
11075
|
-
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
|
|
11084
|
-
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11725
|
+
const approvalTxHash = params.tokenIn === ETH_ADDRESS ? void 0 : await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.tokenIn, router, amountIn);
|
|
11726
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
11727
|
+
operation: "swap tokens",
|
|
11728
|
+
approvals: [{
|
|
11729
|
+
type: "erc20",
|
|
11730
|
+
approvalTxHash,
|
|
11731
|
+
target: params.tokenIn,
|
|
11732
|
+
spender: router
|
|
11733
|
+
}],
|
|
11734
|
+
run: async () => {
|
|
11735
|
+
const targetTxHash = await walletClient.writeContract({
|
|
11736
|
+
address: router,
|
|
11737
|
+
abi: liquidRouterAbi,
|
|
11738
|
+
functionName: "swap",
|
|
11739
|
+
args: [
|
|
11740
|
+
params.tokenIn,
|
|
11741
|
+
amountIn,
|
|
11742
|
+
params.tokenOut,
|
|
11743
|
+
params.recipient ?? accountAddress,
|
|
11744
|
+
minAmountOut,
|
|
11745
|
+
params.commands,
|
|
11746
|
+
[...params.inputs],
|
|
11747
|
+
resolveDeadline(params.deadline)
|
|
11748
|
+
],
|
|
11749
|
+
account,
|
|
11750
|
+
chain: void 0,
|
|
11751
|
+
value: params.tokenIn === ETH_ADDRESS ? amountIn : void 0
|
|
11752
|
+
});
|
|
11753
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
11754
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
11755
|
+
}
|
|
11095
11756
|
});
|
|
11096
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
11097
11757
|
return { txHash, receipt };
|
|
11098
11758
|
},
|
|
11099
11759
|
async quoteBuyToken(params) {
|
|
@@ -11160,7 +11820,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11160
11820
|
});
|
|
11161
11821
|
if (quoteDetails.kind === "local") {
|
|
11162
11822
|
const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
|
|
11163
|
-
const
|
|
11823
|
+
const targetTxHash = await walletClient.writeContract({
|
|
11164
11824
|
address: router,
|
|
11165
11825
|
abi: liquidRouterAbi,
|
|
11166
11826
|
functionName: "buy",
|
|
@@ -11176,10 +11836,10 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11176
11836
|
chain: void 0,
|
|
11177
11837
|
value: quoteDetails.quote.amountIn
|
|
11178
11838
|
});
|
|
11179
|
-
const
|
|
11839
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
11180
11840
|
return {
|
|
11181
|
-
txHash,
|
|
11182
|
-
receipt,
|
|
11841
|
+
txHash: targetTxHash,
|
|
11842
|
+
receipt: targetReceipt,
|
|
11183
11843
|
estimatedAmountOut: quoteDetails.quote.estimatedAmountOut,
|
|
11184
11844
|
minAmountOut: quoteDetails.quote.minAmountOut,
|
|
11185
11845
|
routeSource: quoteDetails.quote.routeSource,
|
|
@@ -11271,24 +11931,36 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11271
11931
|
const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
|
|
11272
11932
|
const amountIn = requireInput(params.amountIn, "amountIn");
|
|
11273
11933
|
const tokenAmount = await toTokenAmount(publicClient, params.token, amountIn, "amountIn");
|
|
11274
|
-
await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
11275
|
-
const txHash = await
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
params.token,
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
|
|
11284
|
-
|
|
11285
|
-
|
|
11286
|
-
|
|
11287
|
-
|
|
11288
|
-
|
|
11289
|
-
|
|
11934
|
+
const approvalTxHash2 = await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
11935
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
11936
|
+
operation: "sell token",
|
|
11937
|
+
approvals: [{
|
|
11938
|
+
type: "erc20",
|
|
11939
|
+
approvalTxHash: approvalTxHash2,
|
|
11940
|
+
target: params.token,
|
|
11941
|
+
spender: router
|
|
11942
|
+
}],
|
|
11943
|
+
run: async () => {
|
|
11944
|
+
const targetTxHash = await walletClient.writeContract({
|
|
11945
|
+
address: router,
|
|
11946
|
+
abi: liquidRouterAbi,
|
|
11947
|
+
functionName: "sell",
|
|
11948
|
+
args: [
|
|
11949
|
+
params.token,
|
|
11950
|
+
tokenAmount,
|
|
11951
|
+
params.recipient ?? accountAddress,
|
|
11952
|
+
quoteDetails.quote.minAmountOut,
|
|
11953
|
+
quoteDetails.quote.commands,
|
|
11954
|
+
[...quoteDetails.quote.inputs],
|
|
11955
|
+
resolveDeadline(params.deadline)
|
|
11956
|
+
],
|
|
11957
|
+
account,
|
|
11958
|
+
chain: void 0
|
|
11959
|
+
});
|
|
11960
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
11961
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
11962
|
+
}
|
|
11290
11963
|
});
|
|
11291
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
11292
11964
|
return {
|
|
11293
11965
|
txHash,
|
|
11294
11966
|
receipt,
|
|
@@ -11297,7 +11969,8 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11297
11969
|
routeSource: quoteDetails.quote.routeSource,
|
|
11298
11970
|
execution: quoteDetails.quote.execution,
|
|
11299
11971
|
commands: quoteDetails.quote.commands,
|
|
11300
|
-
inputs: quoteDetails.quote.inputs
|
|
11972
|
+
inputs: quoteDetails.quote.inputs,
|
|
11973
|
+
approvalTxHash: approvalTxHash2
|
|
11301
11974
|
};
|
|
11302
11975
|
}
|
|
11303
11976
|
const approval = await requestUniswapApproval({
|
|
@@ -11316,14 +11989,33 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11316
11989
|
accountAddress,
|
|
11317
11990
|
chainId
|
|
11318
11991
|
})).txHash : void 0;
|
|
11319
|
-
const
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11992
|
+
const sent = await runWithApprovalSideEffectAlert({
|
|
11993
|
+
operation: "sell token",
|
|
11994
|
+
approvals: [
|
|
11995
|
+
{
|
|
11996
|
+
type: "erc20-reset",
|
|
11997
|
+
approvalTxHash: approvalResetTxHash,
|
|
11998
|
+
target: params.token,
|
|
11999
|
+
spender: approval.cancel?.to
|
|
12000
|
+
},
|
|
12001
|
+
{
|
|
12002
|
+
type: "erc20",
|
|
12003
|
+
approvalTxHash,
|
|
12004
|
+
target: params.token,
|
|
12005
|
+
spender: approval.approval?.to
|
|
12006
|
+
}
|
|
12007
|
+
],
|
|
12008
|
+
run: async () => {
|
|
12009
|
+
const swapResponse = await requestUniswapSwap({
|
|
12010
|
+
apiKey: quoteDetails.apiKey,
|
|
12011
|
+
quote: quoteDetails.rawQuote,
|
|
12012
|
+
deadline: uniswapDeadline
|
|
12013
|
+
});
|
|
12014
|
+
return sendPreparedTransaction(publicClient, walletClient, account, swapResponse.swap, {
|
|
12015
|
+
accountAddress,
|
|
12016
|
+
chainId
|
|
12017
|
+
});
|
|
12018
|
+
}
|
|
11327
12019
|
});
|
|
11328
12020
|
return {
|
|
11329
12021
|
...sent,
|
|
@@ -11342,7 +12034,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11342
12034
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
11343
12035
|
const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
|
|
11344
12036
|
const quote = await buildBuyRareQuote(publicClient, chain, addresses, params);
|
|
11345
|
-
const
|
|
12037
|
+
const targetTxHash = await walletClient.writeContract({
|
|
11346
12038
|
address: router,
|
|
11347
12039
|
abi: liquidRouterAbi,
|
|
11348
12040
|
functionName: "buy",
|
|
@@ -11351,10 +12043,10 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
11351
12043
|
chain: void 0,
|
|
11352
12044
|
value: quote.ethAmount
|
|
11353
12045
|
});
|
|
11354
|
-
const
|
|
12046
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
11355
12047
|
return {
|
|
11356
|
-
txHash,
|
|
11357
|
-
receipt,
|
|
12048
|
+
txHash: targetTxHash,
|
|
12049
|
+
receipt: targetReceipt,
|
|
11358
12050
|
estimatedRareOut: quote.estimatedRareOut,
|
|
11359
12051
|
minRareOut: quote.minRareOut,
|
|
11360
12052
|
commands: quote.commands,
|
|
@@ -11715,7 +12407,7 @@ function normalizeLazySovereignCollectionContractType(input) {
|
|
|
11715
12407
|
);
|
|
11716
12408
|
}
|
|
11717
12409
|
function planCreateLazySovereignCollection(params) {
|
|
11718
|
-
const contractType = params.contractType ?? "lazy";
|
|
12410
|
+
const contractType = normalizeLazySovereignCollectionContractType(params.contractType) ?? "lazy";
|
|
11719
12411
|
return {
|
|
11720
12412
|
name: params.name,
|
|
11721
12413
|
symbol: params.symbol,
|
|
@@ -12542,10 +13234,8 @@ async function readReleaseCollectionOwner(publicClient, contract) {
|
|
|
12542
13234
|
);
|
|
12543
13235
|
}
|
|
12544
13236
|
}
|
|
12545
|
-
async function
|
|
13237
|
+
async function assertReleaseMinterCanMint(opts) {
|
|
12546
13238
|
const { publicClient, contract, accountAddress, rareMinter } = opts;
|
|
12547
|
-
const owner = await readReleaseCollectionOwner(publicClient, contract);
|
|
12548
|
-
assertReleaseContractOwner({ contract, accountAddress, owner });
|
|
12549
13239
|
try {
|
|
12550
13240
|
await publicClient.simulateContract({
|
|
12551
13241
|
address: contract,
|
|
@@ -12911,6 +13601,11 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
|
|
|
12911
13601
|
currencyDecimals: currencyDecimals2,
|
|
12912
13602
|
nowSeconds: currentUnixTimestamp3()
|
|
12913
13603
|
});
|
|
13604
|
+
await assertCollectionOwnerForReleaseWrite({
|
|
13605
|
+
publicClient,
|
|
13606
|
+
contract: plan.contract,
|
|
13607
|
+
accountAddress
|
|
13608
|
+
});
|
|
12914
13609
|
const approvalTxHash = await approveReleaseMinterIfNeeded({
|
|
12915
13610
|
publicClient,
|
|
12916
13611
|
walletClient,
|
|
@@ -12919,29 +13614,41 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
|
|
|
12919
13614
|
minter: rareMinter,
|
|
12920
13615
|
autoApprove: params.autoApprove
|
|
12921
13616
|
});
|
|
12922
|
-
await
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
13617
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
13618
|
+
operation: "release configure",
|
|
13619
|
+
approvals: [{
|
|
13620
|
+
type: "minter",
|
|
13621
|
+
approvalTxHash,
|
|
13622
|
+
target: plan.contract,
|
|
13623
|
+
minter: rareMinter
|
|
13624
|
+
}],
|
|
13625
|
+
run: async () => {
|
|
13626
|
+
await assertReleaseMinterCanMint({
|
|
13627
|
+
publicClient,
|
|
13628
|
+
contract: plan.contract,
|
|
13629
|
+
accountAddress,
|
|
13630
|
+
rareMinter
|
|
13631
|
+
});
|
|
13632
|
+
const configureTxHash = await walletClient.writeContract({
|
|
13633
|
+
address: rareMinter,
|
|
13634
|
+
abi: rareMinterAbi,
|
|
13635
|
+
functionName: "prepareMintDirectSale",
|
|
13636
|
+
args: [
|
|
13637
|
+
plan.contract,
|
|
13638
|
+
plan.currencyAddress,
|
|
13639
|
+
plan.price,
|
|
13640
|
+
plan.startTime,
|
|
13641
|
+
plan.maxMints,
|
|
13642
|
+
plan.splitRecipients,
|
|
13643
|
+
plan.splitRatios
|
|
13644
|
+
],
|
|
13645
|
+
account,
|
|
13646
|
+
chain: void 0
|
|
13647
|
+
});
|
|
13648
|
+
const configureReceipt = await publicClient.waitForTransactionReceipt({ hash: configureTxHash });
|
|
13649
|
+
return { txHash: configureTxHash, receipt: configureReceipt };
|
|
13650
|
+
}
|
|
12943
13651
|
});
|
|
12944
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
12945
13652
|
return {
|
|
12946
13653
|
txHash,
|
|
12947
13654
|
receipt,
|
|
@@ -12990,26 +13697,38 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
|
|
|
12990
13697
|
amount: mint.totalPrice,
|
|
12991
13698
|
autoApprove: plan.autoApprove
|
|
12992
13699
|
});
|
|
12993
|
-
const txHash = await
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
mint.
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13700
|
+
const { txHash, receipt, tokenRange } = await runWithApprovalSideEffectAlert({
|
|
13701
|
+
operation: "release mint",
|
|
13702
|
+
approvals: [{
|
|
13703
|
+
type: "erc20",
|
|
13704
|
+
approvalTxHash: payment.approvalTxHash,
|
|
13705
|
+
target: mint.currency,
|
|
13706
|
+
spender: rareMinter
|
|
13707
|
+
}],
|
|
13708
|
+
run: async () => {
|
|
13709
|
+
const targetTxHash = await walletClient.writeContract({
|
|
13710
|
+
address: rareMinter,
|
|
13711
|
+
abi: rareMinterAbi,
|
|
13712
|
+
functionName: "mintDirectSale",
|
|
13713
|
+
args: [
|
|
13714
|
+
mint.contract,
|
|
13715
|
+
mint.currency,
|
|
13716
|
+
mint.price,
|
|
13717
|
+
mint.quantity,
|
|
13718
|
+
mint.proof
|
|
13719
|
+
],
|
|
13720
|
+
account,
|
|
13721
|
+
chain: void 0,
|
|
13722
|
+
value: payment.value
|
|
13723
|
+
});
|
|
13724
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
13725
|
+
const mintedTokenRange = readMintDirectSaleTokenRange({
|
|
13726
|
+
receipt: targetReceipt,
|
|
13727
|
+
contract: mint.contract,
|
|
13728
|
+
buyer: accountAddress
|
|
13729
|
+
});
|
|
13730
|
+
return { txHash: targetTxHash, receipt: targetReceipt, tokenRange: mintedTokenRange };
|
|
13731
|
+
}
|
|
13013
13732
|
});
|
|
13014
13733
|
return {
|
|
13015
13734
|
txHash,
|
|
@@ -14085,10 +14804,14 @@ function addressLeaf(address) {
|
|
|
14085
14804
|
return hexBuffer(keccak2563(address));
|
|
14086
14805
|
}
|
|
14087
14806
|
function parseBytes32(value, field) {
|
|
14088
|
-
if (!isHex5(value) || value.length !== 66) {
|
|
14807
|
+
if (!isHex5(value, { strict: true }) || value.length !== 66) {
|
|
14089
14808
|
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
14090
14809
|
}
|
|
14091
|
-
|
|
14810
|
+
const normalized = value.toLowerCase();
|
|
14811
|
+
if (!isHex5(normalized, { strict: true }) || normalized.length !== 66) {
|
|
14812
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
14813
|
+
}
|
|
14814
|
+
return normalized;
|
|
14092
14815
|
}
|
|
14093
14816
|
function parseBytes32Array(values, field) {
|
|
14094
14817
|
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
@@ -14164,14 +14887,15 @@ function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
|
14164
14887
|
const { tree, root } = buildBatchListingTree(
|
|
14165
14888
|
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
14166
14889
|
);
|
|
14167
|
-
|
|
14890
|
+
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
14891
|
+
if (root !== artifactRoot) {
|
|
14168
14892
|
throw new Error(
|
|
14169
14893
|
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
14170
14894
|
);
|
|
14171
14895
|
}
|
|
14172
14896
|
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
14173
14897
|
return {
|
|
14174
|
-
root:
|
|
14898
|
+
root: artifactRoot,
|
|
14175
14899
|
contract: contractChecksum,
|
|
14176
14900
|
tokenId: tokenIdBig.toString(),
|
|
14177
14901
|
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
@@ -14192,7 +14916,8 @@ function buildAllowListProofFields(artifact, buyer) {
|
|
|
14192
14916
|
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
14193
14917
|
}
|
|
14194
14918
|
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
14195
|
-
|
|
14919
|
+
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
14920
|
+
if (root !== artifactAllowListRoot) {
|
|
14196
14921
|
throw new Error(
|
|
14197
14922
|
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
14198
14923
|
);
|
|
@@ -14208,7 +14933,7 @@ function assertRecord(value, field) {
|
|
|
14208
14933
|
}
|
|
14209
14934
|
}
|
|
14210
14935
|
function assertHexRoot(value, field) {
|
|
14211
|
-
if (typeof value !== "string" || !isHex5(value) || value.length !== 66) {
|
|
14936
|
+
if (typeof value !== "string" || !isHex5(value, { strict: true }) || value.length !== 66) {
|
|
14212
14937
|
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
14213
14938
|
}
|
|
14214
14939
|
}
|
|
@@ -14355,6 +15080,7 @@ function createRareClient(config) {
|
|
|
14355
15080
|
contracts: {
|
|
14356
15081
|
factory: addresses.factory,
|
|
14357
15082
|
auction: addresses.auction,
|
|
15083
|
+
rareBridge: addresses.rareBridge,
|
|
14358
15084
|
sovereignFactory: addresses.sovereignFactory,
|
|
14359
15085
|
lazySovereignFactory: addresses.lazySovereignFactory,
|
|
14360
15086
|
rareMinter: addresses.rareMinter,
|
|
@@ -14370,6 +15096,7 @@ function createRareClient(config) {
|
|
|
14370
15096
|
v4Quoter: addresses.v4Quoter
|
|
14371
15097
|
},
|
|
14372
15098
|
liquidEdition: createLiquidNamespace(config, chain, addresses),
|
|
15099
|
+
bridge: createBridgeNamespace(publicClient, config, chain),
|
|
14373
15100
|
swap: createSwapNamespace(config, chain, chainId, addresses),
|
|
14374
15101
|
auction,
|
|
14375
15102
|
offer,
|
|
@@ -18906,14 +19633,172 @@ function formatLongValue(value, maxLength = 160) {
|
|
|
18906
19633
|
return value.length <= maxLength ? value : `${value.slice(0, maxLength - 3)}...`;
|
|
18907
19634
|
}
|
|
18908
19635
|
|
|
19636
|
+
// src/commands/bridge.ts
|
|
19637
|
+
import { Command as Command18 } from "commander";
|
|
19638
|
+
import { formatEther as formatEther2 } from "viem";
|
|
19639
|
+
|
|
19640
|
+
// src/commands/options.ts
|
|
19641
|
+
import { getAddress as getAddress14, isAddress as isAddress11 } from "viem";
|
|
19642
|
+
var chainOptionDescription = "chain name (mainnet, sepolia, base, base-sepolia)";
|
|
19643
|
+
var chainIdOptionDescription = "chain ID (1, 11155111, 8453, 84532)";
|
|
19644
|
+
function addChainOptions(cmd) {
|
|
19645
|
+
return cmd.option("--chain <chain>", chainOptionDescription).option("--chain-id <id>", chainIdOptionDescription);
|
|
19646
|
+
}
|
|
19647
|
+
|
|
19648
|
+
// src/commands/bridge.ts
|
|
19649
|
+
function bridgeCommand() {
|
|
19650
|
+
const cmd = new Command18("bridge");
|
|
19651
|
+
cmd.description("Bridge RARE across supported CCIP routes");
|
|
19652
|
+
cmd.addCommand(bridgeQuoteCommand());
|
|
19653
|
+
cmd.addCommand(bridgeSendCommand());
|
|
19654
|
+
return cmd;
|
|
19655
|
+
}
|
|
19656
|
+
function bridgeQuoteCommand() {
|
|
19657
|
+
const cmd = new Command18("quote");
|
|
19658
|
+
cmd.description("Quote the native fee for bridging RARE");
|
|
19659
|
+
addBridgeRouteOptions(cmd).action(async (opts) => {
|
|
19660
|
+
const plan = parseBridgeRouteOptions(opts, "rare bridge quote");
|
|
19661
|
+
const publicClient = getPublicClient(plan.sourceChain);
|
|
19662
|
+
const rare = createRareClient({
|
|
19663
|
+
publicClient,
|
|
19664
|
+
account: getConfiguredAccountAddress(plan.sourceChain)
|
|
19665
|
+
});
|
|
19666
|
+
const quote = await rare.bridge.quote({
|
|
19667
|
+
amount: plan.amount,
|
|
19668
|
+
destinationChain: plan.destinationChain,
|
|
19669
|
+
recipient: plan.recipient
|
|
19670
|
+
});
|
|
19671
|
+
output(
|
|
19672
|
+
{
|
|
19673
|
+
sourceChain: quote.sourceChain,
|
|
19674
|
+
sourceChainId: quote.sourceChainId,
|
|
19675
|
+
destinationChain: quote.destinationChain,
|
|
19676
|
+
destinationChainId: quote.destinationChainId,
|
|
19677
|
+
sourceBridgeAddress: quote.sourceBridgeAddress,
|
|
19678
|
+
destinationBridgeAddress: quote.destinationBridgeAddress,
|
|
19679
|
+
rareTokenAddress: quote.rareTokenAddress,
|
|
19680
|
+
destinationCcipChainSelector: quote.destinationCcipChainSelector,
|
|
19681
|
+
amount: quote.amount,
|
|
19682
|
+
recipient: quote.recipient,
|
|
19683
|
+
nativeFee: quote.nativeFee,
|
|
19684
|
+
estimatedGas: quote.estimatedGas ?? null,
|
|
19685
|
+
distributionData: quote.distributionData
|
|
19686
|
+
},
|
|
19687
|
+
() => {
|
|
19688
|
+
printBridgeQuote(quote);
|
|
19689
|
+
}
|
|
19690
|
+
);
|
|
19691
|
+
});
|
|
19692
|
+
return cmd;
|
|
19693
|
+
}
|
|
19694
|
+
function bridgeSendCommand() {
|
|
19695
|
+
const cmd = new Command18("send");
|
|
19696
|
+
cmd.description("Bridge RARE to another supported chain");
|
|
19697
|
+
addBridgeRouteOptions(cmd).option("--yes", "yes to all prompts, including approval and transaction submission").action(async (opts) => {
|
|
19698
|
+
const plan = parseBridgeRouteOptions(opts, "rare bridge send");
|
|
19699
|
+
const publicClient = getPublicClient(plan.sourceChain);
|
|
19700
|
+
const { client } = getWalletClient(plan.sourceChain);
|
|
19701
|
+
const rare = createRareClient({ publicClient, walletClient: client });
|
|
19702
|
+
log(`Bridging RARE from ${plan.sourceChain} to ${plan.destinationChain}...`);
|
|
19703
|
+
log(` Source bridge: ${rare.contracts.rareBridge ?? "unavailable"}`);
|
|
19704
|
+
log(` Amount: ${plan.amount} RARE`);
|
|
19705
|
+
if (plan.recipient !== void 0) {
|
|
19706
|
+
log(` Recipient: ${plan.recipient}`);
|
|
19707
|
+
}
|
|
19708
|
+
const sendParams = {
|
|
19709
|
+
amount: plan.amount,
|
|
19710
|
+
destinationChain: plan.destinationChain,
|
|
19711
|
+
recipient: plan.recipient
|
|
19712
|
+
};
|
|
19713
|
+
const result = await runWithPaymentApprovalConsent({
|
|
19714
|
+
commandName: "rare bridge send",
|
|
19715
|
+
approvalMessage: "RARE approval is required before bridging.",
|
|
19716
|
+
runWithoutApproval: async () => rare.bridge.send({
|
|
19717
|
+
...sendParams,
|
|
19718
|
+
autoApprove: opts.yes === true
|
|
19719
|
+
}),
|
|
19720
|
+
runWithApproval: async () => rare.bridge.send({
|
|
19721
|
+
...sendParams,
|
|
19722
|
+
autoApprove: true
|
|
19723
|
+
})
|
|
19724
|
+
});
|
|
19725
|
+
if (result === void 0) {
|
|
19726
|
+
return;
|
|
19727
|
+
}
|
|
19728
|
+
output(
|
|
19729
|
+
{
|
|
19730
|
+
txHash: result.txHash,
|
|
19731
|
+
blockNumber: result.receipt.blockNumber.toString(),
|
|
19732
|
+
approvalTxHash: result.approvalTxHash ?? null,
|
|
19733
|
+
ccipExplorerUrl: result.ccipExplorerUrl,
|
|
19734
|
+
sourceChain: result.sourceChain,
|
|
19735
|
+
sourceChainId: result.sourceChainId,
|
|
19736
|
+
destinationChain: result.destinationChain,
|
|
19737
|
+
destinationChainId: result.destinationChainId,
|
|
19738
|
+
sourceBridgeAddress: result.sourceBridgeAddress,
|
|
19739
|
+
destinationBridgeAddress: result.destinationBridgeAddress,
|
|
19740
|
+
rareTokenAddress: result.rareTokenAddress,
|
|
19741
|
+
destinationCcipChainSelector: result.destinationCcipChainSelector,
|
|
19742
|
+
amount: result.amount,
|
|
19743
|
+
recipient: result.recipient,
|
|
19744
|
+
nativeFee: result.nativeFee,
|
|
19745
|
+
estimatedGas: result.estimatedGas ?? null,
|
|
19746
|
+
distributionData: result.distributionData
|
|
19747
|
+
},
|
|
19748
|
+
() => {
|
|
19749
|
+
if (result.approvalTxHash !== void 0) {
|
|
19750
|
+
console.log(`Approval tx sent: ${result.approvalTxHash}`);
|
|
19751
|
+
}
|
|
19752
|
+
console.log(`Transaction sent: ${result.txHash}`);
|
|
19753
|
+
console.log(`Confirmed in block ${result.receipt.blockNumber}`);
|
|
19754
|
+
console.log(`CCIP explorer: ${result.ccipExplorerUrl}`);
|
|
19755
|
+
}
|
|
19756
|
+
);
|
|
19757
|
+
});
|
|
19758
|
+
return cmd;
|
|
19759
|
+
}
|
|
19760
|
+
function addBridgeRouteOptions(cmd) {
|
|
19761
|
+
return addChainOptions(cmd).requiredOption("--amount <amount>", "RARE amount to bridge").requiredOption("--destination-chain <chain>", "destination chain (mainnet, base, sepolia, base-sepolia)").option("--recipient <address>", "destination recipient address");
|
|
19762
|
+
}
|
|
19763
|
+
function parseBridgeRouteOptions(opts, commandName) {
|
|
19764
|
+
if (opts.amount === void 0) {
|
|
19765
|
+
throw new Error(`${commandName} requires --amount.`);
|
|
19766
|
+
}
|
|
19767
|
+
if (opts.destinationChain === void 0) {
|
|
19768
|
+
throw new Error(`${commandName} requires --destination-chain.`);
|
|
19769
|
+
}
|
|
19770
|
+
return {
|
|
19771
|
+
sourceChain: getActiveChain(opts.chain, opts.chainId),
|
|
19772
|
+
destinationChain: parseDestinationChain(opts.destinationChain),
|
|
19773
|
+
amount: opts.amount,
|
|
19774
|
+
recipient: parseOptionalAddress(opts.recipient, "--recipient")
|
|
19775
|
+
};
|
|
19776
|
+
}
|
|
19777
|
+
function parseDestinationChain(value) {
|
|
19778
|
+
if (!isSupportedChain(value)) {
|
|
19779
|
+
throw new Error(`--destination-chain must be one of: ${supportedChains.join(", ")}`);
|
|
19780
|
+
}
|
|
19781
|
+
return value;
|
|
19782
|
+
}
|
|
19783
|
+
function printBridgeQuote(quote) {
|
|
19784
|
+
console.log(`
|
|
19785
|
+
RARE bridge quote: ${quote.sourceChain} -> ${quote.destinationChain}`);
|
|
19786
|
+
console.log(` Amount: ${formatEther2(quote.amount)} RARE`);
|
|
19787
|
+
console.log(` Recipient: ${quote.recipient}`);
|
|
19788
|
+
console.log(` Native fee: ${formatEther2(quote.nativeFee)} ETH`);
|
|
19789
|
+
console.log(` Estimated gas: ${quote.estimatedGas?.toString() ?? "unavailable"}`);
|
|
19790
|
+
console.log(` Source bridge: ${quote.sourceBridgeAddress}`);
|
|
19791
|
+
console.log(` Destination bridge: ${quote.destinationBridgeAddress}`);
|
|
19792
|
+
}
|
|
19793
|
+
|
|
18909
19794
|
// src/commands/swap.ts
|
|
18910
19795
|
import { readFile as readFile5 } from "fs/promises";
|
|
18911
19796
|
import { createInterface as createInterface6 } from "readline/promises";
|
|
18912
|
-
import { Command as
|
|
18913
|
-
import { formatEther as
|
|
19797
|
+
import { Command as Command19 } from "commander";
|
|
19798
|
+
import { formatEther as formatEther4 } from "viem";
|
|
18914
19799
|
|
|
18915
19800
|
// src/commands/swap-core.ts
|
|
18916
|
-
import { formatEther as
|
|
19801
|
+
import { formatEther as formatEther3, formatUnits as formatUnits9, getAddress as getAddress15, isHex as isHex7 } from "viem";
|
|
18917
19802
|
function parseInputsJson(raw, label) {
|
|
18918
19803
|
const parsed = parseJson4(raw, label);
|
|
18919
19804
|
if (!Array.isArray(parsed)) {
|
|
@@ -18941,7 +19826,7 @@ function ensureHex(value, label) {
|
|
|
18941
19826
|
}
|
|
18942
19827
|
function parseAddress3(value, label) {
|
|
18943
19828
|
try {
|
|
18944
|
-
return
|
|
19829
|
+
return getAddress15(value);
|
|
18945
19830
|
} catch {
|
|
18946
19831
|
throw new Error(`${label} must be a valid EVM address.`);
|
|
18947
19832
|
}
|
|
@@ -18967,15 +19852,15 @@ function formatBuyRareQuoteLines(params) {
|
|
|
18967
19852
|
`Quote for buying RARE on ${params.chain}:`,
|
|
18968
19853
|
...params.router ? [` Router: ${params.router}`] : [],
|
|
18969
19854
|
` ETH in: ${params.eth}`,
|
|
18970
|
-
` Estimated RARE out: ${
|
|
18971
|
-
` Min RARE out: ${
|
|
19855
|
+
` Estimated RARE out: ${formatEther3(params.quote.estimatedRareOut)}`,
|
|
19856
|
+
` Min RARE out: ${formatEther3(params.quote.minRareOut)}`,
|
|
18972
19857
|
params.usedMinRareOutOverride ? " Min out source: manual override" : ` Slippage: ${params.quote.slippageBps} bps`,
|
|
18973
19858
|
...params.recipient ? [` Recipient: ${params.recipient}`] : []
|
|
18974
19859
|
];
|
|
18975
19860
|
return lines;
|
|
18976
19861
|
}
|
|
18977
19862
|
function formatQuotedAmount(amount, decimals) {
|
|
18978
|
-
return decimals === 18 ?
|
|
19863
|
+
return decimals === 18 ? formatEther3(amount) : formatUnits9(amount, decimals);
|
|
18979
19864
|
}
|
|
18980
19865
|
function formatTokenTradeQuoteLines(params) {
|
|
18981
19866
|
const outputLabel = params.direction === "buy" ? "Estimated token out" : "Estimated ETH out";
|
|
@@ -19022,7 +19907,7 @@ async function confirmProceed() {
|
|
|
19022
19907
|
}
|
|
19023
19908
|
}
|
|
19024
19909
|
function swapTokensCommand() {
|
|
19025
|
-
const cmd = new
|
|
19910
|
+
const cmd = new Command19("tokens");
|
|
19026
19911
|
cmd.alias("swap");
|
|
19027
19912
|
cmd.description("Execute a raw router token swap");
|
|
19028
19913
|
cmd.requiredOption("--token-in <address>", "input token address").requiredOption("--amount-in <amount>", "amount of the input token").requiredOption("--token-out <address>", "output token address").requiredOption("--min-amount-out <amount>", "minimum output token amount").requiredOption("--commands <hex>", "raw router commands hex").requiredOption("--inputs-file <path>", "JSON file containing router input calldata array").option("--recipient <address>", "recipient address").option("--deadline <seconds>", "deadline as a unix timestamp in seconds").option("--yes", "skip the interactive transaction confirmation").option("--chain <chain>", "chain to use (mainnet, sepolia)").option("--chain-id <id>", "chain ID (1, 11155111)").action(async (opts) => {
|
|
@@ -19068,7 +19953,7 @@ function swapTokensCommand() {
|
|
|
19068
19953
|
return cmd;
|
|
19069
19954
|
}
|
|
19070
19955
|
function swapBuyTokenCommand() {
|
|
19071
|
-
const cmd = new
|
|
19956
|
+
const cmd = new Command19("buy-token");
|
|
19072
19957
|
cmd.description("Buy a token with ETH using a canonical liquid route or Uniswap fallback");
|
|
19073
19958
|
cmd.requiredOption("--token <address>", "token address to buy").requiredOption("--amount-in <amount>", "ETH amount to spend").option("--route <mode>", "route mode: auto, local, uniswap, raw (default: auto)").option("--slippage-bps <bps>", "slippage in basis points (default: 50)").option("--min-amount-out <amount>", "override minimum token amount out").option("--commands <hex>", "raw router commands hex when --route raw").option("--inputs-file <path>", "JSON file containing router input calldata array when --route raw").option("--quote-only", "show the quote without submitting a transaction").option("--yes", "submit the quoted swap and any required approvals without an interactive confirmation").option("--recipient <address>", "recipient address").option("--deadline <seconds>", "deadline as a unix timestamp in seconds").option("--chain <chain>", "chain to use").option("--chain-id <id>", "chain ID (1, 11155111, 8453, 84532)").action(async (opts) => {
|
|
19074
19959
|
const quoteOnly = opts.quoteOnly === true;
|
|
@@ -19220,7 +20105,7 @@ function swapBuyTokenCommand() {
|
|
|
19220
20105
|
return cmd;
|
|
19221
20106
|
}
|
|
19222
20107
|
function swapSellTokenCommand() {
|
|
19223
|
-
const cmd = new
|
|
20108
|
+
const cmd = new Command19("sell-token");
|
|
19224
20109
|
cmd.description("Sell a token for ETH using a canonical liquid route or Uniswap fallback");
|
|
19225
20110
|
cmd.requiredOption("--token <address>", "token address to sell").requiredOption("--amount-in <amount>", "token amount to sell").option("--route <mode>", "route mode: auto, local, uniswap, raw (default: auto)").option("--slippage-bps <bps>", "slippage in basis points (default: 50)").option("--min-amount-out <amount>", "override minimum ETH amount out").option("--commands <hex>", "raw router commands hex when --route raw").option("--inputs-file <path>", "JSON file containing router input calldata array when --route raw").option("--quote-only", "show the quote without submitting a transaction").option("--yes", "submit the quoted swap and any required approvals without an interactive confirmation").option("--recipient <address>", "recipient address").option("--deadline <seconds>", "deadline as a unix timestamp in seconds").option("--chain <chain>", "chain to use").option("--chain-id <id>", "chain ID (1, 11155111, 8453, 84532)").action(async (opts) => {
|
|
19226
20111
|
const quoteOnly = opts.quoteOnly === true;
|
|
@@ -19278,7 +20163,7 @@ function swapSellTokenCommand() {
|
|
|
19278
20163
|
},
|
|
19279
20164
|
() => {
|
|
19280
20165
|
console.log(`Transaction sent: ${result2.txHash}`);
|
|
19281
|
-
console.log(`Min ETH out: ${
|
|
20166
|
+
console.log(`Min ETH out: ${formatEther4(result2.minAmountOut)}`);
|
|
19282
20167
|
}
|
|
19283
20168
|
);
|
|
19284
20169
|
return;
|
|
@@ -19366,15 +20251,15 @@ function swapSellTokenCommand() {
|
|
|
19366
20251
|
},
|
|
19367
20252
|
() => {
|
|
19368
20253
|
console.log(`Transaction sent: ${result.txHash}`);
|
|
19369
|
-
console.log(`Estimated ETH out: ${
|
|
19370
|
-
console.log(`Min ETH out: ${
|
|
20254
|
+
console.log(`Estimated ETH out: ${formatEther4(result.estimatedAmountOut)}`);
|
|
20255
|
+
console.log(`Min ETH out: ${formatEther4(result.minAmountOut)}`);
|
|
19371
20256
|
}
|
|
19372
20257
|
);
|
|
19373
20258
|
});
|
|
19374
20259
|
return cmd;
|
|
19375
20260
|
}
|
|
19376
20261
|
function swapBuyRareCommand() {
|
|
19377
|
-
const cmd = new
|
|
20262
|
+
const cmd = new Command19("buy-rare");
|
|
19378
20263
|
cmd.description("Buy RARE with ETH using the curated canonical route");
|
|
19379
20264
|
cmd.requiredOption("--amount-in <amount>", "ETH amount to spend").option("--slippage-bps <bps>", "slippage in basis points (default: 50)").option("--min-amount-out <amount>", "override minimum RARE out").option("--quote-only", "show the quote without submitting a transaction").option("--yes", "submit the quoted swap without an interactive confirmation").option("--recipient <address>", "recipient address").option("--deadline <seconds>", "deadline as a unix timestamp in seconds").option("--chain <chain>", "chain to use (mainnet, sepolia)").option("--chain-id <id>", "chain ID (1, 11155111)").action(async (opts) => {
|
|
19380
20265
|
const quoteOnly = opts.quoteOnly === true;
|
|
@@ -19450,15 +20335,15 @@ function swapBuyRareCommand() {
|
|
|
19450
20335
|
},
|
|
19451
20336
|
() => {
|
|
19452
20337
|
console.log(`Transaction sent: ${result.txHash}`);
|
|
19453
|
-
console.log(`Estimated RARE out: ${
|
|
19454
|
-
console.log(`Min RARE out: ${
|
|
20338
|
+
console.log(`Estimated RARE out: ${formatEther4(result.estimatedRareOut)}`);
|
|
20339
|
+
console.log(`Min RARE out: ${formatEther4(result.minRareOut)}`);
|
|
19455
20340
|
}
|
|
19456
20341
|
);
|
|
19457
20342
|
});
|
|
19458
20343
|
return cmd;
|
|
19459
20344
|
}
|
|
19460
20345
|
function swapCommand() {
|
|
19461
|
-
const cmd = new
|
|
20346
|
+
const cmd = new Command19("swap");
|
|
19462
20347
|
cmd.description("Interact with token swap routes");
|
|
19463
20348
|
cmd.addCommand(swapTokensCommand());
|
|
19464
20349
|
cmd.addCommand(swapBuyTokenCommand());
|
|
@@ -19468,9 +20353,9 @@ function swapCommand() {
|
|
|
19468
20353
|
}
|
|
19469
20354
|
|
|
19470
20355
|
// src/commands/user.ts
|
|
19471
|
-
import { Command as
|
|
20356
|
+
import { Command as Command20 } from "commander";
|
|
19472
20357
|
function userCommand() {
|
|
19473
|
-
const cmd = new
|
|
20358
|
+
const cmd = new Command20("user");
|
|
19474
20359
|
cmd.description("Get RARE Protocol users");
|
|
19475
20360
|
cmd.command("get").description("Get a user by wallet address").argument("<address>", "wallet address").action(async (address) => {
|
|
19476
20361
|
const userAddress = parseAddress(address, "<address>");
|
|
@@ -19484,9 +20369,9 @@ function userCommand() {
|
|
|
19484
20369
|
}
|
|
19485
20370
|
|
|
19486
20371
|
// src/commands/utils.ts
|
|
19487
|
-
import { Command as
|
|
20372
|
+
import { Command as Command21 } from "commander";
|
|
19488
20373
|
function utilsCommand() {
|
|
19489
|
-
const cmd = new
|
|
20374
|
+
const cmd = new Command21("utils");
|
|
19490
20375
|
cmd.description("Offline Merkle tree and proof utilities");
|
|
19491
20376
|
cmd.addCommand(createUtilsTreeCommand());
|
|
19492
20377
|
cmd.addCommand(createUtilsMerkleCommand());
|
|
@@ -19494,14 +20379,14 @@ function utilsCommand() {
|
|
|
19494
20379
|
}
|
|
19495
20380
|
|
|
19496
20381
|
// src/commands/mcp.ts
|
|
19497
|
-
import { Command as
|
|
20382
|
+
import { Command as Command22 } from "commander";
|
|
19498
20383
|
|
|
19499
20384
|
// src/mcp/server.ts
|
|
19500
20385
|
import { readFile as readFile6 } from "fs/promises";
|
|
19501
20386
|
import { basename as basename3 } from "path";
|
|
19502
20387
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
19503
20388
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
19504
|
-
import { isAddress as
|
|
20389
|
+
import { isAddress as isAddress12, isHex as isHex8 } from "viem";
|
|
19505
20390
|
import { z } from "zod";
|
|
19506
20391
|
|
|
19507
20392
|
// src/mcp/core.ts
|
|
@@ -19536,6 +20421,8 @@ var mcpToolSpecs = [
|
|
|
19536
20421
|
sdkTool("write", "rare.swap.buy", "Execute a raw liquid-router token buy."),
|
|
19537
20422
|
sdkTool("write", "rare.swap.sell", "Execute a raw liquid-router token sell."),
|
|
19538
20423
|
sdkTool("write", "rare.swap.swapTokens", "Execute a raw liquid-router token swap."),
|
|
20424
|
+
sdkTool("read", "rare.bridge.quote", "Quote the native fee for bridging RARE."),
|
|
20425
|
+
sdkTool("write", "rare.bridge.send", "Bridge RARE to another supported chain."),
|
|
19539
20426
|
sdkTool("read", "rare.swap.quoteBuyToken", "Quote buying a token with ETH."),
|
|
19540
20427
|
sdkTool("write", "rare.swap.buyToken", "Buy a token with ETH."),
|
|
19541
20428
|
sdkTool("read", "rare.swap.quoteSellToken", "Quote selling a token for ETH."),
|
|
@@ -19624,6 +20511,13 @@ var mcpToolNames = mcpToolSpecs.map((tool) => tool.name);
|
|
|
19624
20511
|
function selectMcpToolNames(opts) {
|
|
19625
20512
|
return opts.allowWrites ? [...mcpReadToolNames, ...mcpWriteToolNames] : [...mcpReadToolNames];
|
|
19626
20513
|
}
|
|
20514
|
+
function shapeMcpToolAnnotations(access) {
|
|
20515
|
+
return {
|
|
20516
|
+
readOnlyHint: access === "read",
|
|
20517
|
+
destructiveHint: access === "write" ? true : void 0,
|
|
20518
|
+
openWorldHint: true
|
|
20519
|
+
};
|
|
20520
|
+
}
|
|
19627
20521
|
function sdkPathToMcpToolName(sdkPath) {
|
|
19628
20522
|
const path2 = sdkPath.startsWith("rare.") ? sdkPath.slice("rare.".length) : sdkPath;
|
|
19629
20523
|
return path2.split(".").map(camelToSnake).join("_");
|
|
@@ -19692,7 +20586,7 @@ function isRecord10(value) {
|
|
|
19692
20586
|
// src/mcp/server.ts
|
|
19693
20587
|
var chainSchema = z.enum(supportedChains);
|
|
19694
20588
|
var optionalChain = { chain: chainSchema.optional() };
|
|
19695
|
-
var addressSchema = z.string().refine(
|
|
20589
|
+
var addressSchema = z.string().refine(isAddress12, "must be a valid 0x address");
|
|
19696
20590
|
var hexSchema = z.string().refine(isHex8, "must be a hex string");
|
|
19697
20591
|
var integerSchema = z.union([z.string(), z.number()]);
|
|
19698
20592
|
var amountSchema = z.union([z.string(), z.number()]);
|
|
@@ -19762,11 +20656,7 @@ function registerTool(server, spec) {
|
|
|
19762
20656
|
server.registerTool(spec.name, {
|
|
19763
20657
|
description: spec.description,
|
|
19764
20658
|
inputSchema: tool.inputSchema,
|
|
19765
|
-
annotations:
|
|
19766
|
-
readOnlyHint: spec.access === "read",
|
|
19767
|
-
destructiveHint: spec.access === "write" ? false : void 0,
|
|
19768
|
-
openWorldHint: true
|
|
19769
|
-
}
|
|
20659
|
+
annotations: shapeMcpToolAnnotations(spec.access)
|
|
19770
20660
|
}, async (args) => withToolErrors(async () => tool.handler(args)));
|
|
19771
20661
|
}
|
|
19772
20662
|
var toolHandlers = {
|
|
@@ -19863,6 +20753,14 @@ var toolHandlers = {
|
|
|
19863
20753
|
inputSchema: { ...optionalChain, tokenIn: addressSchema, tokenOut: addressSchema, amountIn: amountSchema, ...rawRouteSchema, recipient: addressSchema.optional(), deadline: integerSchema.optional() },
|
|
19864
20754
|
handler: ({ chain, ...args }) => callWrite(chain, async (rare) => txResult(await rare.swap.swapTokens(args)))
|
|
19865
20755
|
},
|
|
20756
|
+
bridge_quote: {
|
|
20757
|
+
inputSchema: { ...optionalChain, amount: amountSchema, destinationChain: chainSchema, recipient: addressSchema.optional() },
|
|
20758
|
+
handler: ({ chain, ...args }) => callRead(chain, (rare) => rare.bridge.quote(args))
|
|
20759
|
+
},
|
|
20760
|
+
bridge_send: {
|
|
20761
|
+
inputSchema: { ...optionalChain, amount: amountSchema, destinationChain: chainSchema, recipient: addressSchema.optional(), ...autoApproveSchema },
|
|
20762
|
+
handler: ({ chain, ...args }) => callWrite(chain, async (rare) => txResult(await rare.bridge.send(args)))
|
|
20763
|
+
},
|
|
19866
20764
|
swap_quote_buy_token: {
|
|
19867
20765
|
inputSchema: { ...optionalChain, token: addressSchema, amountIn: amountSchema, minAmountOut: amountSchema.optional(), slippageBps: integerSchema.optional(), recipient: addressSchema.optional(), deadline: integerSchema.optional() },
|
|
19868
20766
|
handler: ({ chain, ...args }) => callRead(chain, (rare) => rare.swap.quoteBuyToken(args))
|
|
@@ -20220,6 +21118,7 @@ function readRare(chain) {
|
|
|
20220
21118
|
const selected = resolveChain(chain);
|
|
20221
21119
|
return createRareClient({
|
|
20222
21120
|
publicClient: getPublicClient(selected),
|
|
21121
|
+
account: getConfiguredAccountAddress(selected),
|
|
20223
21122
|
resolveUniswapApiKey: () => getConfiguredUniswapApiKey(selected)
|
|
20224
21123
|
});
|
|
20225
21124
|
}
|
|
@@ -20301,7 +21200,7 @@ var McpToolError = class extends Error {
|
|
|
20301
21200
|
|
|
20302
21201
|
// src/commands/mcp.ts
|
|
20303
21202
|
function mcpCommand() {
|
|
20304
|
-
const cmd = new
|
|
21203
|
+
const cmd = new Command22("mcp");
|
|
20305
21204
|
cmd.description("Run MCP server integrations");
|
|
20306
21205
|
cmd.command("serve").description("Start a stdio MCP server for agent-friendly RARE SDK access").option("--allow-writes", "register write-capable tools").action(async (opts) => {
|
|
20307
21206
|
await serveMcp({ allowWrites: Boolean(opts.allowWrites) });
|
|
@@ -20339,7 +21238,7 @@ function requiresExplicitConfirmation(commandPath2) {
|
|
|
20339
21238
|
// package.json
|
|
20340
21239
|
var package_default = {
|
|
20341
21240
|
name: "@rareprotocol/rare-cli",
|
|
20342
|
-
version: "1.
|
|
21241
|
+
version: "1.2.0",
|
|
20343
21242
|
description: "CLI tool for interacting with the RARE protocol smart contracts",
|
|
20344
21243
|
type: "module",
|
|
20345
21244
|
license: "MIT",
|
|
@@ -20453,7 +21352,7 @@ var package_default = {
|
|
|
20453
21352
|
|
|
20454
21353
|
// src/program.ts
|
|
20455
21354
|
function createRareProgram() {
|
|
20456
|
-
const program2 = new
|
|
21355
|
+
const program2 = new Command23();
|
|
20457
21356
|
program2.name("rare").description("CLI tool for interacting with the RARE protocol smart contracts").version(package_default.version).option("--json", "output results as JSON");
|
|
20458
21357
|
program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
20459
21358
|
const decision = confirmationDecision(program2, actionCommand);
|
|
@@ -20482,6 +21381,7 @@ function createRareProgram() {
|
|
|
20482
21381
|
program2.addCommand(collectionCommand());
|
|
20483
21382
|
program2.addCommand(currenciesCommand());
|
|
20484
21383
|
program2.addCommand(liquidEditionCommand());
|
|
21384
|
+
program2.addCommand(bridgeCommand());
|
|
20485
21385
|
program2.addCommand(swapCommand());
|
|
20486
21386
|
program2.addCommand(userCommand());
|
|
20487
21387
|
program2.addCommand(utilsCommand());
|