@rareprotocol/rare-cli 1.0.2 → 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 +31 -2
- 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 +4434 -2986
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +11 -5
- package/package.json +4 -2
package/dist/client.js
CHANGED
|
@@ -17,6 +17,7 @@ var contractAddresses = {
|
|
|
17
17
|
sepolia: {
|
|
18
18
|
factory: getAddress("0x3c7526a0975156299ceef369b8ff3c01cc670523"),
|
|
19
19
|
auction: getAddress("0xC8Edc7049b233641ad3723D6C60019D1c8771612"),
|
|
20
|
+
rareBridge: getAddress("0xdC168291658f6C5F1D0b33E573c4d289DCA9dD08"),
|
|
20
21
|
sovereignFactory: getAddress("0x46B2850ba7787734F648A6848b5eDE0815C1F8Bf"),
|
|
21
22
|
lazySovereignFactory: getAddress("0xc5B8Ad9003673a23d005A6448C74d8955a1a38fA"),
|
|
22
23
|
rareMinter: getAddress("0xd28Dc0B89104d7BBd902F338a0193fF063617ccE"),
|
|
@@ -34,6 +35,7 @@ var contractAddresses = {
|
|
|
34
35
|
mainnet: {
|
|
35
36
|
factory: getAddress("0xAe8E375a268Ed6442bEaC66C6254d6De5AeD4aB1"),
|
|
36
37
|
auction: getAddress("0x6D7c44773C52D396F43c2D511B81aa168E9a7a42"),
|
|
38
|
+
rareBridge: getAddress("0x88135dd0e7a8a2e42272dda89849a997ce2e83f7"),
|
|
37
39
|
sovereignFactory: getAddress("0xe980ec62378529d95ba446433f4deb6324129c59"),
|
|
38
40
|
lazySovereignFactory: getAddress("0xba798BD606d86D207ca2751510173532899117a1"),
|
|
39
41
|
rareMinter: getAddress("0x5fa112EFeD8297bec0010b312208d223E0cE891E"),
|
|
@@ -44,19 +46,27 @@ var contractAddresses = {
|
|
|
44
46
|
marketplaceSettings: getAddress("0x61DBF87164d33FD3695256DC8Ba74D3B1d304170"),
|
|
45
47
|
erc20ApprovalManager: getAddress("0xa837a7eAff154Ab837617Cf7250648D3Ec0A4436"),
|
|
46
48
|
erc721ApprovalManager: getAddress("0x4bb0Deea6d1A30C601338aAB776d394C2AE5c0F8"),
|
|
47
|
-
liquidFactory: getAddress("
|
|
49
|
+
liquidFactory: getAddress("0x25f993C222fE5e891128a782A5168f1C78629540"),
|
|
48
50
|
swapRouter: getAddress("0xEBd58EdA8408d9EA409f2c2bE8898BD9738f3583"),
|
|
49
51
|
v4Quoter: getAddress("0x52F0E24D1c21C8A0cB1e5a5dD6198556BD9E1203")
|
|
50
52
|
},
|
|
51
53
|
base: {
|
|
52
54
|
factory: getAddress("0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd"),
|
|
53
|
-
auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2")
|
|
55
|
+
auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2"),
|
|
56
|
+
rareBridge: getAddress("0x3b41e21094611d152a08d3691a70837f1a077dae")
|
|
54
57
|
},
|
|
55
58
|
"base-sepolia": {
|
|
56
59
|
factory: getAddress("0x2b181ae0f1aea6fed75591b04991b1a3f9868d51"),
|
|
57
|
-
auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2")
|
|
60
|
+
auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2"),
|
|
61
|
+
rareBridge: getAddress("0xca491bb62A7730E97F500510132C47633DDD0229")
|
|
58
62
|
}
|
|
59
63
|
};
|
|
64
|
+
var ccipChainSelectors = {
|
|
65
|
+
mainnet: 5009297550715157269n,
|
|
66
|
+
sepolia: 16015286601757825753n,
|
|
67
|
+
base: 15971525489660198786n,
|
|
68
|
+
"base-sepolia": 10344971235874465080n
|
|
69
|
+
};
|
|
60
70
|
var canonicalV4Pools = {
|
|
61
71
|
sepolia: {
|
|
62
72
|
rareEthPool: {
|
|
@@ -206,6 +216,16 @@ function getCanonicalV4Pools(chain) {
|
|
|
206
216
|
}
|
|
207
217
|
return pools;
|
|
208
218
|
}
|
|
219
|
+
function getRareBridgeAddress(chain) {
|
|
220
|
+
const address = getContractAddresses(chain).rareBridge;
|
|
221
|
+
if (!address) {
|
|
222
|
+
throw new Error(`RareBridge is not configured on "${chain}". Supported RareBridge chains: mainnet, sepolia, base, base-sepolia.`);
|
|
223
|
+
}
|
|
224
|
+
return address;
|
|
225
|
+
}
|
|
226
|
+
function getCcipChainSelector(chain) {
|
|
227
|
+
return ccipChainSelectors[chain];
|
|
228
|
+
}
|
|
209
229
|
function isSupportedChain(value) {
|
|
210
230
|
return supportedChains.some((chain) => chain === value);
|
|
211
231
|
}
|
|
@@ -248,8 +268,12 @@ var RareApiError = class extends Error {
|
|
|
248
268
|
|
|
249
269
|
// src/data-access/base-url.ts
|
|
250
270
|
var DEFAULT_RARE_API_BASE_URL = "https://api.superrare.com";
|
|
271
|
+
function normalizeRareApiBaseUrlCandidate(baseUrl) {
|
|
272
|
+
const trimmedBaseUrl = baseUrl?.trim();
|
|
273
|
+
return trimmedBaseUrl === "" ? void 0 : trimmedBaseUrl;
|
|
274
|
+
}
|
|
251
275
|
function resolveRareApiBaseUrl(baseUrl) {
|
|
252
|
-
return process.env.RARE_API_BASE_URL ?? baseUrl ?? DEFAULT_RARE_API_BASE_URL;
|
|
276
|
+
return normalizeRareApiBaseUrlCandidate(process.env.RARE_API_BASE_URL) ?? normalizeRareApiBaseUrlCandidate(baseUrl) ?? DEFAULT_RARE_API_BASE_URL;
|
|
253
277
|
}
|
|
254
278
|
|
|
255
279
|
// src/data-access/client.ts
|
|
@@ -3481,6 +3505,50 @@ var auctionAbi = [
|
|
|
3481
3505
|
];
|
|
3482
3506
|
|
|
3483
3507
|
// src/sdk/approvals-shell.ts
|
|
3508
|
+
var ApprovalSideEffectError = class extends Error {
|
|
3509
|
+
operation;
|
|
3510
|
+
approvals;
|
|
3511
|
+
constructor(params) {
|
|
3512
|
+
super(
|
|
3513
|
+
`${approvalSummary(params.approvals)} before ${params.operation}, but ${params.operation} did not complete. The approval remains valid; retry the operation or revoke approval if it should not remain active.`,
|
|
3514
|
+
{ cause: params.cause }
|
|
3515
|
+
);
|
|
3516
|
+
this.name = "ApprovalSideEffectError";
|
|
3517
|
+
this.operation = params.operation;
|
|
3518
|
+
this.approvals = params.approvals;
|
|
3519
|
+
}
|
|
3520
|
+
};
|
|
3521
|
+
async function runWithApprovalSideEffectAlert(params) {
|
|
3522
|
+
try {
|
|
3523
|
+
return await params.run();
|
|
3524
|
+
} catch (error) {
|
|
3525
|
+
const approvals = params.approvals.filter(hasApprovalTxHash);
|
|
3526
|
+
if (approvals.length === 0) {
|
|
3527
|
+
throw error;
|
|
3528
|
+
}
|
|
3529
|
+
throw new ApprovalSideEffectError({
|
|
3530
|
+
operation: params.operation,
|
|
3531
|
+
approvals,
|
|
3532
|
+
cause: error
|
|
3533
|
+
});
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
function hasApprovalTxHash(approval) {
|
|
3537
|
+
return approval.approvalTxHash !== void 0;
|
|
3538
|
+
}
|
|
3539
|
+
function approvalSummary(approvals) {
|
|
3540
|
+
const [approval] = approvals;
|
|
3541
|
+
return approvals.length === 1 && approval !== void 0 ? `Approval transaction ${approval.approvalTxHash} was mined (${approvalDetails(approval)})` : `Approval transactions were mined: ${approvals.map((sideEffect) => `${sideEffect.approvalTxHash} (${approvalDetails(sideEffect)})`).join(", ")}`;
|
|
3542
|
+
}
|
|
3543
|
+
function approvalDetails(approval) {
|
|
3544
|
+
if (approval.type === "erc20" || approval.type === "erc20-reset") {
|
|
3545
|
+
return `${approval.type}; token ${approval.target}; spender ${approval.spender ?? "unknown"}`;
|
|
3546
|
+
}
|
|
3547
|
+
if (approval.type === "minter") {
|
|
3548
|
+
return `minter; collection ${approval.target}; minter ${approval.minter ?? "unknown"}`;
|
|
3549
|
+
}
|
|
3550
|
+
return `nft; contract ${approval.target}; operator ${approval.operator ?? "unknown"}`;
|
|
3551
|
+
}
|
|
3484
3552
|
var approvalAbi = [
|
|
3485
3553
|
{
|
|
3486
3554
|
inputs: [{ name: "owner", type: "address" }, { name: "operator", type: "address" }],
|
|
@@ -3633,7 +3701,7 @@ async function toTokenAmount(publicClient, token, value, field) {
|
|
|
3633
3701
|
}
|
|
3634
3702
|
async function ensureTokenAllowance(publicClient, walletClient, account, owner, token, spender, amount) {
|
|
3635
3703
|
if (isAddressEqual4(token, ETH_ADDRESS) || amount === 0n) {
|
|
3636
|
-
return;
|
|
3704
|
+
return void 0;
|
|
3637
3705
|
}
|
|
3638
3706
|
const allowance = await publicClient.readContract({
|
|
3639
3707
|
address: token,
|
|
@@ -3642,7 +3710,7 @@ async function ensureTokenAllowance(publicClient, walletClient, account, owner,
|
|
|
3642
3710
|
args: [owner, spender]
|
|
3643
3711
|
});
|
|
3644
3712
|
if (allowance >= amount) {
|
|
3645
|
-
return;
|
|
3713
|
+
return void 0;
|
|
3646
3714
|
}
|
|
3647
3715
|
const approveTx = await walletClient.writeContract({
|
|
3648
3716
|
address: token,
|
|
@@ -3652,7 +3720,14 @@ async function ensureTokenAllowance(publicClient, walletClient, account, owner,
|
|
|
3652
3720
|
account,
|
|
3653
3721
|
chain: void 0
|
|
3654
3722
|
});
|
|
3655
|
-
await publicClient
|
|
3723
|
+
await confirmErc20Approval(publicClient, {
|
|
3724
|
+
approvalTxHash: approveTx,
|
|
3725
|
+
currency: token,
|
|
3726
|
+
accountAddress: owner,
|
|
3727
|
+
spenderAddress: spender,
|
|
3728
|
+
requiredAmount: amount
|
|
3729
|
+
});
|
|
3730
|
+
return approveTx;
|
|
3656
3731
|
}
|
|
3657
3732
|
var PaymentApprovalRequiredError = class extends Error {
|
|
3658
3733
|
requiredAmount;
|
|
@@ -3725,7 +3800,13 @@ async function preparePaymentAmountForSpender(opts) {
|
|
|
3725
3800
|
account,
|
|
3726
3801
|
chain: void 0
|
|
3727
3802
|
});
|
|
3728
|
-
await publicClient
|
|
3803
|
+
await confirmErc20Approval(publicClient, {
|
|
3804
|
+
approvalTxHash,
|
|
3805
|
+
currency,
|
|
3806
|
+
accountAddress,
|
|
3807
|
+
spenderAddress,
|
|
3808
|
+
requiredAmount
|
|
3809
|
+
});
|
|
3729
3810
|
return {
|
|
3730
3811
|
value: 0n,
|
|
3731
3812
|
requiredAmount,
|
|
@@ -3763,6 +3844,23 @@ async function readAllowance(publicClient, currency, accountAddress, spenderAddr
|
|
|
3763
3844
|
args: [accountAddress, spenderAddress]
|
|
3764
3845
|
});
|
|
3765
3846
|
}
|
|
3847
|
+
async function confirmErc20Approval(publicClient, params) {
|
|
3848
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: params.approvalTxHash });
|
|
3849
|
+
if (receipt.status !== "success") {
|
|
3850
|
+
throw new Error(`ERC20 approval transaction ${params.approvalTxHash} did not succeed.`);
|
|
3851
|
+
}
|
|
3852
|
+
const allowance = await readAllowance(
|
|
3853
|
+
publicClient,
|
|
3854
|
+
params.currency,
|
|
3855
|
+
params.accountAddress,
|
|
3856
|
+
params.spenderAddress
|
|
3857
|
+
);
|
|
3858
|
+
if (allowance < params.requiredAmount) {
|
|
3859
|
+
throw new Error(
|
|
3860
|
+
`ERC20 approval transaction ${params.approvalTxHash} was mined but allowance for spender ${params.spenderAddress} is ${allowance.toString()} raw units, below the required ${params.requiredAmount.toString()} raw units.`
|
|
3861
|
+
);
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3766
3864
|
|
|
3767
3865
|
// src/sdk/validation-core.ts
|
|
3768
3866
|
import { isHex } from "viem";
|
|
@@ -4207,6 +4305,11 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
4207
4305
|
accountAddress,
|
|
4208
4306
|
currentUnixTimestamp()
|
|
4209
4307
|
);
|
|
4308
|
+
const auctionType = await publicClient.readContract({
|
|
4309
|
+
address: addresses.auction,
|
|
4310
|
+
abi: auctionAbi,
|
|
4311
|
+
functionName: plan.auctionType === "scheduled" ? "SCHEDULED_AUCTION" : "COLDIE_AUCTION"
|
|
4312
|
+
});
|
|
4210
4313
|
const approvalTxHash = await approveNftContractIfNeeded({
|
|
4211
4314
|
publicClient,
|
|
4212
4315
|
walletClient,
|
|
@@ -4216,30 +4319,37 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
4216
4319
|
operator: addresses.auction,
|
|
4217
4320
|
autoApprove: params.autoApprove
|
|
4218
4321
|
});
|
|
4219
|
-
const
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4322
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
4323
|
+
operation: "auction create",
|
|
4324
|
+
approvals: [{
|
|
4325
|
+
type: "nft",
|
|
4326
|
+
approvalTxHash,
|
|
4327
|
+
target: plan.nftAddress,
|
|
4328
|
+
operator: addresses.auction
|
|
4329
|
+
}],
|
|
4330
|
+
run: async () => {
|
|
4331
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4332
|
+
address: addresses.auction,
|
|
4333
|
+
abi: auctionAbi,
|
|
4334
|
+
functionName: "configureAuction",
|
|
4335
|
+
args: [
|
|
4336
|
+
auctionType,
|
|
4337
|
+
plan.nftAddress,
|
|
4338
|
+
plan.tokenId,
|
|
4339
|
+
plan.startingPrice,
|
|
4340
|
+
plan.currency,
|
|
4341
|
+
plan.duration,
|
|
4342
|
+
plan.startTime,
|
|
4343
|
+
plan.splitAddresses,
|
|
4344
|
+
plan.splitRatios
|
|
4345
|
+
],
|
|
4346
|
+
account,
|
|
4347
|
+
chain: void 0
|
|
4348
|
+
});
|
|
4349
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4350
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4351
|
+
}
|
|
4241
4352
|
});
|
|
4242
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
4243
4353
|
return {
|
|
4244
4354
|
txHash,
|
|
4245
4355
|
receipt,
|
|
@@ -4265,22 +4375,34 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
4265
4375
|
amount: plan.amount,
|
|
4266
4376
|
autoApprove: params.autoApprove
|
|
4267
4377
|
});
|
|
4268
|
-
const txHash = await
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4378
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
4379
|
+
operation: "auction bid",
|
|
4380
|
+
approvals: [{
|
|
4381
|
+
type: "erc20",
|
|
4382
|
+
approvalTxHash: payment.approvalTxHash,
|
|
4383
|
+
target: plan.currency,
|
|
4384
|
+
spender: addresses.auction
|
|
4385
|
+
}],
|
|
4386
|
+
run: async () => {
|
|
4387
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4388
|
+
address: addresses.auction,
|
|
4389
|
+
abi: auctionAbi,
|
|
4390
|
+
functionName: "bid",
|
|
4391
|
+
args: [params.contract, plan.tokenId, plan.currency, plan.amount],
|
|
4392
|
+
account,
|
|
4393
|
+
chain: void 0,
|
|
4394
|
+
value: payment.value
|
|
4395
|
+
});
|
|
4396
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4397
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4398
|
+
}
|
|
4276
4399
|
});
|
|
4277
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
4278
4400
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
4279
4401
|
},
|
|
4280
4402
|
async settle(params) {
|
|
4281
4403
|
const { walletClient, account } = requireWallet(config);
|
|
4282
4404
|
const plan = planAuctionTokenAction(params);
|
|
4283
|
-
const
|
|
4405
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4284
4406
|
address: addresses.auction,
|
|
4285
4407
|
abi: auctionAbi,
|
|
4286
4408
|
functionName: "settleAuction",
|
|
@@ -4288,13 +4410,13 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
4288
4410
|
account,
|
|
4289
4411
|
chain: void 0
|
|
4290
4412
|
});
|
|
4291
|
-
const
|
|
4292
|
-
return { txHash, receipt };
|
|
4413
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4414
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4293
4415
|
},
|
|
4294
4416
|
async cancel(params) {
|
|
4295
4417
|
const { walletClient, account } = requireWallet(config);
|
|
4296
4418
|
const plan = planAuctionTokenAction(params);
|
|
4297
|
-
const
|
|
4419
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4298
4420
|
address: addresses.auction,
|
|
4299
4421
|
abi: auctionAbi,
|
|
4300
4422
|
functionName: "cancelAuction",
|
|
@@ -4302,8 +4424,8 @@ function createAuctionNamespace(publicClient, config, chain, addresses) {
|
|
|
4302
4424
|
account,
|
|
4303
4425
|
chain: void 0
|
|
4304
4426
|
});
|
|
4305
|
-
const
|
|
4306
|
-
return { txHash, receipt };
|
|
4427
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4428
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4307
4429
|
},
|
|
4308
4430
|
async status(params) {
|
|
4309
4431
|
const plan = planAuctionTokenAction(params);
|
|
@@ -4380,23 +4502,35 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
|
|
|
4380
4502
|
amount: plan.amount,
|
|
4381
4503
|
autoApprove: params.autoApprove
|
|
4382
4504
|
});
|
|
4383
|
-
const txHash = await
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4505
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
4506
|
+
operation: "offer create",
|
|
4507
|
+
approvals: [{
|
|
4508
|
+
type: "erc20",
|
|
4509
|
+
approvalTxHash: payment.approvalTxHash,
|
|
4510
|
+
target: plan.currency,
|
|
4511
|
+
spender: addresses.auction
|
|
4512
|
+
}],
|
|
4513
|
+
run: async () => {
|
|
4514
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4515
|
+
address: addresses.auction,
|
|
4516
|
+
abi: auctionAbi,
|
|
4517
|
+
functionName: "offer",
|
|
4518
|
+
args: [params.contract, plan.tokenId, plan.currency, plan.amount, false],
|
|
4519
|
+
account,
|
|
4520
|
+
chain: void 0,
|
|
4521
|
+
value: payment.value
|
|
4522
|
+
});
|
|
4523
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4524
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4525
|
+
}
|
|
4391
4526
|
});
|
|
4392
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
4393
4527
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
4394
4528
|
},
|
|
4395
4529
|
async cancel(params) {
|
|
4396
4530
|
const { walletClient, account } = requireWallet(config);
|
|
4397
4531
|
const currency = params.currency === void 0 ? ETH_ADDRESS : resolveCurrencyForSdk(params.currency, chain).address;
|
|
4398
4532
|
const plan = planOfferCancel({ ...params, currency });
|
|
4399
|
-
const
|
|
4533
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4400
4534
|
address: addresses.auction,
|
|
4401
4535
|
abi: auctionAbi,
|
|
4402
4536
|
functionName: "cancelOffer",
|
|
@@ -4404,8 +4538,8 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
|
|
|
4404
4538
|
account,
|
|
4405
4539
|
chain: void 0
|
|
4406
4540
|
});
|
|
4407
|
-
const
|
|
4408
|
-
return { txHash, receipt };
|
|
4541
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4542
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4409
4543
|
},
|
|
4410
4544
|
async accept(params) {
|
|
4411
4545
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
@@ -4422,22 +4556,34 @@ function createOfferNamespace(publicClient, config, chain, addresses) {
|
|
|
4422
4556
|
operator: addresses.auction,
|
|
4423
4557
|
autoApprove: params.autoApprove
|
|
4424
4558
|
});
|
|
4425
|
-
const txHash = await
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
params.contract,
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4559
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
4560
|
+
operation: "offer accept",
|
|
4561
|
+
approvals: [{
|
|
4562
|
+
type: "nft",
|
|
4563
|
+
approvalTxHash,
|
|
4564
|
+
target: params.contract,
|
|
4565
|
+
operator: addresses.auction
|
|
4566
|
+
}],
|
|
4567
|
+
run: async () => {
|
|
4568
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4569
|
+
address: addresses.auction,
|
|
4570
|
+
abi: auctionAbi,
|
|
4571
|
+
functionName: "acceptOffer",
|
|
4572
|
+
args: [
|
|
4573
|
+
params.contract,
|
|
4574
|
+
plan.tokenId,
|
|
4575
|
+
plan.currency,
|
|
4576
|
+
plan.amount,
|
|
4577
|
+
plan.splitAddresses,
|
|
4578
|
+
plan.splitRatios
|
|
4579
|
+
],
|
|
4580
|
+
account,
|
|
4581
|
+
chain: void 0
|
|
4582
|
+
});
|
|
4583
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4584
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4585
|
+
}
|
|
4439
4586
|
});
|
|
4440
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
4441
4587
|
return { txHash, receipt, approvalTxHash };
|
|
4442
4588
|
},
|
|
4443
4589
|
async status(params) {
|
|
@@ -4502,29 +4648,41 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
4502
4648
|
operator: addresses.auction,
|
|
4503
4649
|
autoApprove: params.autoApprove
|
|
4504
4650
|
});
|
|
4505
|
-
const txHash = await
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
plan.nftAddress,
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4651
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
4652
|
+
operation: "listing create",
|
|
4653
|
+
approvals: [{
|
|
4654
|
+
type: "nft",
|
|
4655
|
+
approvalTxHash,
|
|
4656
|
+
target: plan.nftAddress,
|
|
4657
|
+
operator: addresses.auction
|
|
4658
|
+
}],
|
|
4659
|
+
run: async () => {
|
|
4660
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4661
|
+
address: addresses.auction,
|
|
4662
|
+
abi: auctionAbi,
|
|
4663
|
+
functionName: "setSalePrice",
|
|
4664
|
+
args: [
|
|
4665
|
+
plan.nftAddress,
|
|
4666
|
+
plan.tokenId,
|
|
4667
|
+
plan.currency,
|
|
4668
|
+
plan.price,
|
|
4669
|
+
plan.target,
|
|
4670
|
+
plan.splitAddresses,
|
|
4671
|
+
plan.splitRatios
|
|
4672
|
+
],
|
|
4673
|
+
account,
|
|
4674
|
+
chain: void 0
|
|
4675
|
+
});
|
|
4676
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4677
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4678
|
+
}
|
|
4520
4679
|
});
|
|
4521
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
4522
4680
|
return { txHash, receipt, approvalTxHash };
|
|
4523
4681
|
},
|
|
4524
4682
|
async cancel(params) {
|
|
4525
4683
|
const { walletClient, account } = requireWallet(config);
|
|
4526
4684
|
const plan = planListingCancel(params);
|
|
4527
|
-
const
|
|
4685
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4528
4686
|
address: addresses.auction,
|
|
4529
4687
|
abi: auctionAbi,
|
|
4530
4688
|
functionName: "removeSalePrice",
|
|
@@ -4532,8 +4690,8 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
4532
4690
|
account,
|
|
4533
4691
|
chain: void 0
|
|
4534
4692
|
});
|
|
4535
|
-
const
|
|
4536
|
-
return { txHash, receipt };
|
|
4693
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4694
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4537
4695
|
},
|
|
4538
4696
|
async buy(params) {
|
|
4539
4697
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
@@ -4552,16 +4710,28 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
4552
4710
|
amount: plan.amount,
|
|
4553
4711
|
autoApprove: params.autoApprove
|
|
4554
4712
|
});
|
|
4555
|
-
const txHash = await
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4713
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
4714
|
+
operation: "listing buy",
|
|
4715
|
+
approvals: [{
|
|
4716
|
+
type: "erc20",
|
|
4717
|
+
approvalTxHash: payment.approvalTxHash,
|
|
4718
|
+
target: plan.currency,
|
|
4719
|
+
spender: addresses.auction
|
|
4720
|
+
}],
|
|
4721
|
+
run: async () => {
|
|
4722
|
+
const targetTxHash = await walletClient.writeContract({
|
|
4723
|
+
address: addresses.auction,
|
|
4724
|
+
abi: auctionAbi,
|
|
4725
|
+
functionName: "buy",
|
|
4726
|
+
args: [params.contract, plan.tokenId, plan.currency, plan.amount],
|
|
4727
|
+
account,
|
|
4728
|
+
chain: void 0,
|
|
4729
|
+
value: payment.value
|
|
4730
|
+
});
|
|
4731
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
4732
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
4733
|
+
}
|
|
4563
4734
|
});
|
|
4564
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
4565
4735
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
4566
4736
|
},
|
|
4567
4737
|
async status(params) {
|
|
@@ -5368,7 +5538,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5368
5538
|
);
|
|
5369
5539
|
}
|
|
5370
5540
|
}
|
|
5371
|
-
const
|
|
5541
|
+
const nftApprovals = await approveNftContracts({
|
|
5372
5542
|
publicClient,
|
|
5373
5543
|
walletClient,
|
|
5374
5544
|
account,
|
|
@@ -5377,26 +5547,38 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5377
5547
|
nftAddresses: uniqueContracts,
|
|
5378
5548
|
autoApprove: params.autoApprove
|
|
5379
5549
|
});
|
|
5380
|
-
const txHash = await
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5550
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5551
|
+
operation: "batch listing create",
|
|
5552
|
+
approvals: nftApprovals.map((approval) => ({
|
|
5553
|
+
type: "nft",
|
|
5554
|
+
approvalTxHash: approval.txHash,
|
|
5555
|
+
target: approval.nftAddress,
|
|
5556
|
+
operator: addresses.erc721ApprovalManager
|
|
5557
|
+
})),
|
|
5558
|
+
run: async () => {
|
|
5559
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5560
|
+
address: addresses.batchListing,
|
|
5561
|
+
abi: batchListingAbi,
|
|
5562
|
+
functionName: "registerSalePriceMerkleRoot",
|
|
5563
|
+
args: [
|
|
5564
|
+
artifact.root,
|
|
5565
|
+
artifact.currency,
|
|
5566
|
+
BigInt(artifact.amount),
|
|
5567
|
+
splitConfig.splitAddresses,
|
|
5568
|
+
splitConfig.splitRatios
|
|
5569
|
+
],
|
|
5570
|
+
account,
|
|
5571
|
+
chain: void 0
|
|
5572
|
+
});
|
|
5573
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5574
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5575
|
+
}
|
|
5393
5576
|
});
|
|
5394
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5395
5577
|
return {
|
|
5396
5578
|
txHash,
|
|
5397
5579
|
receipt,
|
|
5398
5580
|
root: artifact.root,
|
|
5399
|
-
approvalTxHashes:
|
|
5581
|
+
approvalTxHashes: nftApprovals.length > 0 ? nftApprovals.map((approval) => approval.txHash) : void 0
|
|
5400
5582
|
};
|
|
5401
5583
|
},
|
|
5402
5584
|
async cancel(params) {
|
|
@@ -5409,7 +5591,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5409
5591
|
creator: accountAddress,
|
|
5410
5592
|
params
|
|
5411
5593
|
});
|
|
5412
|
-
const
|
|
5594
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5413
5595
|
address: addresses.batchListing,
|
|
5414
5596
|
abi: batchListingAbi,
|
|
5415
5597
|
functionName: "cancelSalePriceMerkleRoot",
|
|
@@ -5417,8 +5599,8 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5417
5599
|
account,
|
|
5418
5600
|
chain: void 0
|
|
5419
5601
|
});
|
|
5420
|
-
const
|
|
5421
|
-
return { txHash, receipt, root };
|
|
5602
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5603
|
+
return { txHash: targetTxHash, receipt: targetReceipt, root };
|
|
5422
5604
|
},
|
|
5423
5605
|
async buy(params) {
|
|
5424
5606
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
@@ -5449,25 +5631,37 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5449
5631
|
amount,
|
|
5450
5632
|
autoApprove: params.autoApprove
|
|
5451
5633
|
});
|
|
5452
|
-
const txHash = await
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5634
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
5635
|
+
operation: "batch listing buy",
|
|
5636
|
+
approvals: [{
|
|
5637
|
+
type: "erc20",
|
|
5638
|
+
approvalTxHash: payment.approvalTxHash,
|
|
5639
|
+
target: currency,
|
|
5640
|
+
spender: addresses.erc20ApprovalManager
|
|
5641
|
+
}],
|
|
5642
|
+
run: async () => {
|
|
5643
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5644
|
+
address: addresses.batchListing,
|
|
5645
|
+
abi: batchListingAbi,
|
|
5646
|
+
functionName: "buyWithMerkleProof",
|
|
5647
|
+
args: [
|
|
5648
|
+
proofArtifact.contract,
|
|
5649
|
+
tokenIdBig,
|
|
5650
|
+
currency,
|
|
5651
|
+
amount,
|
|
5652
|
+
params.creator,
|
|
5653
|
+
proofArtifact.root,
|
|
5654
|
+
proofArtifact.proof,
|
|
5655
|
+
allowListProof
|
|
5656
|
+
],
|
|
5657
|
+
account,
|
|
5658
|
+
chain: void 0,
|
|
5659
|
+
value: payment.value
|
|
5660
|
+
});
|
|
5661
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5662
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
5663
|
+
}
|
|
5469
5664
|
});
|
|
5470
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
5471
5665
|
return { txHash, receipt, approvalTxHash: payment.approvalTxHash };
|
|
5472
5666
|
},
|
|
5473
5667
|
async setAllowlist(params) {
|
|
@@ -5485,7 +5679,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5485
5679
|
requireInput(params.endTime ?? params.artifact?.allowList?.endTimestamp, "endTime"),
|
|
5486
5680
|
"endTime"
|
|
5487
5681
|
);
|
|
5488
|
-
const
|
|
5682
|
+
const targetTxHash = await walletClient.writeContract({
|
|
5489
5683
|
address: addresses.batchListing,
|
|
5490
5684
|
abi: batchListingAbi,
|
|
5491
5685
|
functionName: "setAllowListConfig",
|
|
@@ -5493,8 +5687,8 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5493
5687
|
account,
|
|
5494
5688
|
chain: void 0
|
|
5495
5689
|
});
|
|
5496
|
-
const
|
|
5497
|
-
return { txHash, receipt, root, allowListRoot, endTime };
|
|
5690
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
5691
|
+
return { txHash: targetTxHash, receipt: targetReceipt, root, allowListRoot, endTime };
|
|
5498
5692
|
},
|
|
5499
5693
|
async status(params) {
|
|
5500
5694
|
const resolvedParams = await resolveBatchListingStatusParams({
|
|
@@ -5723,7 +5917,7 @@ function isHash(value) {
|
|
|
5723
5917
|
}
|
|
5724
5918
|
async function approveNftContracts(opts) {
|
|
5725
5919
|
return opts.nftAddresses.reduce(async (previous, nftAddress) => {
|
|
5726
|
-
const
|
|
5920
|
+
const approvals = await previous;
|
|
5727
5921
|
const txHash = await approveNftContractIfNeeded({
|
|
5728
5922
|
publicClient: opts.publicClient,
|
|
5729
5923
|
walletClient: opts.walletClient,
|
|
@@ -5733,7 +5927,7 @@ async function approveNftContracts(opts) {
|
|
|
5733
5927
|
operator: opts.operator,
|
|
5734
5928
|
autoApprove: opts.autoApprove
|
|
5735
5929
|
});
|
|
5736
|
-
return isHash(txHash) ? [...
|
|
5930
|
+
return isHash(txHash) ? [...approvals, { nftAddress, txHash }] : approvals;
|
|
5737
5931
|
}, Promise.resolve([]));
|
|
5738
5932
|
}
|
|
5739
5933
|
async function prepareBatchListingPayment(opts) {
|
|
@@ -6104,16 +6298,18 @@ function planBatchAuctionStatus(params) {
|
|
|
6104
6298
|
}
|
|
6105
6299
|
function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
6106
6300
|
const hasAuction = details.startingTime > 0n && !isAddressEqual10(details.seller, zeroAddress3);
|
|
6107
|
-
const
|
|
6108
|
-
const
|
|
6301
|
+
const hasCurrentRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n && rootContext.rootNonce === rootContext.config.nonce;
|
|
6302
|
+
const currentRootConfig = hasCurrentRootConfig ? rootContext.config : void 0;
|
|
6303
|
+
const hasRootConfig = currentRootConfig !== void 0;
|
|
6304
|
+
const duration = hasAuction ? details.duration : currentRootConfig?.duration ?? 0n;
|
|
6109
6305
|
const startingTime = hasAuction ? details.startingTime : 0n;
|
|
6110
6306
|
const endTime = hasAuction ? startingTime + duration : null;
|
|
6111
6307
|
const ended = endTime !== null && nowSeconds >= endTime;
|
|
6112
6308
|
const currentBidder = currentBid.amount > 0n && !isAddressEqual10(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
|
|
6113
6309
|
const seller = hasAuction ? details.seller : rootContext?.creator ?? zeroAddress3;
|
|
6114
|
-
const currency = hasAuction ? details.currency :
|
|
6115
|
-
const reserveAmount = hasAuction ? details.reserveAmount :
|
|
6116
|
-
const tokenNonceConsumed = rootContext === void 0 ? null : rootContext.tokenNonce >= rootContext.config.nonce;
|
|
6310
|
+
const currency = hasAuction ? details.currency : currentRootConfig?.currency ?? ETH_ADDRESS;
|
|
6311
|
+
const reserveAmount = hasAuction ? details.reserveAmount : currentRootConfig?.reserveAmount ?? 0n;
|
|
6312
|
+
const tokenNonceConsumed = rootContext === void 0 ? null : !hasCurrentRootConfig || rootContext.tokenNonce >= rootContext.config.nonce;
|
|
6117
6313
|
return {
|
|
6118
6314
|
seller,
|
|
6119
6315
|
root: rootContext?.root ?? null,
|
|
@@ -6123,8 +6319,8 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
6123
6319
|
creationBlock: details.creationBlock,
|
|
6124
6320
|
startingTime,
|
|
6125
6321
|
endTime,
|
|
6126
|
-
splitAddresses: resolveStatusSplitAddresses(hasAuction, details,
|
|
6127
|
-
splitRatios: resolveStatusSplitRatios(hasAuction, details,
|
|
6322
|
+
splitAddresses: resolveStatusSplitAddresses(hasAuction, details, currentRootConfig),
|
|
6323
|
+
splitRatios: resolveStatusSplitRatios(hasAuction, details, currentRootConfig),
|
|
6128
6324
|
hasRootConfig,
|
|
6129
6325
|
rootNonce: rootContext?.rootNonce ?? null,
|
|
6130
6326
|
tokenNonce: rootContext?.tokenNonce ?? null,
|
|
@@ -6260,23 +6456,23 @@ function uniqueAddresses2(addresses) {
|
|
|
6260
6456
|
function addMinimumBidIncrease(amount) {
|
|
6261
6457
|
return amount + amount * marketplaceFeePercentage / 100n;
|
|
6262
6458
|
}
|
|
6263
|
-
function resolveStatusSplitAddresses(hasAuction, details,
|
|
6459
|
+
function resolveStatusSplitAddresses(hasAuction, details, rootConfig) {
|
|
6264
6460
|
if (hasAuction) {
|
|
6265
6461
|
return [...details.splitAddresses];
|
|
6266
6462
|
}
|
|
6267
|
-
if (
|
|
6463
|
+
if (rootConfig === void 0) {
|
|
6268
6464
|
return [];
|
|
6269
6465
|
}
|
|
6270
|
-
return [...
|
|
6466
|
+
return [...rootConfig.splitAddresses];
|
|
6271
6467
|
}
|
|
6272
|
-
function resolveStatusSplitRatios(hasAuction, details,
|
|
6468
|
+
function resolveStatusSplitRatios(hasAuction, details, rootConfig) {
|
|
6273
6469
|
if (hasAuction) {
|
|
6274
6470
|
return [...details.splitRatios];
|
|
6275
6471
|
}
|
|
6276
|
-
if (
|
|
6472
|
+
if (rootConfig === void 0) {
|
|
6277
6473
|
return [];
|
|
6278
6474
|
}
|
|
6279
|
-
return [...
|
|
6475
|
+
return [...rootConfig.splitRatios];
|
|
6280
6476
|
}
|
|
6281
6477
|
function resolveBatchAuctionState(params) {
|
|
6282
6478
|
if (params.hasAuction) {
|
|
@@ -6310,7 +6506,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6310
6506
|
currentUnixTimestamp2()
|
|
6311
6507
|
);
|
|
6312
6508
|
const erc721ApprovalManager = plan.approvalContracts.length === 0 ? void 0 : requireContractAddress(chain, "erc721ApprovalManager");
|
|
6313
|
-
const
|
|
6509
|
+
const nftApprovals = await approveNftContracts2({
|
|
6314
6510
|
publicClient,
|
|
6315
6511
|
account,
|
|
6316
6512
|
accountAddress,
|
|
@@ -6319,31 +6515,43 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6319
6515
|
nftAddresses: plan.approvalContracts,
|
|
6320
6516
|
autoApprove: params.autoApprove
|
|
6321
6517
|
});
|
|
6322
|
-
const txHash = await
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6518
|
+
const { txHash, receipt, registered } = await runWithApprovalSideEffectAlert({
|
|
6519
|
+
operation: "batch auction create",
|
|
6520
|
+
approvals: nftApprovals.map((approval) => ({
|
|
6521
|
+
type: "nft",
|
|
6522
|
+
approvalTxHash: approval.txHash,
|
|
6523
|
+
target: approval.nftAddress,
|
|
6524
|
+
operator: erc721ApprovalManager
|
|
6525
|
+
})),
|
|
6526
|
+
run: async () => {
|
|
6527
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6528
|
+
address: batchAuctionHouse,
|
|
6529
|
+
abi: batchAuctionHouseAbi,
|
|
6530
|
+
functionName: "registerAuctionMerkleRoot",
|
|
6531
|
+
args: [
|
|
6532
|
+
plan.root,
|
|
6533
|
+
plan.currency,
|
|
6534
|
+
plan.reserveAmount,
|
|
6535
|
+
plan.duration,
|
|
6536
|
+
plan.splitAddresses,
|
|
6537
|
+
plan.splitRatios
|
|
6538
|
+
],
|
|
6539
|
+
account,
|
|
6540
|
+
chain: void 0
|
|
6541
|
+
});
|
|
6542
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6543
|
+
const logs = parseEventLogs3({
|
|
6544
|
+
abi: batchAuctionHouseAbi,
|
|
6545
|
+
logs: targetReceipt.logs,
|
|
6546
|
+
eventName: "AuctionMerkleRootRegistered"
|
|
6547
|
+
});
|
|
6548
|
+
const [registeredLog] = logs;
|
|
6549
|
+
if (!registeredLog) {
|
|
6550
|
+
throw new Error("Batch auction create transaction succeeded but AuctionMerkleRootRegistered was not found in logs.");
|
|
6551
|
+
}
|
|
6552
|
+
return { txHash: targetTxHash, receipt: targetReceipt, registered: registeredLog };
|
|
6553
|
+
}
|
|
6342
6554
|
});
|
|
6343
|
-
const [registered] = logs;
|
|
6344
|
-
if (!registered) {
|
|
6345
|
-
throw new Error("Batch auction create transaction succeeded but AuctionMerkleRootRegistered was not found in logs.");
|
|
6346
|
-
}
|
|
6347
6555
|
return {
|
|
6348
6556
|
txHash,
|
|
6349
6557
|
receipt,
|
|
@@ -6354,7 +6562,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6354
6562
|
reserveAmount: registered.args.startingAmount,
|
|
6355
6563
|
duration: registered.args.duration,
|
|
6356
6564
|
nonce: registered.args.nonce,
|
|
6357
|
-
approvalTxHashes
|
|
6565
|
+
approvalTxHashes: nftApprovals.map((approval) => approval.txHash)
|
|
6358
6566
|
};
|
|
6359
6567
|
},
|
|
6360
6568
|
async cancel(params) {
|
|
@@ -6367,7 +6575,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6367
6575
|
params
|
|
6368
6576
|
);
|
|
6369
6577
|
const plan = planBatchAuctionRoot(resolvedParams);
|
|
6370
|
-
const
|
|
6578
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6371
6579
|
address: batchAuctionHouse,
|
|
6372
6580
|
abi: batchAuctionHouseAbi,
|
|
6373
6581
|
functionName: "cancelAuctionMerkleRoot",
|
|
@@ -6375,10 +6583,10 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6375
6583
|
account,
|
|
6376
6584
|
chain: void 0
|
|
6377
6585
|
});
|
|
6378
|
-
const
|
|
6586
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6379
6587
|
const logs = parseEventLogs3({
|
|
6380
6588
|
abi: batchAuctionHouseAbi,
|
|
6381
|
-
logs:
|
|
6589
|
+
logs: targetReceipt.logs,
|
|
6382
6590
|
eventName: "AuctionMerkleRootCancelled"
|
|
6383
6591
|
});
|
|
6384
6592
|
const [cancelled] = logs;
|
|
@@ -6386,8 +6594,8 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6386
6594
|
throw new Error("Batch auction cancel transaction succeeded but AuctionMerkleRootCancelled was not found in logs.");
|
|
6387
6595
|
}
|
|
6388
6596
|
return {
|
|
6389
|
-
txHash,
|
|
6390
|
-
receipt,
|
|
6597
|
+
txHash: targetTxHash,
|
|
6598
|
+
receipt: targetReceipt,
|
|
6391
6599
|
batchAuctionHouse,
|
|
6392
6600
|
creator: cancelled.args.creator,
|
|
6393
6601
|
root: cancelled.args.merkleRoot
|
|
@@ -6428,33 +6636,45 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6428
6636
|
requiredAmount: plan.requiredPayment,
|
|
6429
6637
|
autoApprove: params.autoApprove
|
|
6430
6638
|
});
|
|
6431
|
-
const txHash = await
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
plan.currency,
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6639
|
+
const { txHash, receipt, bid } = await runWithApprovalSideEffectAlert({
|
|
6640
|
+
operation: "batch auction bid",
|
|
6641
|
+
approvals: [{
|
|
6642
|
+
type: "erc20",
|
|
6643
|
+
approvalTxHash: payment.approvalTxHash,
|
|
6644
|
+
target: plan.currency,
|
|
6645
|
+
spender: erc20ApprovalManager
|
|
6646
|
+
}],
|
|
6647
|
+
run: async () => {
|
|
6648
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6649
|
+
address: batchAuctionHouse,
|
|
6650
|
+
abi: batchAuctionHouseAbi,
|
|
6651
|
+
functionName: "bidWithAuctionMerkleProof",
|
|
6652
|
+
args: [
|
|
6653
|
+
plan.currency,
|
|
6654
|
+
plan.contract,
|
|
6655
|
+
plan.tokenId,
|
|
6656
|
+
plan.creator,
|
|
6657
|
+
plan.root,
|
|
6658
|
+
plan.amount,
|
|
6659
|
+
plan.proof
|
|
6660
|
+
],
|
|
6661
|
+
account,
|
|
6662
|
+
chain: void 0,
|
|
6663
|
+
value: payment.value
|
|
6664
|
+
});
|
|
6665
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6666
|
+
const logs = parseEventLogs3({
|
|
6667
|
+
abi: batchAuctionHouseAbi,
|
|
6668
|
+
logs: targetReceipt.logs,
|
|
6669
|
+
eventName: "AuctionMerkleBid"
|
|
6670
|
+
});
|
|
6671
|
+
const [bidLog] = logs;
|
|
6672
|
+
if (!bidLog) {
|
|
6673
|
+
throw new Error("Batch auction bid transaction succeeded but AuctionMerkleBid was not found in logs.");
|
|
6674
|
+
}
|
|
6675
|
+
return { txHash: targetTxHash, receipt: targetReceipt, bid: bidLog };
|
|
6676
|
+
}
|
|
6453
6677
|
});
|
|
6454
|
-
const [bid] = logs;
|
|
6455
|
-
if (!bid) {
|
|
6456
|
-
throw new Error("Batch auction bid transaction succeeded but AuctionMerkleBid was not found in logs.");
|
|
6457
|
-
}
|
|
6458
6678
|
return {
|
|
6459
6679
|
txHash,
|
|
6460
6680
|
receipt,
|
|
@@ -6475,7 +6695,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6475
6695
|
const batchAuctionHouse = requireContractAddress(chain, "batchAuctionHouse");
|
|
6476
6696
|
const { walletClient, account } = requireWallet(config);
|
|
6477
6697
|
const plan = planBatchAuctionStatus(params);
|
|
6478
|
-
const
|
|
6698
|
+
const targetTxHash = await walletClient.writeContract({
|
|
6479
6699
|
address: batchAuctionHouse,
|
|
6480
6700
|
abi: batchAuctionHouseAbi,
|
|
6481
6701
|
functionName: "settleAuction",
|
|
@@ -6483,10 +6703,10 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6483
6703
|
account,
|
|
6484
6704
|
chain: void 0
|
|
6485
6705
|
});
|
|
6486
|
-
const
|
|
6706
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
6487
6707
|
const logs = parseEventLogs3({
|
|
6488
6708
|
abi: batchAuctionHouseAbi,
|
|
6489
|
-
logs:
|
|
6709
|
+
logs: targetReceipt.logs,
|
|
6490
6710
|
eventName: "AuctionSettled"
|
|
6491
6711
|
});
|
|
6492
6712
|
const [settled] = logs;
|
|
@@ -6494,8 +6714,8 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6494
6714
|
throw new Error("Batch auction settle transaction succeeded but AuctionSettled was not found in logs.");
|
|
6495
6715
|
}
|
|
6496
6716
|
return {
|
|
6497
|
-
txHash,
|
|
6498
|
-
receipt,
|
|
6717
|
+
txHash: targetTxHash,
|
|
6718
|
+
receipt: targetReceipt,
|
|
6499
6719
|
batchAuctionHouse,
|
|
6500
6720
|
seller: settled.args.seller,
|
|
6501
6721
|
bidder: settled.args.bidder,
|
|
@@ -6682,7 +6902,7 @@ async function approveNftContracts2(opts) {
|
|
|
6682
6902
|
}
|
|
6683
6903
|
const { walletClient, operator } = opts;
|
|
6684
6904
|
return opts.nftAddresses.reduce(async (previous, nftAddress) => {
|
|
6685
|
-
const
|
|
6905
|
+
const approvals = await previous;
|
|
6686
6906
|
const txHash = await approveNftContract({
|
|
6687
6907
|
publicClient: opts.publicClient,
|
|
6688
6908
|
walletClient,
|
|
@@ -6692,7 +6912,7 @@ async function approveNftContracts2(opts) {
|
|
|
6692
6912
|
nftAddress,
|
|
6693
6913
|
autoApprove: opts.autoApprove
|
|
6694
6914
|
});
|
|
6695
|
-
return txHash === void 0 ?
|
|
6915
|
+
return txHash === void 0 ? approvals : [...approvals, { nftAddress, txHash }];
|
|
6696
6916
|
}, Promise.resolve([]));
|
|
6697
6917
|
}
|
|
6698
6918
|
async function approveNftContract(opts) {
|
|
@@ -7032,25 +7252,37 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
7032
7252
|
amount: plan.amount,
|
|
7033
7253
|
autoApprove: params.autoApprove
|
|
7034
7254
|
});
|
|
7035
|
-
const txHash = await
|
|
7036
|
-
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7255
|
+
const { txHash, receipt, created } = await runWithApprovalSideEffectAlert({
|
|
7256
|
+
operation: "batch offer create",
|
|
7257
|
+
approvals: [{
|
|
7258
|
+
type: "erc20",
|
|
7259
|
+
approvalTxHash: payment.approvalTxHash,
|
|
7260
|
+
target: plan.currency,
|
|
7261
|
+
spender: batchOfferCreator
|
|
7262
|
+
}],
|
|
7263
|
+
run: async () => {
|
|
7264
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7265
|
+
address: batchOfferCreator,
|
|
7266
|
+
abi: batchOfferAbi,
|
|
7267
|
+
functionName: "createBatchOffer",
|
|
7268
|
+
args: [plan.root, plan.amount, plan.currency, plan.expiry],
|
|
7269
|
+
account,
|
|
7270
|
+
chain: void 0,
|
|
7271
|
+
value: payment.value
|
|
7272
|
+
});
|
|
7273
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7274
|
+
const logs = parseEventLogs4({
|
|
7275
|
+
abi: batchOfferAbi,
|
|
7276
|
+
logs: targetReceipt.logs,
|
|
7277
|
+
eventName: "BatchOfferCreated"
|
|
7278
|
+
});
|
|
7279
|
+
const [createdLog] = logs;
|
|
7280
|
+
if (!createdLog) {
|
|
7281
|
+
throw new Error("Batch offer create transaction succeeded but BatchOfferCreated was not found in logs.");
|
|
7282
|
+
}
|
|
7283
|
+
return { txHash: targetTxHash, receipt: targetReceipt, created: createdLog };
|
|
7284
|
+
}
|
|
7049
7285
|
});
|
|
7050
|
-
const [created] = logs;
|
|
7051
|
-
if (!created) {
|
|
7052
|
-
throw new Error("Batch offer create transaction succeeded but BatchOfferCreated was not found in logs.");
|
|
7053
|
-
}
|
|
7054
7286
|
return {
|
|
7055
7287
|
txHash,
|
|
7056
7288
|
receipt,
|
|
@@ -7076,7 +7308,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
7076
7308
|
params
|
|
7077
7309
|
});
|
|
7078
7310
|
const plan = planBatchOfferRoot(resolvedParams);
|
|
7079
|
-
const
|
|
7311
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7080
7312
|
address: batchOfferCreator,
|
|
7081
7313
|
abi: batchOfferAbi,
|
|
7082
7314
|
functionName: "revokeBatchOffer",
|
|
@@ -7084,10 +7316,10 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
7084
7316
|
account,
|
|
7085
7317
|
chain: void 0
|
|
7086
7318
|
});
|
|
7087
|
-
const
|
|
7319
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7088
7320
|
const logs = parseEventLogs4({
|
|
7089
7321
|
abi: batchOfferAbi,
|
|
7090
|
-
logs:
|
|
7322
|
+
logs: targetReceipt.logs,
|
|
7091
7323
|
eventName: "BatchOfferRevoked"
|
|
7092
7324
|
});
|
|
7093
7325
|
const [revoked] = logs;
|
|
@@ -7095,8 +7327,8 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
7095
7327
|
throw new Error("Batch offer revoke transaction succeeded but BatchOfferRevoked was not found in logs.");
|
|
7096
7328
|
}
|
|
7097
7329
|
return {
|
|
7098
|
-
txHash,
|
|
7099
|
-
receipt,
|
|
7330
|
+
txHash: targetTxHash,
|
|
7331
|
+
receipt: targetReceipt,
|
|
7100
7332
|
batchOfferCreator,
|
|
7101
7333
|
creator: revoked.args.creator,
|
|
7102
7334
|
root: revoked.args.rootHash,
|
|
@@ -7133,32 +7365,44 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
7133
7365
|
operator: batchOfferCreator,
|
|
7134
7366
|
autoApprove: plan.autoApprove
|
|
7135
7367
|
});
|
|
7136
|
-
const txHash = await
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
plan.
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7368
|
+
const { txHash, receipt, accepted } = await runWithApprovalSideEffectAlert({
|
|
7369
|
+
operation: "batch offer accept",
|
|
7370
|
+
approvals: [{
|
|
7371
|
+
type: "nft",
|
|
7372
|
+
approvalTxHash,
|
|
7373
|
+
target: plan.contract,
|
|
7374
|
+
operator: batchOfferCreator
|
|
7375
|
+
}],
|
|
7376
|
+
run: async () => {
|
|
7377
|
+
const targetTxHash = await walletClient.writeContract({
|
|
7378
|
+
address: batchOfferCreator,
|
|
7379
|
+
abi: batchOfferAbi,
|
|
7380
|
+
functionName: "acceptBatchOffer",
|
|
7381
|
+
args: [
|
|
7382
|
+
plan.creator,
|
|
7383
|
+
plan.proof,
|
|
7384
|
+
plan.root,
|
|
7385
|
+
plan.contract,
|
|
7386
|
+
plan.tokenId,
|
|
7387
|
+
plan.splitAddresses,
|
|
7388
|
+
plan.splitRatios
|
|
7389
|
+
],
|
|
7390
|
+
account,
|
|
7391
|
+
chain: void 0
|
|
7392
|
+
});
|
|
7393
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
7394
|
+
const logs = parseEventLogs4({
|
|
7395
|
+
abi: batchOfferAbi,
|
|
7396
|
+
logs: targetReceipt.logs,
|
|
7397
|
+
eventName: "BatchOfferAccepted"
|
|
7398
|
+
});
|
|
7399
|
+
const [acceptedLog] = logs;
|
|
7400
|
+
if (!acceptedLog) {
|
|
7401
|
+
throw new Error("Batch offer accept transaction succeeded but BatchOfferAccepted was not found in logs.");
|
|
7402
|
+
}
|
|
7403
|
+
return { txHash: targetTxHash, receipt: targetReceipt, accepted: acceptedLog };
|
|
7404
|
+
}
|
|
7157
7405
|
});
|
|
7158
|
-
const [accepted] = logs;
|
|
7159
|
-
if (!accepted) {
|
|
7160
|
-
throw new Error("Batch offer accept transaction succeeded but BatchOfferAccepted was not found in logs.");
|
|
7161
|
-
}
|
|
7162
7406
|
return {
|
|
7163
7407
|
txHash,
|
|
7164
7408
|
receipt,
|
|
@@ -7779,6 +8023,7 @@ var liquidFactoryAbi = [
|
|
|
7779
8023
|
var TICK_BASE = 1.0001;
|
|
7780
8024
|
var TICK_LOG_BASE = Math.log(TICK_BASE);
|
|
7781
8025
|
var TOKEN_BASE_UNITS = 1e18;
|
|
8026
|
+
var SHARE_SCALE_UNITS = 10n ** 18n;
|
|
7782
8027
|
var RESERVE_TAIL_SHARES_PERCENT = 2;
|
|
7783
8028
|
var RESERVE_TAIL_END_PRICE_MULTIPLE = 100;
|
|
7784
8029
|
var SHARES_SUM_TOLERANCE = 1e-6;
|
|
@@ -7837,12 +8082,66 @@ function toValidNumber(value) {
|
|
|
7837
8082
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
7838
8083
|
return value;
|
|
7839
8084
|
}
|
|
7840
|
-
function
|
|
7841
|
-
|
|
7842
|
-
|
|
8085
|
+
function toNormalizedShare(value) {
|
|
8086
|
+
if (typeof value === "number") {
|
|
8087
|
+
if (!Number.isFinite(value) || value <= 0 || value > 1) {
|
|
8088
|
+
return null;
|
|
8089
|
+
}
|
|
8090
|
+
return parseShareDecimalString(expandFiniteNumber(value));
|
|
8091
|
+
}
|
|
8092
|
+
if (typeof value !== "string") {
|
|
7843
8093
|
return null;
|
|
7844
8094
|
}
|
|
7845
|
-
return
|
|
8095
|
+
return parseShareDecimalString(value);
|
|
8096
|
+
}
|
|
8097
|
+
function expandFiniteNumber(value) {
|
|
8098
|
+
const rawValue = value.toString();
|
|
8099
|
+
const [coefficient = "", exponentValue] = rawValue.toLowerCase().split("e");
|
|
8100
|
+
if (exponentValue === void 0) {
|
|
8101
|
+
return rawValue;
|
|
8102
|
+
}
|
|
8103
|
+
const exponent = Number(exponentValue);
|
|
8104
|
+
const [integerPart = "", fractionalPart = ""] = coefficient.split(".");
|
|
8105
|
+
const digits = `${integerPart}${fractionalPart}`;
|
|
8106
|
+
const decimalIndex = integerPart.length + exponent;
|
|
8107
|
+
if (decimalIndex <= 0) {
|
|
8108
|
+
return `0.${"0".repeat(Math.abs(decimalIndex))}${digits}`;
|
|
8109
|
+
}
|
|
8110
|
+
if (decimalIndex >= digits.length) {
|
|
8111
|
+
return `${digits}${"0".repeat(decimalIndex - digits.length)}`;
|
|
8112
|
+
}
|
|
8113
|
+
return `${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
|
|
8114
|
+
}
|
|
8115
|
+
function parseShareDecimalString(value) {
|
|
8116
|
+
const normalized = value.trim();
|
|
8117
|
+
if (!/^(?:\d+\.?\d*|\.\d+)$/.test(normalized)) {
|
|
8118
|
+
return null;
|
|
8119
|
+
}
|
|
8120
|
+
const shareParts = normalized.startsWith(".") ? ["0", normalized.slice(1)] : normalized.split(".");
|
|
8121
|
+
const integerPart = shareParts[0] ?? "";
|
|
8122
|
+
const fractionalDigits = shareParts[1] ?? "";
|
|
8123
|
+
const excessFractionalDigits = fractionalDigits.slice(18);
|
|
8124
|
+
if (/[1-9]/.test(excessFractionalDigits)) {
|
|
8125
|
+
return null;
|
|
8126
|
+
}
|
|
8127
|
+
const integerUnits = BigInt(integerPart === "" ? "0" : integerPart);
|
|
8128
|
+
const fractionalUnits = BigInt(fractionalDigits.slice(0, 18).padEnd(18, "0"));
|
|
8129
|
+
const scaledUnits = integerUnits * SHARE_SCALE_UNITS + fractionalUnits;
|
|
8130
|
+
if (scaledUnits <= 0n || scaledUnits > SHARE_SCALE_UNITS) {
|
|
8131
|
+
return null;
|
|
8132
|
+
}
|
|
8133
|
+
return {
|
|
8134
|
+
decimal: formatScaledShareDecimal(scaledUnits),
|
|
8135
|
+
scaledUnits
|
|
8136
|
+
};
|
|
8137
|
+
}
|
|
8138
|
+
function formatScaledShareDecimal(scaledUnits) {
|
|
8139
|
+
const integerUnits = scaledUnits / SHARE_SCALE_UNITS;
|
|
8140
|
+
const fractionalUnits = scaledUnits % SHARE_SCALE_UNITS;
|
|
8141
|
+
if (fractionalUnits === 0n) {
|
|
8142
|
+
return integerUnits.toString();
|
|
8143
|
+
}
|
|
8144
|
+
return `${integerUnits}.${fractionalUnits.toString().padStart(18, "0").replace(/0+$/, "")}`;
|
|
7846
8145
|
}
|
|
7847
8146
|
function toApproxTokenAmount(value, label) {
|
|
7848
8147
|
const numeric = typeof value === "number" ? value : Number(value);
|
|
@@ -7991,8 +8290,8 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
7991
8290
|
if (invalidResult !== void 0) {
|
|
7992
8291
|
return invalidResult.result;
|
|
7993
8292
|
}
|
|
7994
|
-
const
|
|
7995
|
-
const totalPositions =
|
|
8293
|
+
const parsedEntries = normalizedResults.filter((result) => result.isValid).map((result) => result.entry);
|
|
8294
|
+
const totalPositions = parsedEntries.reduce((sum, entry) => sum + entry.segment.numPositions, 0);
|
|
7996
8295
|
if (totalPositions > MAX_TOTAL_POSITIONS) {
|
|
7997
8296
|
return {
|
|
7998
8297
|
isValid: false,
|
|
@@ -8000,8 +8299,8 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
8000
8299
|
errorMessage: `Total positions across all curves must not exceed ${MAX_TOTAL_POSITIONS}`
|
|
8001
8300
|
};
|
|
8002
8301
|
}
|
|
8003
|
-
const
|
|
8004
|
-
const hasGapOrOverlap =
|
|
8302
|
+
const sortedEntries = [...parsedEntries].sort((a, b) => a.segment.tickLower - b.segment.tickLower);
|
|
8303
|
+
const hasGapOrOverlap = sortedEntries.slice(1).some((current, index) => current.segment.tickLower !== sortedEntries[index]?.segment.tickUpper);
|
|
8005
8304
|
if (hasGapOrOverlap) {
|
|
8006
8305
|
return {
|
|
8007
8306
|
isValid: false,
|
|
@@ -8009,10 +8308,11 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
8009
8308
|
errorMessage: "Curve segments must be contiguous (no overlap or gaps)"
|
|
8010
8309
|
};
|
|
8011
8310
|
}
|
|
8012
|
-
const shareSum =
|
|
8013
|
-
if (
|
|
8311
|
+
const shareSum = sortedEntries.reduce((sum, entry) => sum + entry.shareScaledUnits, 0n);
|
|
8312
|
+
if (shareSum !== SHARE_SCALE_UNITS) {
|
|
8014
8313
|
return { isValid: false, error: "share-sum-invalid", errorMessage: "Curve share values must add up to 1" };
|
|
8015
8314
|
}
|
|
8315
|
+
const sortedSegments = sortedEntries.map((entry) => entry.segment);
|
|
8016
8316
|
const narrowSegment = sortedSegments.find((segment) => {
|
|
8017
8317
|
const minSpan = segment.numPositions * tickSpacing;
|
|
8018
8318
|
return segment.tickUpper - segment.tickLower < minSpan || computeGrossLiquidityAtFarTick(segment.tickLower, segment.tickUpper - segment.tickLower, segment.numPositions, Number(segment.shares), totalCurveSupplyTokens) > MAX_LIQUIDITY_PER_TICK;
|
|
@@ -8041,8 +8341,8 @@ function normalizeSegment(segment, tickSpacing) {
|
|
|
8041
8341
|
const tickLower = toValidNumber(segment.tickLower);
|
|
8042
8342
|
const tickUpper = toValidNumber(segment.tickUpper);
|
|
8043
8343
|
const numPositions = toValidNumber(segment.numPositions);
|
|
8044
|
-
const
|
|
8045
|
-
if (tickLower === null || tickUpper === null || numPositions === null ||
|
|
8344
|
+
const share = toNormalizedShare(segment.shares);
|
|
8345
|
+
if (tickLower === null || tickUpper === null || numPositions === null || share === null) {
|
|
8046
8346
|
return invalidSegmentResult();
|
|
8047
8347
|
}
|
|
8048
8348
|
if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper) || !Number.isInteger(numPositions) || numPositions <= 0) {
|
|
@@ -8059,11 +8359,14 @@ function normalizeSegment(segment, tickSpacing) {
|
|
|
8059
8359
|
}
|
|
8060
8360
|
return {
|
|
8061
8361
|
isValid: true,
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8362
|
+
entry: {
|
|
8363
|
+
segment: {
|
|
8364
|
+
tickLower,
|
|
8365
|
+
tickUpper,
|
|
8366
|
+
numPositions,
|
|
8367
|
+
shares: share.decimal
|
|
8368
|
+
},
|
|
8369
|
+
shareScaledUnits: share.scaledUnits
|
|
8067
8370
|
}
|
|
8068
8371
|
};
|
|
8069
8372
|
}
|
|
@@ -8430,9 +8733,23 @@ function missingLiquidEditionAddressError(txHash, receipt, cause) {
|
|
|
8430
8733
|
const message = `Liquid Edition deploy transaction succeeded, but the deployed contract address could not be read from the LiquidTokenCreated event logs after ${LIQUID_EDITION_ADDRESS_LOG_RETRY_ATTEMPTS + 1} attempts. Transaction hash: ${txHash}. Block: ${receipt.blockNumber}. The connected RPC may be delayed or returning incomplete receipt logs; retry with a synced RPC or inspect the transaction hash.`;
|
|
8431
8734
|
return cause instanceof Error ? new Error(message, { cause }) : new Error(message);
|
|
8432
8735
|
}
|
|
8433
|
-
function
|
|
8736
|
+
function liquidEditionRevertedReceiptError(message, txHash, receipt) {
|
|
8434
8737
|
return new Error(
|
|
8435
|
-
|
|
8738
|
+
`${message} Transaction hash: ${txHash}. Block: ${receipt.blockNumber}.`
|
|
8739
|
+
);
|
|
8740
|
+
}
|
|
8741
|
+
function liquidEditionDeployRevertedError(txHash, receipt) {
|
|
8742
|
+
return liquidEditionRevertedReceiptError(
|
|
8743
|
+
"Liquid Edition deploy transaction reverted before emitting LiquidTokenCreated.",
|
|
8744
|
+
txHash,
|
|
8745
|
+
receipt
|
|
8746
|
+
);
|
|
8747
|
+
}
|
|
8748
|
+
function liquidEditionSetRenderContractRevertedError(txHash, receipt) {
|
|
8749
|
+
return liquidEditionRevertedReceiptError(
|
|
8750
|
+
'Liquid Edition setRenderContract transaction was confirmed with status "reverted".',
|
|
8751
|
+
txHash,
|
|
8752
|
+
receipt
|
|
8436
8753
|
);
|
|
8437
8754
|
}
|
|
8438
8755
|
async function waitForLiquidEditionAddress(publicClient, txHash) {
|
|
@@ -8518,7 +8835,13 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
8518
8835
|
throw new Error(validation.errorMessage ?? "Invalid curve configuration");
|
|
8519
8836
|
}
|
|
8520
8837
|
const initialRareLiquidity = params.initialRareLiquidity !== void 0 ? await toTokenAmount(publicClient, factoryConfig.baseToken, params.initialRareLiquidity, "initialRareLiquidity") : 0n;
|
|
8521
|
-
|
|
8838
|
+
const curves = validation.curves.map((curve) => ({
|
|
8839
|
+
tickLower: curve.tickLower,
|
|
8840
|
+
tickUpper: curve.tickUpper,
|
|
8841
|
+
numPositions: curve.numPositions,
|
|
8842
|
+
shares: parseUnits6(curve.shares, 18)
|
|
8843
|
+
}));
|
|
8844
|
+
const approvalTxHash = await ensureTokenAllowance(
|
|
8522
8845
|
publicClient,
|
|
8523
8846
|
walletClient,
|
|
8524
8847
|
account,
|
|
@@ -8527,43 +8850,49 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
8527
8850
|
liquidFactory,
|
|
8528
8851
|
initialRareLiquidity
|
|
8529
8852
|
);
|
|
8530
|
-
const
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8853
|
+
const { txHash, receipt, contract } = await runWithApprovalSideEffectAlert({
|
|
8854
|
+
operation: "liquid edition deploy",
|
|
8855
|
+
approvals: [{
|
|
8856
|
+
type: "erc20",
|
|
8857
|
+
approvalTxHash,
|
|
8858
|
+
target: factoryConfig.baseToken,
|
|
8859
|
+
spender: liquidFactory
|
|
8860
|
+
}],
|
|
8861
|
+
run: async () => {
|
|
8862
|
+
const targetTxHash = customMaxTotalSupply === void 0 ? await walletClient.writeContract({
|
|
8863
|
+
address: liquidFactory,
|
|
8864
|
+
abi: liquidFactoryAbi,
|
|
8865
|
+
functionName: "createLiquidTokenMultiCurve",
|
|
8866
|
+
args: [
|
|
8867
|
+
accountAddress,
|
|
8868
|
+
params.tokenUri,
|
|
8869
|
+
params.name,
|
|
8870
|
+
params.symbol,
|
|
8871
|
+
initialRareLiquidity,
|
|
8872
|
+
curves
|
|
8873
|
+
],
|
|
8874
|
+
account,
|
|
8875
|
+
chain: void 0
|
|
8876
|
+
}) : await walletClient.writeContract({
|
|
8877
|
+
address: liquidFactory,
|
|
8878
|
+
abi: liquidFactoryAbi,
|
|
8879
|
+
functionName: "createLiquidTokenMultiCurveWithSupply",
|
|
8880
|
+
args: [
|
|
8881
|
+
accountAddress,
|
|
8882
|
+
params.tokenUri,
|
|
8883
|
+
params.name,
|
|
8884
|
+
params.symbol,
|
|
8885
|
+
initialRareLiquidity,
|
|
8886
|
+
curves,
|
|
8887
|
+
customMaxTotalSupply
|
|
8888
|
+
],
|
|
8889
|
+
account,
|
|
8890
|
+
chain: void 0
|
|
8891
|
+
});
|
|
8892
|
+
const deployed = await waitForLiquidEditionAddress(publicClient, targetTxHash);
|
|
8893
|
+
return { txHash: targetTxHash, receipt: deployed.receipt, contract: deployed.contract };
|
|
8894
|
+
}
|
|
8565
8895
|
});
|
|
8566
|
-
const { receipt, contract } = await waitForLiquidEditionAddress(publicClient, txHash);
|
|
8567
8896
|
return {
|
|
8568
8897
|
txHash,
|
|
8569
8898
|
receipt,
|
|
@@ -8598,6 +8927,9 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
8598
8927
|
chain: void 0
|
|
8599
8928
|
});
|
|
8600
8929
|
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
8930
|
+
if (receipt.status === "reverted") {
|
|
8931
|
+
throw liquidEditionSetRenderContractRevertedError(txHash, receipt);
|
|
8932
|
+
}
|
|
8601
8933
|
return {
|
|
8602
8934
|
txHash,
|
|
8603
8935
|
receipt,
|
|
@@ -8704,6 +9036,312 @@ function createLiquidNamespace(config, chain, addresses) {
|
|
|
8704
9036
|
};
|
|
8705
9037
|
}
|
|
8706
9038
|
|
|
9039
|
+
// src/sdk/bridge.ts
|
|
9040
|
+
import { encodeFunctionData } from "viem";
|
|
9041
|
+
|
|
9042
|
+
// src/contracts/abis/rare-bridge.ts
|
|
9043
|
+
var rareBridgeAbi = [
|
|
9044
|
+
{
|
|
9045
|
+
type: "function",
|
|
9046
|
+
name: "getFee",
|
|
9047
|
+
inputs: [
|
|
9048
|
+
{
|
|
9049
|
+
name: "_destinationChainSelector",
|
|
9050
|
+
type: "uint64",
|
|
9051
|
+
internalType: "uint64"
|
|
9052
|
+
},
|
|
9053
|
+
{
|
|
9054
|
+
name: "_destinationChainRecipient",
|
|
9055
|
+
type: "address",
|
|
9056
|
+
internalType: "address"
|
|
9057
|
+
},
|
|
9058
|
+
{
|
|
9059
|
+
name: "_distributionData",
|
|
9060
|
+
type: "bytes",
|
|
9061
|
+
internalType: "bytes"
|
|
9062
|
+
},
|
|
9063
|
+
{
|
|
9064
|
+
name: "_extraArgs",
|
|
9065
|
+
type: "bytes",
|
|
9066
|
+
internalType: "bytes"
|
|
9067
|
+
},
|
|
9068
|
+
{
|
|
9069
|
+
name: "_payFeesInLink",
|
|
9070
|
+
type: "bool",
|
|
9071
|
+
internalType: "bool"
|
|
9072
|
+
}
|
|
9073
|
+
],
|
|
9074
|
+
outputs: [
|
|
9075
|
+
{
|
|
9076
|
+
name: "fee",
|
|
9077
|
+
type: "uint256",
|
|
9078
|
+
internalType: "uint256"
|
|
9079
|
+
}
|
|
9080
|
+
],
|
|
9081
|
+
stateMutability: "view"
|
|
9082
|
+
},
|
|
9083
|
+
{
|
|
9084
|
+
type: "function",
|
|
9085
|
+
name: "send",
|
|
9086
|
+
inputs: [
|
|
9087
|
+
{
|
|
9088
|
+
name: "_destinationChainSelector",
|
|
9089
|
+
type: "uint64",
|
|
9090
|
+
internalType: "uint64"
|
|
9091
|
+
},
|
|
9092
|
+
{
|
|
9093
|
+
name: "_destinationChainRecipient",
|
|
9094
|
+
type: "address",
|
|
9095
|
+
internalType: "address"
|
|
9096
|
+
},
|
|
9097
|
+
{
|
|
9098
|
+
name: "_distributionData",
|
|
9099
|
+
type: "bytes",
|
|
9100
|
+
internalType: "bytes"
|
|
9101
|
+
},
|
|
9102
|
+
{
|
|
9103
|
+
name: "_extraArgs",
|
|
9104
|
+
type: "bytes",
|
|
9105
|
+
internalType: "bytes"
|
|
9106
|
+
},
|
|
9107
|
+
{
|
|
9108
|
+
name: "_payFeesInLink",
|
|
9109
|
+
type: "bool",
|
|
9110
|
+
internalType: "bool"
|
|
9111
|
+
}
|
|
9112
|
+
],
|
|
9113
|
+
outputs: [],
|
|
9114
|
+
stateMutability: "payable"
|
|
9115
|
+
},
|
|
9116
|
+
{
|
|
9117
|
+
type: "event",
|
|
9118
|
+
name: "MessageSent",
|
|
9119
|
+
inputs: [
|
|
9120
|
+
{
|
|
9121
|
+
name: "messageId",
|
|
9122
|
+
type: "bytes32",
|
|
9123
|
+
indexed: true,
|
|
9124
|
+
internalType: "bytes32"
|
|
9125
|
+
},
|
|
9126
|
+
{
|
|
9127
|
+
name: "destinationChainSelector",
|
|
9128
|
+
type: "uint64",
|
|
9129
|
+
indexed: true,
|
|
9130
|
+
internalType: "uint64"
|
|
9131
|
+
},
|
|
9132
|
+
{
|
|
9133
|
+
name: "destinationChainRecipient",
|
|
9134
|
+
type: "address",
|
|
9135
|
+
indexed: true,
|
|
9136
|
+
internalType: "address"
|
|
9137
|
+
},
|
|
9138
|
+
{
|
|
9139
|
+
name: "fee",
|
|
9140
|
+
type: "uint256",
|
|
9141
|
+
indexed: false,
|
|
9142
|
+
internalType: "uint256"
|
|
9143
|
+
},
|
|
9144
|
+
{
|
|
9145
|
+
name: "payFeesInLink",
|
|
9146
|
+
type: "bool",
|
|
9147
|
+
indexed: false,
|
|
9148
|
+
internalType: "bool"
|
|
9149
|
+
}
|
|
9150
|
+
],
|
|
9151
|
+
anonymous: false
|
|
9152
|
+
}
|
|
9153
|
+
];
|
|
9154
|
+
|
|
9155
|
+
// src/sdk/bridge-core.ts
|
|
9156
|
+
import { encodeAbiParameters } from "viem";
|
|
9157
|
+
var allowedBridgePairs = [
|
|
9158
|
+
{ sourceChain: "mainnet", destinationChain: "base" },
|
|
9159
|
+
{ sourceChain: "base", destinationChain: "mainnet" },
|
|
9160
|
+
{ sourceChain: "sepolia", destinationChain: "base-sepolia" },
|
|
9161
|
+
{ sourceChain: "base-sepolia", destinationChain: "sepolia" }
|
|
9162
|
+
];
|
|
9163
|
+
function validateBridgeRoute(route) {
|
|
9164
|
+
const supported = allowedBridgePairs.some(
|
|
9165
|
+
(pair) => pair.sourceChain === route.sourceChain && pair.destinationChain === route.destinationChain
|
|
9166
|
+
);
|
|
9167
|
+
if (supported) {
|
|
9168
|
+
return { isValid: true };
|
|
9169
|
+
}
|
|
9170
|
+
return {
|
|
9171
|
+
isValid: false,
|
|
9172
|
+
error: "unsupported_bridge_route",
|
|
9173
|
+
errorMessage: `Unsupported RARE bridge route "${route.sourceChain}" -> "${route.destinationChain}". Supported routes: mainnet <-> base, sepolia <-> base-sepolia.`
|
|
9174
|
+
};
|
|
9175
|
+
}
|
|
9176
|
+
function getBridgeInfo(chain) {
|
|
9177
|
+
return {
|
|
9178
|
+
chain,
|
|
9179
|
+
chainId: chainIds[chain],
|
|
9180
|
+
rareBridgeAddress: getRareBridgeAddress(chain),
|
|
9181
|
+
rareTokenAddress: resolveCurrency("rare", chain),
|
|
9182
|
+
ccipChainSelector: getCcipChainSelector(chain)
|
|
9183
|
+
};
|
|
9184
|
+
}
|
|
9185
|
+
function encodeBridgeDistribution(params) {
|
|
9186
|
+
return encodeAbiParameters(
|
|
9187
|
+
[
|
|
9188
|
+
{ name: "recipients", type: "address[]" },
|
|
9189
|
+
{ name: "amounts", type: "uint256[]" }
|
|
9190
|
+
],
|
|
9191
|
+
[[params.recipient], [params.amount]]
|
|
9192
|
+
);
|
|
9193
|
+
}
|
|
9194
|
+
function buildBridgeSendArgs(params) {
|
|
9195
|
+
return [
|
|
9196
|
+
params.destinationBridgeInfo.ccipChainSelector,
|
|
9197
|
+
params.destinationBridgeInfo.rareBridgeAddress,
|
|
9198
|
+
params.distributionData,
|
|
9199
|
+
"0x",
|
|
9200
|
+
false
|
|
9201
|
+
];
|
|
9202
|
+
}
|
|
9203
|
+
function buildCcipExplorerUrl(txHash) {
|
|
9204
|
+
return `https://ccip.chain.link/tx/${txHash}`;
|
|
9205
|
+
}
|
|
9206
|
+
|
|
9207
|
+
// src/sdk/bridge.ts
|
|
9208
|
+
function createBridgeNamespace(publicClient, config, sourceChain) {
|
|
9209
|
+
return {
|
|
9210
|
+
async quote(params) {
|
|
9211
|
+
return buildBridgeQuote(publicClient, config, sourceChain, params);
|
|
9212
|
+
},
|
|
9213
|
+
async send(params) {
|
|
9214
|
+
return executeBridge(publicClient, config, sourceChain, params);
|
|
9215
|
+
}
|
|
9216
|
+
};
|
|
9217
|
+
}
|
|
9218
|
+
async function executeBridge(publicClient, config, sourceChain, params) {
|
|
9219
|
+
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
9220
|
+
const quote = await buildBridgeQuote(publicClient, config, sourceChain, {
|
|
9221
|
+
...params,
|
|
9222
|
+
recipient: params.recipient ?? accountAddress
|
|
9223
|
+
}, {
|
|
9224
|
+
estimateGas: false
|
|
9225
|
+
});
|
|
9226
|
+
const approval = await preparePaymentAmountForSpender({
|
|
9227
|
+
publicClient,
|
|
9228
|
+
walletClient,
|
|
9229
|
+
account,
|
|
9230
|
+
accountAddress,
|
|
9231
|
+
spenderAddress: quote.sourceBridgeAddress,
|
|
9232
|
+
currency: quote.rareTokenAddress,
|
|
9233
|
+
requiredAmount: quote.amount,
|
|
9234
|
+
autoApprove: params.autoApprove
|
|
9235
|
+
});
|
|
9236
|
+
const sendArgs = buildBridgeSendArgs({
|
|
9237
|
+
destinationBridgeInfo: getBridgeInfo(quote.destinationChain),
|
|
9238
|
+
distributionData: quote.distributionData
|
|
9239
|
+
});
|
|
9240
|
+
const { txHash, receipt, estimatedGas } = await runWithApprovalSideEffectAlert({
|
|
9241
|
+
operation: "bridge send",
|
|
9242
|
+
approvals: [{
|
|
9243
|
+
type: "erc20",
|
|
9244
|
+
approvalTxHash: approval.approvalTxHash,
|
|
9245
|
+
target: quote.rareTokenAddress,
|
|
9246
|
+
spender: quote.sourceBridgeAddress
|
|
9247
|
+
}],
|
|
9248
|
+
run: async () => {
|
|
9249
|
+
const gas = await estimateBridgeGas(publicClient, {
|
|
9250
|
+
account: accountAddress,
|
|
9251
|
+
sourceBridgeAddress: quote.sourceBridgeAddress,
|
|
9252
|
+
args: sendArgs,
|
|
9253
|
+
nativeFee: quote.nativeFee
|
|
9254
|
+
});
|
|
9255
|
+
const targetTxHash = await walletClient.writeContract({
|
|
9256
|
+
address: quote.sourceBridgeAddress,
|
|
9257
|
+
abi: rareBridgeAbi,
|
|
9258
|
+
functionName: "send",
|
|
9259
|
+
args: sendArgs,
|
|
9260
|
+
value: quote.nativeFee,
|
|
9261
|
+
account,
|
|
9262
|
+
chain: void 0
|
|
9263
|
+
});
|
|
9264
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
9265
|
+
return { txHash: targetTxHash, receipt: targetReceipt, estimatedGas: gas };
|
|
9266
|
+
}
|
|
9267
|
+
});
|
|
9268
|
+
return {
|
|
9269
|
+
...quote,
|
|
9270
|
+
estimatedGas,
|
|
9271
|
+
txHash,
|
|
9272
|
+
receipt,
|
|
9273
|
+
approvalTxHash: approval.approvalTxHash,
|
|
9274
|
+
ccipExplorerUrl: buildCcipExplorerUrl(txHash)
|
|
9275
|
+
};
|
|
9276
|
+
}
|
|
9277
|
+
async function buildBridgeQuote(publicClient, config, sourceChain, params, options = {}) {
|
|
9278
|
+
const routeValidation = validateBridgeRoute({
|
|
9279
|
+
sourceChain,
|
|
9280
|
+
destinationChain: params.destinationChain
|
|
9281
|
+
});
|
|
9282
|
+
if (!routeValidation.isValid) {
|
|
9283
|
+
throw new Error(routeValidation.errorMessage);
|
|
9284
|
+
}
|
|
9285
|
+
const sourceBridgeInfo = getBridgeInfo(sourceChain);
|
|
9286
|
+
const destinationBridgeInfo = getBridgeInfo(params.destinationChain);
|
|
9287
|
+
const recipient = resolveRecipient(params.recipient, config);
|
|
9288
|
+
const amount = toPositiveWei(params.amount, "amount");
|
|
9289
|
+
const distributionData = encodeBridgeDistribution({ recipient, amount });
|
|
9290
|
+
const args = buildBridgeSendArgs({
|
|
9291
|
+
destinationBridgeInfo,
|
|
9292
|
+
distributionData
|
|
9293
|
+
});
|
|
9294
|
+
const nativeFee = await publicClient.readContract({
|
|
9295
|
+
address: sourceBridgeInfo.rareBridgeAddress,
|
|
9296
|
+
abi: rareBridgeAbi,
|
|
9297
|
+
functionName: "getFee",
|
|
9298
|
+
args
|
|
9299
|
+
});
|
|
9300
|
+
const estimatedGas = options.estimateGas === false ? void 0 : await estimateBridgeGas(publicClient, {
|
|
9301
|
+
account: getConfiguredAccountAddress(config),
|
|
9302
|
+
sourceBridgeAddress: sourceBridgeInfo.rareBridgeAddress,
|
|
9303
|
+
args,
|
|
9304
|
+
nativeFee
|
|
9305
|
+
});
|
|
9306
|
+
return {
|
|
9307
|
+
sourceChain,
|
|
9308
|
+
sourceChainId: sourceBridgeInfo.chainId,
|
|
9309
|
+
destinationChain: params.destinationChain,
|
|
9310
|
+
destinationChainId: destinationBridgeInfo.chainId,
|
|
9311
|
+
sourceBridgeAddress: sourceBridgeInfo.rareBridgeAddress,
|
|
9312
|
+
destinationBridgeAddress: destinationBridgeInfo.rareBridgeAddress,
|
|
9313
|
+
rareTokenAddress: sourceBridgeInfo.rareTokenAddress,
|
|
9314
|
+
destinationCcipChainSelector: destinationBridgeInfo.ccipChainSelector,
|
|
9315
|
+
amount,
|
|
9316
|
+
recipient,
|
|
9317
|
+
distributionData,
|
|
9318
|
+
nativeFee,
|
|
9319
|
+
estimatedGas
|
|
9320
|
+
};
|
|
9321
|
+
}
|
|
9322
|
+
function resolveRecipient(recipient, config) {
|
|
9323
|
+
const resolved = recipient ?? getConfiguredAccountAddress(config);
|
|
9324
|
+
if (resolved === void 0) {
|
|
9325
|
+
throw new Error("No recipient available for bridge quote. Pass params.recipient or provide config.account/walletClient with an account.");
|
|
9326
|
+
}
|
|
9327
|
+
return resolved;
|
|
9328
|
+
}
|
|
9329
|
+
async function estimateBridgeGas(publicClient, params) {
|
|
9330
|
+
if (params.account === void 0) {
|
|
9331
|
+
return void 0;
|
|
9332
|
+
}
|
|
9333
|
+
return publicClient.estimateGas({
|
|
9334
|
+
account: params.account,
|
|
9335
|
+
to: params.sourceBridgeAddress,
|
|
9336
|
+
data: encodeFunctionData({
|
|
9337
|
+
abi: rareBridgeAbi,
|
|
9338
|
+
functionName: "send",
|
|
9339
|
+
args: params.args
|
|
9340
|
+
}),
|
|
9341
|
+
value: params.nativeFee
|
|
9342
|
+
});
|
|
9343
|
+
}
|
|
9344
|
+
|
|
8707
9345
|
// src/contracts/abis/liquid-router.ts
|
|
8708
9346
|
var liquidRouterAbi = [
|
|
8709
9347
|
{
|
|
@@ -9090,7 +9728,7 @@ async function quoteRouteSteps(publicClient, quoterAddress, routeSteps, currentA
|
|
|
9090
9728
|
|
|
9091
9729
|
// src/swap/route-encoding.ts
|
|
9092
9730
|
import {
|
|
9093
|
-
encodeAbiParameters,
|
|
9731
|
+
encodeAbiParameters as encodeAbiParameters2,
|
|
9094
9732
|
encodePacked as encodePacked2,
|
|
9095
9733
|
getAddress as getAddress7,
|
|
9096
9734
|
parseAbiParameters
|
|
@@ -9202,13 +9840,13 @@ function getV4ExecutionMode(v4BlockStartIndex, nextIndex, routeLength) {
|
|
|
9202
9840
|
};
|
|
9203
9841
|
}
|
|
9204
9842
|
function encodeWrapEth(recipient, amount) {
|
|
9205
|
-
return
|
|
9843
|
+
return encodeAbiParameters2(
|
|
9206
9844
|
parseAbiParameters("address recipient, uint256 amount"),
|
|
9207
9845
|
[recipient, amount]
|
|
9208
9846
|
);
|
|
9209
9847
|
}
|
|
9210
9848
|
function encodeUnwrapWeth(recipient, amountMinimum) {
|
|
9211
|
-
return
|
|
9849
|
+
return encodeAbiParameters2(
|
|
9212
9850
|
parseAbiParameters("address recipient, uint256 amountMinimum"),
|
|
9213
9851
|
[recipient, amountMinimum]
|
|
9214
9852
|
);
|
|
@@ -9228,23 +9866,23 @@ function encodeV4ExactIn({
|
|
|
9228
9866
|
step.poolKey.hooks,
|
|
9229
9867
|
"0x"
|
|
9230
9868
|
]);
|
|
9231
|
-
const swapParams =
|
|
9869
|
+
const swapParams = encodeAbiParameters2(
|
|
9232
9870
|
parseAbiParameters("(address,(address,uint24,int24,address,bytes)[],uint128,uint128)"),
|
|
9233
9871
|
[[currencyIn, pathKeysArray, amountIn, minAmountOut]]
|
|
9234
9872
|
);
|
|
9235
9873
|
const settleAction = executionMode.inputSource === "user" ? V4_ACTIONS.SETTLE_ALL : V4_ACTIONS.SETTLE;
|
|
9236
|
-
const settleParams = executionMode.inputSource === "user" ?
|
|
9874
|
+
const settleParams = executionMode.inputSource === "user" ? encodeAbiParameters2(
|
|
9237
9875
|
parseAbiParameters("address currency, uint128 maxAmount"),
|
|
9238
9876
|
[currencyIn, amountIn]
|
|
9239
|
-
) :
|
|
9877
|
+
) : encodeAbiParameters2(
|
|
9240
9878
|
parseAbiParameters("address currency, uint256 amount, bool payerIsUser"),
|
|
9241
9879
|
[currencyIn, ROUTER_AMOUNT_CONSTANTS.contractBalance, false]
|
|
9242
9880
|
);
|
|
9243
9881
|
const takeAction = executionMode.outputTarget === "user" ? V4_ACTIONS.TAKE_ALL : V4_ACTIONS.TAKE;
|
|
9244
|
-
const takeParams = executionMode.outputTarget === "user" ?
|
|
9882
|
+
const takeParams = executionMode.outputTarget === "user" ? encodeAbiParameters2(
|
|
9245
9883
|
parseAbiParameters("address currency, uint128 minAmount"),
|
|
9246
9884
|
[currencyOut, minAmountOut]
|
|
9247
|
-
) :
|
|
9885
|
+
) : encodeAbiParameters2(
|
|
9248
9886
|
parseAbiParameters("address currency, address recipient, uint256 amount"),
|
|
9249
9887
|
[currencyOut, ROUTER_RECIPIENTS.addressThis, ROUTER_AMOUNT_CONSTANTS.openDelta]
|
|
9250
9888
|
);
|
|
@@ -9257,7 +9895,7 @@ function encodeV4ExactIn({
|
|
|
9257
9895
|
["uint8", "uint8", "uint8"],
|
|
9258
9896
|
[settleAction, V4_ACTIONS.SWAP_EXACT_IN_SINGLE, takeAction]
|
|
9259
9897
|
);
|
|
9260
|
-
return
|
|
9898
|
+
return encodeAbiParameters2(
|
|
9261
9899
|
parseAbiParameters("bytes actions, bytes[] params"),
|
|
9262
9900
|
[
|
|
9263
9901
|
actions2,
|
|
@@ -9273,7 +9911,7 @@ function encodeV4ExactIn({
|
|
|
9273
9911
|
["uint8", "uint8", "uint8"],
|
|
9274
9912
|
[V4_ACTIONS.SWAP_EXACT_IN, settleAction, takeAction]
|
|
9275
9913
|
);
|
|
9276
|
-
return
|
|
9914
|
+
return encodeAbiParameters2(
|
|
9277
9915
|
parseAbiParameters("bytes actions, bytes[] params"),
|
|
9278
9916
|
[actions, [swapParams, settleParams, takeParams]]
|
|
9279
9917
|
);
|
|
@@ -9292,7 +9930,7 @@ function encodeV4ExactInSingle(step, amountIn, minAmountOut) {
|
|
|
9292
9930
|
minAmountOut,
|
|
9293
9931
|
"0x"
|
|
9294
9932
|
];
|
|
9295
|
-
return
|
|
9933
|
+
return encodeAbiParameters2(
|
|
9296
9934
|
parseAbiParameters("((address,address,uint24,int24,address),bool,uint128,uint128,bytes)"),
|
|
9297
9935
|
[swapExactInSingleTuple]
|
|
9298
9936
|
);
|
|
@@ -9899,7 +10537,7 @@ async function executeRawRouterBuy(params) {
|
|
|
9899
10537
|
const minAmountOutInput = requireInput(params.minAmountOut, "minAmountOut");
|
|
9900
10538
|
const ethAmount = toWei(amountIn);
|
|
9901
10539
|
const minTokensOut = await toTokenAmount(params.publicClient, params.token, minAmountOutInput, "minAmountOut");
|
|
9902
|
-
const
|
|
10540
|
+
const targetTxHash = await walletClient.writeContract({
|
|
9903
10541
|
address: router,
|
|
9904
10542
|
abi: liquidRouterAbi,
|
|
9905
10543
|
functionName: "buy",
|
|
@@ -9908,8 +10546,8 @@ async function executeRawRouterBuy(params) {
|
|
|
9908
10546
|
chain: void 0,
|
|
9909
10547
|
value: ethAmount
|
|
9910
10548
|
});
|
|
9911
|
-
const
|
|
9912
|
-
return { txHash, receipt, minAmountOut: minTokensOut };
|
|
10549
|
+
const targetReceipt = await params.publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10550
|
+
return { txHash: targetTxHash, receipt: targetReceipt, minAmountOut: minTokensOut };
|
|
9913
10551
|
}
|
|
9914
10552
|
async function executeRawRouterSell(params) {
|
|
9915
10553
|
const { walletClient, account, accountAddress } = requireWallet(params.config);
|
|
@@ -9919,25 +10557,37 @@ async function executeRawRouterSell(params) {
|
|
|
9919
10557
|
const minAmountOutInput = requireInput(params.minAmountOut, "minAmountOut");
|
|
9920
10558
|
const tokenAmount = await toTokenAmount(params.publicClient, params.token, amountIn, "amountIn");
|
|
9921
10559
|
const minEthOut = toWei(minAmountOutInput);
|
|
9922
|
-
await ensureTokenAllowance(params.publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
9923
|
-
const txHash = await
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
params.token,
|
|
9929
|
-
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
10560
|
+
const approvalTxHash = await ensureTokenAllowance(params.publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
10561
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
10562
|
+
operation: "swap sell",
|
|
10563
|
+
approvals: [{
|
|
10564
|
+
type: "erc20",
|
|
10565
|
+
approvalTxHash,
|
|
10566
|
+
target: params.token,
|
|
10567
|
+
spender: router
|
|
10568
|
+
}],
|
|
10569
|
+
run: async () => {
|
|
10570
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10571
|
+
address: router,
|
|
10572
|
+
abi: liquidRouterAbi,
|
|
10573
|
+
functionName: "sell",
|
|
10574
|
+
args: [
|
|
10575
|
+
params.token,
|
|
10576
|
+
tokenAmount,
|
|
10577
|
+
params.recipient ?? accountAddress,
|
|
10578
|
+
minEthOut,
|
|
10579
|
+
params.commands,
|
|
10580
|
+
[...params.inputs],
|
|
10581
|
+
resolveDeadline(params.deadline)
|
|
10582
|
+
],
|
|
10583
|
+
account,
|
|
10584
|
+
chain: void 0
|
|
10585
|
+
});
|
|
10586
|
+
const targetReceipt = await params.publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10587
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
10588
|
+
}
|
|
9938
10589
|
});
|
|
9939
|
-
|
|
9940
|
-
return { txHash, receipt, minAmountOut: minEthOut, tokenAmount };
|
|
10590
|
+
return { txHash, receipt, minAmountOut: minEthOut, tokenAmount, approvalTxHash };
|
|
9941
10591
|
}
|
|
9942
10592
|
function isRawTokenTradeParams(params) {
|
|
9943
10593
|
return params.route === "raw";
|
|
@@ -9981,28 +10631,38 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
9981
10631
|
validateRouterPayload(params.commands, params.inputs);
|
|
9982
10632
|
const amountIn = await toTokenAmount(publicClient, params.tokenIn, params.amountIn, "amountIn");
|
|
9983
10633
|
const minAmountOut = await toTokenAmount(publicClient, params.tokenOut, params.minAmountOut, "minAmountOut");
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
|
|
10634
|
+
const approvalTxHash = params.tokenIn === ETH_ADDRESS ? void 0 : await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.tokenIn, router, amountIn);
|
|
10635
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
10636
|
+
operation: "swap tokens",
|
|
10637
|
+
approvals: [{
|
|
10638
|
+
type: "erc20",
|
|
10639
|
+
approvalTxHash,
|
|
10640
|
+
target: params.tokenIn,
|
|
10641
|
+
spender: router
|
|
10642
|
+
}],
|
|
10643
|
+
run: async () => {
|
|
10644
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10645
|
+
address: router,
|
|
10646
|
+
abi: liquidRouterAbi,
|
|
10647
|
+
functionName: "swap",
|
|
10648
|
+
args: [
|
|
10649
|
+
params.tokenIn,
|
|
10650
|
+
amountIn,
|
|
10651
|
+
params.tokenOut,
|
|
10652
|
+
params.recipient ?? accountAddress,
|
|
10653
|
+
minAmountOut,
|
|
10654
|
+
params.commands,
|
|
10655
|
+
[...params.inputs],
|
|
10656
|
+
resolveDeadline(params.deadline)
|
|
10657
|
+
],
|
|
10658
|
+
account,
|
|
10659
|
+
chain: void 0,
|
|
10660
|
+
value: params.tokenIn === ETH_ADDRESS ? amountIn : void 0
|
|
10661
|
+
});
|
|
10662
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10663
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
10664
|
+
}
|
|
10004
10665
|
});
|
|
10005
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
10006
10666
|
return { txHash, receipt };
|
|
10007
10667
|
},
|
|
10008
10668
|
async quoteBuyToken(params) {
|
|
@@ -10069,7 +10729,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10069
10729
|
});
|
|
10070
10730
|
if (quoteDetails.kind === "local") {
|
|
10071
10731
|
const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
|
|
10072
|
-
const
|
|
10732
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10073
10733
|
address: router,
|
|
10074
10734
|
abi: liquidRouterAbi,
|
|
10075
10735
|
functionName: "buy",
|
|
@@ -10085,10 +10745,10 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10085
10745
|
chain: void 0,
|
|
10086
10746
|
value: quoteDetails.quote.amountIn
|
|
10087
10747
|
});
|
|
10088
|
-
const
|
|
10748
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10089
10749
|
return {
|
|
10090
|
-
txHash,
|
|
10091
|
-
receipt,
|
|
10750
|
+
txHash: targetTxHash,
|
|
10751
|
+
receipt: targetReceipt,
|
|
10092
10752
|
estimatedAmountOut: quoteDetails.quote.estimatedAmountOut,
|
|
10093
10753
|
minAmountOut: quoteDetails.quote.minAmountOut,
|
|
10094
10754
|
routeSource: quoteDetails.quote.routeSource,
|
|
@@ -10180,24 +10840,36 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10180
10840
|
const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
|
|
10181
10841
|
const amountIn = requireInput(params.amountIn, "amountIn");
|
|
10182
10842
|
const tokenAmount = await toTokenAmount(publicClient, params.token, amountIn, "amountIn");
|
|
10183
|
-
await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
10184
|
-
const txHash = await
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
|
|
10188
|
-
|
|
10189
|
-
params.token,
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
10843
|
+
const approvalTxHash2 = await ensureTokenAllowance(publicClient, walletClient, account, accountAddress, params.token, router, tokenAmount);
|
|
10844
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
10845
|
+
operation: "sell token",
|
|
10846
|
+
approvals: [{
|
|
10847
|
+
type: "erc20",
|
|
10848
|
+
approvalTxHash: approvalTxHash2,
|
|
10849
|
+
target: params.token,
|
|
10850
|
+
spender: router
|
|
10851
|
+
}],
|
|
10852
|
+
run: async () => {
|
|
10853
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10854
|
+
address: router,
|
|
10855
|
+
abi: liquidRouterAbi,
|
|
10856
|
+
functionName: "sell",
|
|
10857
|
+
args: [
|
|
10858
|
+
params.token,
|
|
10859
|
+
tokenAmount,
|
|
10860
|
+
params.recipient ?? accountAddress,
|
|
10861
|
+
quoteDetails.quote.minAmountOut,
|
|
10862
|
+
quoteDetails.quote.commands,
|
|
10863
|
+
[...quoteDetails.quote.inputs],
|
|
10864
|
+
resolveDeadline(params.deadline)
|
|
10865
|
+
],
|
|
10866
|
+
account,
|
|
10867
|
+
chain: void 0
|
|
10868
|
+
});
|
|
10869
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10870
|
+
return { txHash: targetTxHash, receipt: targetReceipt };
|
|
10871
|
+
}
|
|
10199
10872
|
});
|
|
10200
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
10201
10873
|
return {
|
|
10202
10874
|
txHash,
|
|
10203
10875
|
receipt,
|
|
@@ -10206,7 +10878,8 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10206
10878
|
routeSource: quoteDetails.quote.routeSource,
|
|
10207
10879
|
execution: quoteDetails.quote.execution,
|
|
10208
10880
|
commands: quoteDetails.quote.commands,
|
|
10209
|
-
inputs: quoteDetails.quote.inputs
|
|
10881
|
+
inputs: quoteDetails.quote.inputs,
|
|
10882
|
+
approvalTxHash: approvalTxHash2
|
|
10210
10883
|
};
|
|
10211
10884
|
}
|
|
10212
10885
|
const approval = await requestUniswapApproval({
|
|
@@ -10225,14 +10898,33 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10225
10898
|
accountAddress,
|
|
10226
10899
|
chainId
|
|
10227
10900
|
})).txHash : void 0;
|
|
10228
|
-
const
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10901
|
+
const sent = await runWithApprovalSideEffectAlert({
|
|
10902
|
+
operation: "sell token",
|
|
10903
|
+
approvals: [
|
|
10904
|
+
{
|
|
10905
|
+
type: "erc20-reset",
|
|
10906
|
+
approvalTxHash: approvalResetTxHash,
|
|
10907
|
+
target: params.token,
|
|
10908
|
+
spender: approval.cancel?.to
|
|
10909
|
+
},
|
|
10910
|
+
{
|
|
10911
|
+
type: "erc20",
|
|
10912
|
+
approvalTxHash,
|
|
10913
|
+
target: params.token,
|
|
10914
|
+
spender: approval.approval?.to
|
|
10915
|
+
}
|
|
10916
|
+
],
|
|
10917
|
+
run: async () => {
|
|
10918
|
+
const swapResponse = await requestUniswapSwap({
|
|
10919
|
+
apiKey: quoteDetails.apiKey,
|
|
10920
|
+
quote: quoteDetails.rawQuote,
|
|
10921
|
+
deadline: uniswapDeadline
|
|
10922
|
+
});
|
|
10923
|
+
return sendPreparedTransaction(publicClient, walletClient, account, swapResponse.swap, {
|
|
10924
|
+
accountAddress,
|
|
10925
|
+
chainId
|
|
10926
|
+
});
|
|
10927
|
+
}
|
|
10236
10928
|
});
|
|
10237
10929
|
return {
|
|
10238
10930
|
...sent,
|
|
@@ -10251,7 +10943,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10251
10943
|
const { walletClient, account, accountAddress } = requireWallet(config);
|
|
10252
10944
|
const router = requireConfiguredAddress(addresses.swapRouter, "Liquid router", chain);
|
|
10253
10945
|
const quote = await buildBuyRareQuote(publicClient, chain, addresses, params);
|
|
10254
|
-
const
|
|
10946
|
+
const targetTxHash = await walletClient.writeContract({
|
|
10255
10947
|
address: router,
|
|
10256
10948
|
abi: liquidRouterAbi,
|
|
10257
10949
|
functionName: "buy",
|
|
@@ -10260,10 +10952,10 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10260
10952
|
chain: void 0,
|
|
10261
10953
|
value: quote.ethAmount
|
|
10262
10954
|
});
|
|
10263
|
-
const
|
|
10955
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
10264
10956
|
return {
|
|
10265
|
-
txHash,
|
|
10266
|
-
receipt,
|
|
10957
|
+
txHash: targetTxHash,
|
|
10958
|
+
receipt: targetReceipt,
|
|
10267
10959
|
estimatedRareOut: quote.estimatedRareOut,
|
|
10268
10960
|
minRareOut: quote.minRareOut,
|
|
10269
10961
|
commands: quote.commands,
|
|
@@ -10599,9 +11291,32 @@ var rareMinterAbi = [
|
|
|
10599
11291
|
];
|
|
10600
11292
|
|
|
10601
11293
|
// src/sdk/collection-core.ts
|
|
11294
|
+
var lazySovereignCollectionContractTypes = [
|
|
11295
|
+
"lazy",
|
|
11296
|
+
"lazy-royalty-guard",
|
|
11297
|
+
"lazy-deadman-royalty-guard"
|
|
11298
|
+
];
|
|
10602
11299
|
var defaultRoyaltyInfoSalePrice = 10000n;
|
|
11300
|
+
function normalizeLazySovereignCollectionContractType(input) {
|
|
11301
|
+
if (input === void 0) {
|
|
11302
|
+
return void 0;
|
|
11303
|
+
}
|
|
11304
|
+
const normalized = input.trim().toLowerCase();
|
|
11305
|
+
if (normalized === "lazy" || normalized === "standard" || normalized === "lazy-sovereign" || normalized === "lazy-sovereign-nft") {
|
|
11306
|
+
return "lazy";
|
|
11307
|
+
}
|
|
11308
|
+
if (normalized === "lazy-royalty-guard" || normalized === "royalty-guard") {
|
|
11309
|
+
return "lazy-royalty-guard";
|
|
11310
|
+
}
|
|
11311
|
+
if (normalized === "lazy-deadman-royalty-guard" || normalized === "lazy-royalty-guard-deadman" || normalized === "deadman-royalty-guard" || normalized === "royalty-guard-deadman" || normalized === "deadman") {
|
|
11312
|
+
return "lazy-deadman-royalty-guard";
|
|
11313
|
+
}
|
|
11314
|
+
throw new Error(
|
|
11315
|
+
`Unsupported Lazy Sovereign collection contract type "${input}". Supported: ${lazySovereignCollectionContractTypes.join(", ")}.`
|
|
11316
|
+
);
|
|
11317
|
+
}
|
|
10603
11318
|
function planCreateLazySovereignCollection(params) {
|
|
10604
|
-
const contractType = params.contractType ?? "lazy";
|
|
11319
|
+
const contractType = normalizeLazySovereignCollectionContractType(params.contractType) ?? "lazy";
|
|
10605
11320
|
return {
|
|
10606
11321
|
name: params.name,
|
|
10607
11322
|
symbol: params.symbol,
|
|
@@ -11428,10 +12143,8 @@ async function readReleaseCollectionOwner(publicClient, contract) {
|
|
|
11428
12143
|
);
|
|
11429
12144
|
}
|
|
11430
12145
|
}
|
|
11431
|
-
async function
|
|
12146
|
+
async function assertReleaseMinterCanMint(opts) {
|
|
11432
12147
|
const { publicClient, contract, accountAddress, rareMinter } = opts;
|
|
11433
|
-
const owner = await readReleaseCollectionOwner(publicClient, contract);
|
|
11434
|
-
assertReleaseContractOwner({ contract, accountAddress, owner });
|
|
11435
12148
|
try {
|
|
11436
12149
|
await publicClient.simulateContract({
|
|
11437
12150
|
address: contract,
|
|
@@ -11797,6 +12510,11 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
|
|
|
11797
12510
|
currencyDecimals: currencyDecimals2,
|
|
11798
12511
|
nowSeconds: currentUnixTimestamp3()
|
|
11799
12512
|
});
|
|
12513
|
+
await assertCollectionOwnerForReleaseWrite({
|
|
12514
|
+
publicClient,
|
|
12515
|
+
contract: plan.contract,
|
|
12516
|
+
accountAddress
|
|
12517
|
+
});
|
|
11800
12518
|
const approvalTxHash = await approveReleaseMinterIfNeeded({
|
|
11801
12519
|
publicClient,
|
|
11802
12520
|
walletClient,
|
|
@@ -11805,29 +12523,41 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
|
|
|
11805
12523
|
minter: rareMinter,
|
|
11806
12524
|
autoApprove: params.autoApprove
|
|
11807
12525
|
});
|
|
11808
|
-
await
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
12526
|
+
const { txHash, receipt } = await runWithApprovalSideEffectAlert({
|
|
12527
|
+
operation: "release configure",
|
|
12528
|
+
approvals: [{
|
|
12529
|
+
type: "minter",
|
|
12530
|
+
approvalTxHash,
|
|
12531
|
+
target: plan.contract,
|
|
12532
|
+
minter: rareMinter
|
|
12533
|
+
}],
|
|
12534
|
+
run: async () => {
|
|
12535
|
+
await assertReleaseMinterCanMint({
|
|
12536
|
+
publicClient,
|
|
12537
|
+
contract: plan.contract,
|
|
12538
|
+
accountAddress,
|
|
12539
|
+
rareMinter
|
|
12540
|
+
});
|
|
12541
|
+
const configureTxHash = await walletClient.writeContract({
|
|
12542
|
+
address: rareMinter,
|
|
12543
|
+
abi: rareMinterAbi,
|
|
12544
|
+
functionName: "prepareMintDirectSale",
|
|
12545
|
+
args: [
|
|
12546
|
+
plan.contract,
|
|
12547
|
+
plan.currencyAddress,
|
|
12548
|
+
plan.price,
|
|
12549
|
+
plan.startTime,
|
|
12550
|
+
plan.maxMints,
|
|
12551
|
+
plan.splitRecipients,
|
|
12552
|
+
plan.splitRatios
|
|
12553
|
+
],
|
|
12554
|
+
account,
|
|
12555
|
+
chain: void 0
|
|
12556
|
+
});
|
|
12557
|
+
const configureReceipt = await publicClient.waitForTransactionReceipt({ hash: configureTxHash });
|
|
12558
|
+
return { txHash: configureTxHash, receipt: configureReceipt };
|
|
12559
|
+
}
|
|
11829
12560
|
});
|
|
11830
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
11831
12561
|
return {
|
|
11832
12562
|
txHash,
|
|
11833
12563
|
receipt,
|
|
@@ -11876,26 +12606,38 @@ function createReleaseNamespace(publicClient, config, chain, addresses) {
|
|
|
11876
12606
|
amount: mint.totalPrice,
|
|
11877
12607
|
autoApprove: plan.autoApprove
|
|
11878
12608
|
});
|
|
11879
|
-
const txHash = await
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
mint.
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
12609
|
+
const { txHash, receipt, tokenRange } = await runWithApprovalSideEffectAlert({
|
|
12610
|
+
operation: "release mint",
|
|
12611
|
+
approvals: [{
|
|
12612
|
+
type: "erc20",
|
|
12613
|
+
approvalTxHash: payment.approvalTxHash,
|
|
12614
|
+
target: mint.currency,
|
|
12615
|
+
spender: rareMinter
|
|
12616
|
+
}],
|
|
12617
|
+
run: async () => {
|
|
12618
|
+
const targetTxHash = await walletClient.writeContract({
|
|
12619
|
+
address: rareMinter,
|
|
12620
|
+
abi: rareMinterAbi,
|
|
12621
|
+
functionName: "mintDirectSale",
|
|
12622
|
+
args: [
|
|
12623
|
+
mint.contract,
|
|
12624
|
+
mint.currency,
|
|
12625
|
+
mint.price,
|
|
12626
|
+
mint.quantity,
|
|
12627
|
+
mint.proof
|
|
12628
|
+
],
|
|
12629
|
+
account,
|
|
12630
|
+
chain: void 0,
|
|
12631
|
+
value: payment.value
|
|
12632
|
+
});
|
|
12633
|
+
const targetReceipt = await publicClient.waitForTransactionReceipt({ hash: targetTxHash });
|
|
12634
|
+
const mintedTokenRange = readMintDirectSaleTokenRange({
|
|
12635
|
+
receipt: targetReceipt,
|
|
12636
|
+
contract: mint.contract,
|
|
12637
|
+
buyer: accountAddress
|
|
12638
|
+
});
|
|
12639
|
+
return { txHash: targetTxHash, receipt: targetReceipt, tokenRange: mintedTokenRange };
|
|
12640
|
+
}
|
|
11899
12641
|
});
|
|
11900
12642
|
return {
|
|
11901
12643
|
txHash,
|
|
@@ -12971,10 +13713,14 @@ function addressLeaf(address) {
|
|
|
12971
13713
|
return hexBuffer(keccak2563(address));
|
|
12972
13714
|
}
|
|
12973
13715
|
function parseBytes32(value, field) {
|
|
12974
|
-
if (!isHex5(value) || value.length !== 66) {
|
|
13716
|
+
if (!isHex5(value, { strict: true }) || value.length !== 66) {
|
|
12975
13717
|
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
12976
13718
|
}
|
|
12977
|
-
|
|
13719
|
+
const normalized = value.toLowerCase();
|
|
13720
|
+
if (!isHex5(normalized, { strict: true }) || normalized.length !== 66) {
|
|
13721
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
13722
|
+
}
|
|
13723
|
+
return normalized;
|
|
12978
13724
|
}
|
|
12979
13725
|
function parseBytes32Array(values, field) {
|
|
12980
13726
|
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
@@ -13050,14 +13796,15 @@ function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
|
13050
13796
|
const { tree, root } = buildBatchListingTree(
|
|
13051
13797
|
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
13052
13798
|
);
|
|
13053
|
-
|
|
13799
|
+
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
13800
|
+
if (root !== artifactRoot) {
|
|
13054
13801
|
throw new Error(
|
|
13055
13802
|
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
13056
13803
|
);
|
|
13057
13804
|
}
|
|
13058
13805
|
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
13059
13806
|
return {
|
|
13060
|
-
root:
|
|
13807
|
+
root: artifactRoot,
|
|
13061
13808
|
contract: contractChecksum,
|
|
13062
13809
|
tokenId: tokenIdBig.toString(),
|
|
13063
13810
|
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
@@ -13078,7 +13825,8 @@ function buildAllowListProofFields(artifact, buyer) {
|
|
|
13078
13825
|
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
13079
13826
|
}
|
|
13080
13827
|
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
13081
|
-
|
|
13828
|
+
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
13829
|
+
if (root !== artifactAllowListRoot) {
|
|
13082
13830
|
throw new Error(
|
|
13083
13831
|
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
13084
13832
|
);
|
|
@@ -13179,6 +13927,7 @@ function createRareClient(config) {
|
|
|
13179
13927
|
contracts: {
|
|
13180
13928
|
factory: addresses.factory,
|
|
13181
13929
|
auction: addresses.auction,
|
|
13930
|
+
rareBridge: addresses.rareBridge,
|
|
13182
13931
|
sovereignFactory: addresses.sovereignFactory,
|
|
13183
13932
|
lazySovereignFactory: addresses.lazySovereignFactory,
|
|
13184
13933
|
rareMinter: addresses.rareMinter,
|
|
@@ -13194,6 +13943,7 @@ function createRareClient(config) {
|
|
|
13194
13943
|
v4Quoter: addresses.v4Quoter
|
|
13195
13944
|
},
|
|
13196
13945
|
liquidEdition: createLiquidNamespace(config, chain, addresses),
|
|
13946
|
+
bridge: createBridgeNamespace(publicClient, config, chain),
|
|
13197
13947
|
swap: createSwapNamespace(config, chain, chainId, addresses),
|
|
13198
13948
|
auction,
|
|
13199
13949
|
offer,
|
|
@@ -13277,6 +14027,7 @@ function isRecord5(value) {
|
|
|
13277
14027
|
return typeof value === "object" && value !== null;
|
|
13278
14028
|
}
|
|
13279
14029
|
export {
|
|
14030
|
+
ApprovalSideEffectError,
|
|
13280
14031
|
NftApprovalRequiredError,
|
|
13281
14032
|
PaymentApprovalRequiredError,
|
|
13282
14033
|
createRareClient
|