@rareprotocol/rare-cli 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -10
- package/dist/client.js +205 -203
- package/dist/index.js +459 -300
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -4749,7 +4749,7 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
4749
4749
|
}
|
|
4750
4750
|
|
|
4751
4751
|
// src/sdk/batch-listing.ts
|
|
4752
|
-
import { isAddressEqual as
|
|
4752
|
+
import { isAddressEqual as isAddressEqual10 } from "viem";
|
|
4753
4753
|
|
|
4754
4754
|
// src/contracts/abis/batch-listing.ts
|
|
4755
4755
|
var batchListingAbi = [
|
|
@@ -5454,10 +5454,158 @@ function uniqueRoots(roots) {
|
|
|
5454
5454
|
}
|
|
5455
5455
|
|
|
5456
5456
|
// src/sdk/batch-listing-core.ts
|
|
5457
|
-
import { isAddressEqual as
|
|
5457
|
+
import { isAddressEqual as isAddressEqual9 } from "viem";
|
|
5458
|
+
|
|
5459
|
+
// src/sdk/merkle-core.ts
|
|
5460
|
+
import { Buffer } from "buffer";
|
|
5461
|
+
import { MerkleTree } from "merkletreejs";
|
|
5462
|
+
import {
|
|
5463
|
+
encodePacked as encodePacked2,
|
|
5464
|
+
getAddress as getAddress6,
|
|
5465
|
+
isAddress as isAddress5,
|
|
5466
|
+
isAddressEqual as isAddressEqual8,
|
|
5467
|
+
isHex as isHex3,
|
|
5468
|
+
keccak256 as keccak2562
|
|
5469
|
+
} from "viem";
|
|
5470
|
+
function hexBuffer(hex) {
|
|
5471
|
+
return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
|
|
5472
|
+
}
|
|
5473
|
+
function tokenLeaf(contract, tokenId) {
|
|
5474
|
+
const packed = encodePacked2(["address", "uint256"], [contract, tokenId]);
|
|
5475
|
+
return hexBuffer(keccak2562(packed));
|
|
5476
|
+
}
|
|
5477
|
+
function addressLeaf(address) {
|
|
5478
|
+
return hexBuffer(keccak2562(address));
|
|
5479
|
+
}
|
|
5480
|
+
function parseBytes32(value, field) {
|
|
5481
|
+
if (!isHex3(value, { strict: true }) || value.length !== 66) {
|
|
5482
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
5483
|
+
}
|
|
5484
|
+
const normalized = value.toLowerCase();
|
|
5485
|
+
if (!isHex3(normalized, { strict: true }) || normalized.length !== 66) {
|
|
5486
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
5487
|
+
}
|
|
5488
|
+
return normalized;
|
|
5489
|
+
}
|
|
5490
|
+
function parseBytes32Array(values, field) {
|
|
5491
|
+
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
5492
|
+
}
|
|
5493
|
+
function compareTokenEntries(a, b) {
|
|
5494
|
+
if (!isAddressEqual8(a.contract, b.contract)) {
|
|
5495
|
+
return a.contract.localeCompare(b.contract);
|
|
5496
|
+
}
|
|
5497
|
+
return a.tokenId.localeCompare(b.tokenId);
|
|
5498
|
+
}
|
|
5499
|
+
function normalizeTokenEntry(token) {
|
|
5500
|
+
if (!isAddress5(token.contract)) {
|
|
5501
|
+
throw new Error(`Invalid token contract address: ${token.contract}`);
|
|
5502
|
+
}
|
|
5503
|
+
return {
|
|
5504
|
+
contract: getAddress6(token.contract),
|
|
5505
|
+
tokenId: String(token.tokenId),
|
|
5506
|
+
tokenIdBigInt: toInteger(token.tokenId, "tokenId")
|
|
5507
|
+
};
|
|
5508
|
+
}
|
|
5509
|
+
function buildBatchListingTree(tokens) {
|
|
5510
|
+
if (tokens.length < 2) {
|
|
5511
|
+
throw new Error("buildBatchListingTree requires at least two tokens");
|
|
5512
|
+
}
|
|
5513
|
+
const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
|
|
5514
|
+
const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
|
|
5515
|
+
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
|
|
5516
|
+
sortPairs: true
|
|
5517
|
+
});
|
|
5518
|
+
return {
|
|
5519
|
+
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
5520
|
+
tree,
|
|
5521
|
+
sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
|
|
5522
|
+
};
|
|
5523
|
+
}
|
|
5524
|
+
function buildAllowListTree(addresses) {
|
|
5525
|
+
if (addresses.length < 2) {
|
|
5526
|
+
throw new Error("buildAllowListTree requires at least two addresses");
|
|
5527
|
+
}
|
|
5528
|
+
const sorted = addresses.map((address) => {
|
|
5529
|
+
if (!isAddress5(address)) throw new Error(`Invalid allowlist address: ${address}`);
|
|
5530
|
+
return getAddress6(address);
|
|
5531
|
+
}).sort((a, b) => a.localeCompare(b));
|
|
5532
|
+
const leaves = sorted.map(addressLeaf);
|
|
5533
|
+
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
|
|
5534
|
+
sortPairs: true
|
|
5535
|
+
});
|
|
5536
|
+
return {
|
|
5537
|
+
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
5538
|
+
tree,
|
|
5539
|
+
sortedAddresses: sorted
|
|
5540
|
+
};
|
|
5541
|
+
}
|
|
5542
|
+
function getTokenProof(tree, contract, tokenId) {
|
|
5543
|
+
const leaf = tokenLeaf(getAddress6(contract), tokenId);
|
|
5544
|
+
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
5545
|
+
}
|
|
5546
|
+
function getAddressProof(tree, address) {
|
|
5547
|
+
const leaf = addressLeaf(getAddress6(address));
|
|
5548
|
+
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
5549
|
+
}
|
|
5550
|
+
function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
5551
|
+
const tokenIdBig = toInteger(tokenId, "tokenId");
|
|
5552
|
+
const contractChecksum = getAddress6(contract);
|
|
5553
|
+
const found = artifact.tokens.find(
|
|
5554
|
+
(token) => isAddressEqual8(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
|
|
5555
|
+
);
|
|
5556
|
+
if (found === void 0) {
|
|
5557
|
+
throw new Error(
|
|
5558
|
+
`Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
|
|
5559
|
+
);
|
|
5560
|
+
}
|
|
5561
|
+
const { tree, root } = buildBatchListingTree(
|
|
5562
|
+
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
5563
|
+
);
|
|
5564
|
+
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
5565
|
+
if (root !== artifactRoot) {
|
|
5566
|
+
throw new Error(
|
|
5567
|
+
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
5568
|
+
);
|
|
5569
|
+
}
|
|
5570
|
+
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
5571
|
+
return {
|
|
5572
|
+
root: artifactRoot,
|
|
5573
|
+
contract: contractChecksum,
|
|
5574
|
+
tokenId: tokenIdBig.toString(),
|
|
5575
|
+
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
5576
|
+
...allowListProofFields ?? {}
|
|
5577
|
+
};
|
|
5578
|
+
}
|
|
5579
|
+
function buildAllowListProofFields(artifact, buyer) {
|
|
5580
|
+
if (artifact.allowList === void 0) return void 0;
|
|
5581
|
+
if (buyer === void 0) {
|
|
5582
|
+
throw new Error(
|
|
5583
|
+
"This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
|
|
5584
|
+
);
|
|
5585
|
+
}
|
|
5586
|
+
if (!isAddress5(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
|
|
5587
|
+
const buyerChecksum = getAddress6(buyer);
|
|
5588
|
+
const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual8(address, buyerChecksum));
|
|
5589
|
+
if (!inAllowList) {
|
|
5590
|
+
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
5591
|
+
}
|
|
5592
|
+
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
5593
|
+
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
5594
|
+
if (root !== artifactAllowListRoot) {
|
|
5595
|
+
throw new Error(
|
|
5596
|
+
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
5597
|
+
);
|
|
5598
|
+
}
|
|
5599
|
+
return {
|
|
5600
|
+
allowListProof: getAddressProof(tree, buyerChecksum),
|
|
5601
|
+
allowListAddress: buyerChecksum
|
|
5602
|
+
};
|
|
5603
|
+
}
|
|
5604
|
+
|
|
5605
|
+
// src/sdk/batch-listing-core.ts
|
|
5458
5606
|
function uniqueAddresses(addresses) {
|
|
5459
5607
|
return addresses.reduce(
|
|
5460
|
-
(unique, address) => unique.some((existing) =>
|
|
5608
|
+
(unique, address) => unique.some((existing) => isAddressEqual9(existing, address)) ? unique : [...unique, address],
|
|
5461
5609
|
[]
|
|
5462
5610
|
);
|
|
5463
5611
|
}
|
|
@@ -5501,7 +5649,7 @@ function shapeBatchListingStatus(params) {
|
|
|
5501
5649
|
splitRecipients: [...params.listingConfig.splitRecipients],
|
|
5502
5650
|
splitRatios: [...params.listingConfig.splitRatios],
|
|
5503
5651
|
nonce: params.listingConfig.nonce,
|
|
5504
|
-
isEth:
|
|
5652
|
+
isEth: isAddressEqual9(params.listingConfig.currency, ETH_ADDRESS),
|
|
5505
5653
|
hasListing,
|
|
5506
5654
|
allowList: params.allowList,
|
|
5507
5655
|
...params.tokenStatus
|
|
@@ -5532,7 +5680,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
5532
5680
|
functionName: "ownerOf",
|
|
5533
5681
|
args: [BigInt(token.tokenId)]
|
|
5534
5682
|
});
|
|
5535
|
-
if (!
|
|
5683
|
+
if (!isAddressEqual10(owner, accountAddress)) {
|
|
5536
5684
|
throw new Error(
|
|
5537
5685
|
`Token ${token.contract}/${token.tokenId} is owned by ${owner}, not the configured account ${accountAddress}. Re-check the token set before registering this batch listing.`
|
|
5538
5686
|
);
|
|
@@ -5980,7 +6128,7 @@ async function readTokenStatus(publicClient, batchListingAddress, params) {
|
|
|
5980
6128
|
|
|
5981
6129
|
// src/sdk/batch-auction.ts
|
|
5982
6130
|
import {
|
|
5983
|
-
isAddressEqual as
|
|
6131
|
+
isAddressEqual as isAddressEqual12,
|
|
5984
6132
|
parseUnits as parseUnits3,
|
|
5985
6133
|
parseEventLogs as parseEventLogs3
|
|
5986
6134
|
} from "viem";
|
|
@@ -6212,7 +6360,7 @@ var batchAuctionHouseAbi = [
|
|
|
6212
6360
|
];
|
|
6213
6361
|
|
|
6214
6362
|
// src/sdk/batch-auction-core.ts
|
|
6215
|
-
import { isAddressEqual as
|
|
6363
|
+
import { isAddressEqual as isAddressEqual11 } from "viem";
|
|
6216
6364
|
var zeroAddress3 = ETH_ADDRESS;
|
|
6217
6365
|
var marketplaceFeePercentage = 3n;
|
|
6218
6366
|
function planBatchAuctionCreateLocalInputs(params, nowSeconds) {
|
|
@@ -6297,7 +6445,7 @@ function planBatchAuctionStatus(params) {
|
|
|
6297
6445
|
};
|
|
6298
6446
|
}
|
|
6299
6447
|
function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
6300
|
-
const hasAuction = details.startingTime > 0n && !
|
|
6448
|
+
const hasAuction = details.startingTime > 0n && !isAddressEqual11(details.seller, zeroAddress3);
|
|
6301
6449
|
const hasCurrentRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n && rootContext.rootNonce === rootContext.config.nonce;
|
|
6302
6450
|
const currentRootConfig = hasCurrentRootConfig ? rootContext.config : void 0;
|
|
6303
6451
|
const hasRootConfig = currentRootConfig !== void 0;
|
|
@@ -6305,7 +6453,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
6305
6453
|
const startingTime = hasAuction ? details.startingTime : 0n;
|
|
6306
6454
|
const endTime = hasAuction ? startingTime + duration : null;
|
|
6307
6455
|
const ended = endTime !== null && nowSeconds >= endTime;
|
|
6308
|
-
const currentBidder = currentBid.amount > 0n && !
|
|
6456
|
+
const currentBidder = currentBid.amount > 0n && !isAddressEqual11(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
|
|
6309
6457
|
const seller = hasAuction ? details.seller : rootContext?.creator ?? zeroAddress3;
|
|
6310
6458
|
const currency = hasAuction ? details.currency : currentRootConfig?.currency ?? ETH_ADDRESS;
|
|
6311
6459
|
const reserveAmount = hasAuction ? details.reserveAmount : currentRootConfig?.reserveAmount ?? 0n;
|
|
@@ -6340,7 +6488,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
6340
6488
|
hasRootConfig,
|
|
6341
6489
|
tokenNonceConsumed
|
|
6342
6490
|
}),
|
|
6343
|
-
isEth:
|
|
6491
|
+
isEth: isAddressEqual11(currency, ETH_ADDRESS)
|
|
6344
6492
|
};
|
|
6345
6493
|
}
|
|
6346
6494
|
function shapeBatchAuctionDetailsRead(details) {
|
|
@@ -6451,7 +6599,7 @@ function planSplitRecipients(splitAddresses, splitRatios, accountAddress) {
|
|
|
6451
6599
|
};
|
|
6452
6600
|
}
|
|
6453
6601
|
function uniqueAddresses2(addresses) {
|
|
6454
|
-
return addresses.reduce((unique, address) => unique.some((candidate) =>
|
|
6602
|
+
return addresses.reduce((unique, address) => unique.some((candidate) => isAddressEqual11(candidate, address)) ? unique : [...unique, address], []);
|
|
6455
6603
|
}
|
|
6456
6604
|
function addMinimumBidIncrease(amount) {
|
|
6457
6605
|
return amount + amount * marketplaceFeePercentage / 100n;
|
|
@@ -6625,7 +6773,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
6625
6773
|
const price = requireInput(resolvedParams.price, "price");
|
|
6626
6774
|
const amount = typeof price === "bigint" ? price : parseUnits3(stringifyAmountInput(price, "price"), await resolveCurrencyDecimals(publicClient, chain, currency));
|
|
6627
6775
|
const plan = planBatchAuctionBid({ ...resolvedParams, currency, price: amount });
|
|
6628
|
-
const erc20ApprovalManager =
|
|
6776
|
+
const erc20ApprovalManager = isAddressEqual12(plan.currency, ETH_ADDRESS) ? batchAuctionHouse : requireContractAddress(chain, "erc20ApprovalManager");
|
|
6629
6777
|
const payment = await preparePaymentAmountForSpender({
|
|
6630
6778
|
publicClient,
|
|
6631
6779
|
walletClient,
|
|
@@ -6984,7 +7132,7 @@ async function resolveRootContext(opts) {
|
|
|
6984
7132
|
|
|
6985
7133
|
// src/sdk/batch-offer.ts
|
|
6986
7134
|
import {
|
|
6987
|
-
isAddressEqual as
|
|
7135
|
+
isAddressEqual as isAddressEqual14,
|
|
6988
7136
|
parseUnits as parseUnits4,
|
|
6989
7137
|
parseEventLogs as parseEventLogs4
|
|
6990
7138
|
} from "viem";
|
|
@@ -7091,7 +7239,7 @@ var batchOfferAbi = [
|
|
|
7091
7239
|
];
|
|
7092
7240
|
|
|
7093
7241
|
// src/sdk/batch-offer-core.ts
|
|
7094
|
-
import { isAddressEqual as
|
|
7242
|
+
import { isAddressEqual as isAddressEqual13 } from "viem";
|
|
7095
7243
|
var zeroAddress4 = ETH_ADDRESS;
|
|
7096
7244
|
var zeroBytes322 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
7097
7245
|
function planBatchOfferCreateLocalInputs(params, nowSeconds) {
|
|
@@ -7148,7 +7296,7 @@ function planBatchOfferAccept(params, accountAddress) {
|
|
|
7148
7296
|
};
|
|
7149
7297
|
}
|
|
7150
7298
|
function shapeBatchOfferStatus(offer, expected, nowSeconds) {
|
|
7151
|
-
const hasOffer = !
|
|
7299
|
+
const hasOffer = !isAddressEqual13(offer.creator, zeroAddress4) && offer.rootHash !== zeroBytes322 && offer.amount > 0n;
|
|
7152
7300
|
const expired = hasOffer && offer.expiry <= nowSeconds;
|
|
7153
7301
|
const state = !hasOffer ? "NONE" : expired ? "EXPIRED" : "ACTIVE";
|
|
7154
7302
|
return {
|
|
@@ -7163,7 +7311,7 @@ function shapeBatchOfferStatus(offer, expected, nowSeconds) {
|
|
|
7163
7311
|
revoked: hasOffer ? false : null,
|
|
7164
7312
|
fillable: hasOffer && !expired,
|
|
7165
7313
|
state,
|
|
7166
|
-
isEth:
|
|
7314
|
+
isEth: isAddressEqual13(offer.currency, ETH_ADDRESS)
|
|
7167
7315
|
};
|
|
7168
7316
|
}
|
|
7169
7317
|
function shapeBatchOfferRead(value) {
|
|
@@ -7353,7 +7501,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
7353
7501
|
functionName: "ownerOf",
|
|
7354
7502
|
args: [plan.tokenId]
|
|
7355
7503
|
});
|
|
7356
|
-
if (!
|
|
7504
|
+
if (!isAddressEqual14(owner, accountAddress)) {
|
|
7357
7505
|
throw new Error(`Connected wallet ${accountAddress} does not own token ${plan.contract} #${plan.tokenId.toString()}.`);
|
|
7358
7506
|
}
|
|
7359
7507
|
const approvalTxHash = await approveNftContractIfNeeded({
|
|
@@ -9392,7 +9540,7 @@ var liquidRouterAbi = [
|
|
|
9392
9540
|
];
|
|
9393
9541
|
|
|
9394
9542
|
// src/swap/known-pools.ts
|
|
9395
|
-
import { getAddress as
|
|
9543
|
+
import { getAddress as getAddress7 } from "viem";
|
|
9396
9544
|
|
|
9397
9545
|
// src/swap/pool-core.ts
|
|
9398
9546
|
function normalizeAddress(value) {
|
|
@@ -9411,10 +9559,10 @@ function inferBaseCurrencyAddress(poolKey, token) {
|
|
|
9411
9559
|
|
|
9412
9560
|
// src/swap/known-pools.ts
|
|
9413
9561
|
var wrappedEthAddresses = {
|
|
9414
|
-
mainnet:
|
|
9415
|
-
sepolia:
|
|
9416
|
-
base:
|
|
9417
|
-
"base-sepolia":
|
|
9562
|
+
mainnet: getAddress7("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
|
|
9563
|
+
sepolia: getAddress7("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"),
|
|
9564
|
+
base: getAddress7("0x4200000000000000000000000000000000000006"),
|
|
9565
|
+
"base-sepolia": getAddress7("0x4200000000000000000000000000000000000006")
|
|
9418
9566
|
};
|
|
9419
9567
|
function poolToKey(pool) {
|
|
9420
9568
|
return {
|
|
@@ -9729,8 +9877,8 @@ async function quoteRouteSteps(publicClient, quoterAddress, routeSteps, currentA
|
|
|
9729
9877
|
// src/swap/route-encoding.ts
|
|
9730
9878
|
import {
|
|
9731
9879
|
encodeAbiParameters as encodeAbiParameters2,
|
|
9732
|
-
encodePacked as
|
|
9733
|
-
getAddress as
|
|
9880
|
+
encodePacked as encodePacked3,
|
|
9881
|
+
getAddress as getAddress8,
|
|
9734
9882
|
parseAbiParameters
|
|
9735
9883
|
} from "viem";
|
|
9736
9884
|
var ROUTER_COMMANDS = {
|
|
@@ -9747,8 +9895,8 @@ var V4_ACTIONS = {
|
|
|
9747
9895
|
TAKE_ALL: 15
|
|
9748
9896
|
};
|
|
9749
9897
|
var ROUTER_RECIPIENTS = {
|
|
9750
|
-
msgSender:
|
|
9751
|
-
addressThis:
|
|
9898
|
+
msgSender: getAddress8("0x0000000000000000000000000000000000000001"),
|
|
9899
|
+
addressThis: getAddress8("0x0000000000000000000000000000000000000002")
|
|
9752
9900
|
};
|
|
9753
9901
|
var ROUTER_AMOUNT_CONSTANTS = {
|
|
9754
9902
|
openDelta: 0n,
|
|
@@ -9760,7 +9908,7 @@ function encodeRoute(quote, amountIn, currencyIn, currencyOut) {
|
|
|
9760
9908
|
}
|
|
9761
9909
|
const { commandBytes, inputs } = encodeRouteParts(quote, amountIn, currencyIn, currencyOut, 0);
|
|
9762
9910
|
return {
|
|
9763
|
-
commands:
|
|
9911
|
+
commands: encodePacked3(commandBytes.map(() => "uint8"), [...commandBytes]),
|
|
9764
9912
|
inputs
|
|
9765
9913
|
};
|
|
9766
9914
|
}
|
|
@@ -9891,7 +10039,7 @@ function encodeV4ExactIn({
|
|
|
9891
10039
|
if (singleStep === void 0) {
|
|
9892
10040
|
throw new Error("Missing V4 exact input single step.");
|
|
9893
10041
|
}
|
|
9894
|
-
const actions2 =
|
|
10042
|
+
const actions2 = encodePacked3(
|
|
9895
10043
|
["uint8", "uint8", "uint8"],
|
|
9896
10044
|
[settleAction, V4_ACTIONS.SWAP_EXACT_IN_SINGLE, takeAction]
|
|
9897
10045
|
);
|
|
@@ -9907,7 +10055,7 @@ function encodeV4ExactIn({
|
|
|
9907
10055
|
]
|
|
9908
10056
|
);
|
|
9909
10057
|
}
|
|
9910
|
-
const actions =
|
|
10058
|
+
const actions = encodePacked3(
|
|
9911
10059
|
["uint8", "uint8", "uint8"],
|
|
9912
10060
|
[V4_ACTIONS.SWAP_EXACT_IN, settleAction, takeAction]
|
|
9913
10061
|
);
|
|
@@ -9937,10 +10085,10 @@ function encodeV4ExactInSingle(step, amountIn, minAmountOut) {
|
|
|
9937
10085
|
}
|
|
9938
10086
|
|
|
9939
10087
|
// src/swap/uniswap-api.ts
|
|
9940
|
-
import { getAddress as
|
|
10088
|
+
import { getAddress as getAddress9, isHex as isHex4 } from "viem";
|
|
9941
10089
|
|
|
9942
10090
|
// src/swap/trade-core.ts
|
|
9943
|
-
import { isAddressEqual as
|
|
10091
|
+
import { isAddressEqual as isAddressEqual15 } from "viem";
|
|
9944
10092
|
function toTradeInteger(value, field) {
|
|
9945
10093
|
if (typeof value === "bigint") return value;
|
|
9946
10094
|
if (typeof value === "number") {
|
|
@@ -10008,7 +10156,7 @@ function buildLiquidRouterTradeQuote(params) {
|
|
|
10008
10156
|
}
|
|
10009
10157
|
function getQuotedRecipientAmount(quote, recipient) {
|
|
10010
10158
|
const recipientOutput = quote.aggregatedOutputs?.find(
|
|
10011
|
-
(output) =>
|
|
10159
|
+
(output) => isAddressEqual15(output.recipient, recipient)
|
|
10012
10160
|
);
|
|
10013
10161
|
if (recipientOutput) {
|
|
10014
10162
|
return {
|
|
@@ -10027,7 +10175,7 @@ function assertSupportedUniswapRouting(routing) {
|
|
|
10027
10175
|
}
|
|
10028
10176
|
}
|
|
10029
10177
|
function assertRecipientSupportedForUniswapFallback(recipient, accountAddress) {
|
|
10030
|
-
if (recipient !== void 0 && !
|
|
10178
|
+
if (recipient !== void 0 && !isAddressEqual15(recipient, accountAddress)) {
|
|
10031
10179
|
throw new Error("recipient override is not supported for Uniswap API fallback routes.");
|
|
10032
10180
|
}
|
|
10033
10181
|
}
|
|
@@ -10107,7 +10255,7 @@ function parseNumber(value, field) {
|
|
|
10107
10255
|
function parseAddress2(value, field) {
|
|
10108
10256
|
const raw = parseString(value, field);
|
|
10109
10257
|
try {
|
|
10110
|
-
return
|
|
10258
|
+
return getAddress9(raw);
|
|
10111
10259
|
} catch {
|
|
10112
10260
|
throw new Error(`Uniswap API response field "${field}" must be a valid EVM address.`);
|
|
10113
10261
|
}
|
|
@@ -10117,7 +10265,7 @@ function parseOptionalAddress(value, field) {
|
|
|
10117
10265
|
}
|
|
10118
10266
|
function parseHex(value, field) {
|
|
10119
10267
|
const raw = parseString(value, field);
|
|
10120
|
-
if (!
|
|
10268
|
+
if (!isHex4(raw)) {
|
|
10121
10269
|
throw new Error(`Uniswap API response field "${field}" must be a hex string.`);
|
|
10122
10270
|
}
|
|
10123
10271
|
return raw;
|
|
@@ -10969,7 +11117,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
10969
11117
|
import {
|
|
10970
11118
|
erc20Abi as erc20Abi2,
|
|
10971
11119
|
hexToBigInt as hexToBigInt2,
|
|
10972
|
-
isAddressEqual as
|
|
11120
|
+
isAddressEqual as isAddressEqual17,
|
|
10973
11121
|
parseEventLogs as parseEventLogs6
|
|
10974
11122
|
} from "viem";
|
|
10975
11123
|
|
|
@@ -11474,11 +11622,11 @@ function toRoyaltyPercentage(value) {
|
|
|
11474
11622
|
|
|
11475
11623
|
// src/sdk/release-core.ts
|
|
11476
11624
|
import {
|
|
11477
|
-
getAddress as
|
|
11478
|
-
isAddress as
|
|
11479
|
-
isAddressEqual as
|
|
11480
|
-
isHex as
|
|
11481
|
-
keccak256 as
|
|
11625
|
+
getAddress as getAddress10,
|
|
11626
|
+
isAddress as isAddress6,
|
|
11627
|
+
isAddressEqual as isAddressEqual16,
|
|
11628
|
+
isHex as isHex5,
|
|
11629
|
+
keccak256 as keccak2563,
|
|
11482
11630
|
parseEther as parseEther2,
|
|
11483
11631
|
parseUnits as parseUnits7
|
|
11484
11632
|
} from "viem";
|
|
@@ -11495,7 +11643,7 @@ function requireRareMinterAddress(address) {
|
|
|
11495
11643
|
}
|
|
11496
11644
|
function assertReleaseContractOwner(opts) {
|
|
11497
11645
|
const { contract, accountAddress, owner } = opts;
|
|
11498
|
-
if (!
|
|
11646
|
+
if (!isAddressEqual16(owner, accountAddress)) {
|
|
11499
11647
|
throw new Error(
|
|
11500
11648
|
`Connected wallet ${accountAddress} is not the owner of collection ${contract}. Contract owner is ${owner}.`
|
|
11501
11649
|
);
|
|
@@ -11684,7 +11832,7 @@ function parseReleaseAllowlistCsv(input) {
|
|
|
11684
11832
|
throw new Error("CSV allowlist is empty.");
|
|
11685
11833
|
}
|
|
11686
11834
|
const headerColumn = findAllowlistAddressColumn(firstRow.fields);
|
|
11687
|
-
if (headerColumn === -1 && !
|
|
11835
|
+
if (headerColumn === -1 && !isAddress6(firstRow.fields[0]?.trim() ?? "")) {
|
|
11688
11836
|
throw new Error("CSV allowlist must put wallet addresses in the first column or include an address/wallet header.");
|
|
11689
11837
|
}
|
|
11690
11838
|
const addressColumn = headerColumn === -1 ? 0 : headerColumn;
|
|
@@ -11743,27 +11891,27 @@ function buildReleaseAllowlistArtifact(wallets) {
|
|
|
11743
11891
|
};
|
|
11744
11892
|
}
|
|
11745
11893
|
function getReleaseAllowlistProof(opts) {
|
|
11746
|
-
const address =
|
|
11894
|
+
const address = getAddress10(opts.address);
|
|
11747
11895
|
return opts.artifact.wallets.find((entry) => addressesEqual(entry.address, address)) ?? null;
|
|
11748
11896
|
}
|
|
11749
11897
|
function verifyReleaseAllowlistProof(opts) {
|
|
11750
11898
|
const root = normalizeBytes322(opts.root, "allowlist root");
|
|
11751
11899
|
const hash = opts.proof.reduce(
|
|
11752
11900
|
(current, sibling) => hashMerklePair(current, normalizeBytes322(sibling, "allowlist proof item")),
|
|
11753
|
-
hashAllowlistAddress(
|
|
11901
|
+
hashAllowlistAddress(getAddress10(opts.address))
|
|
11754
11902
|
);
|
|
11755
11903
|
return hexEquals(hash, root);
|
|
11756
11904
|
}
|
|
11757
11905
|
function preflightReleaseDirectSaleMint(params) {
|
|
11758
11906
|
const { status, plan, buyer, nowSeconds } = params;
|
|
11759
11907
|
const quantity = BigInt(plan.quantity);
|
|
11760
|
-
if (!
|
|
11908
|
+
if (!isAddressEqual16(status.contract, plan.contract)) {
|
|
11761
11909
|
throw new Error(`Release status is for ${status.contract}, but mint plan is for ${plan.contract}.`);
|
|
11762
11910
|
}
|
|
11763
11911
|
if (!status.configured) {
|
|
11764
11912
|
throw new Error("RareMinter direct sale is not configured for this contract.");
|
|
11765
11913
|
}
|
|
11766
|
-
if (plan.recipient !== void 0 && !
|
|
11914
|
+
if (plan.recipient !== void 0 && !isAddressEqual16(plan.recipient, buyer)) {
|
|
11767
11915
|
throw new Error("RareMinter direct sale mint does not support a separate recipient; it mints to the connected wallet.");
|
|
11768
11916
|
}
|
|
11769
11917
|
if (status.startTime > nowSeconds) {
|
|
@@ -11787,7 +11935,7 @@ function preflightReleaseDirectSaleMint(params) {
|
|
|
11787
11935
|
throw new Error("buyer has reached the per-wallet transaction limit.");
|
|
11788
11936
|
}
|
|
11789
11937
|
}
|
|
11790
|
-
if (plan.currency !== void 0 && !
|
|
11938
|
+
if (plan.currency !== void 0 && !isAddressEqual16(plan.currency, status.currencyAddress)) {
|
|
11791
11939
|
throw new Error(`expected currency ${plan.currency} does not match configured currency ${status.currencyAddress}.`);
|
|
11792
11940
|
}
|
|
11793
11941
|
const price = plan.price === void 0 ? status.price : normalizeReleasePrice({
|
|
@@ -11921,11 +12069,11 @@ function requireReleaseAccountCounter(value, label) {
|
|
|
11921
12069
|
return value;
|
|
11922
12070
|
}
|
|
11923
12071
|
function normalizeBytes322(value, field) {
|
|
11924
|
-
if (typeof value !== "string" || !
|
|
12072
|
+
if (typeof value !== "string" || !isHex5(value) || value.length !== 66) {
|
|
11925
12073
|
throw new Error(`${field} must be a 32-byte hex string.`);
|
|
11926
12074
|
}
|
|
11927
12075
|
const normalized = value.toLocaleLowerCase();
|
|
11928
|
-
if (!
|
|
12076
|
+
if (!isHex5(normalized) || normalized.length !== 66) {
|
|
11929
12077
|
throw new Error(`${field} must be a 32-byte hex string.`);
|
|
11930
12078
|
}
|
|
11931
12079
|
return normalized;
|
|
@@ -11995,11 +12143,11 @@ function normalizeAllowlistRows(rows) {
|
|
|
11995
12143
|
throw new Error(`Invalid allowlist address at ${row.label}: expected a string.`);
|
|
11996
12144
|
}
|
|
11997
12145
|
const raw = row.value.trim();
|
|
11998
|
-
if (!
|
|
12146
|
+
if (!isAddress6(raw)) {
|
|
11999
12147
|
throw new Error(`Invalid allowlist address at ${row.label}: "${raw}".`);
|
|
12000
12148
|
}
|
|
12001
|
-
const address =
|
|
12002
|
-
const duplicate = state.seen.find((seen) =>
|
|
12149
|
+
const address = getAddress10(raw);
|
|
12150
|
+
const duplicate = state.seen.find((seen) => isAddressEqual16(seen.address, address));
|
|
12003
12151
|
if (duplicate !== void 0) {
|
|
12004
12152
|
throw new Error(`Duplicate allowlist address at ${row.label}: "${address}" duplicates ${duplicate.label}.`);
|
|
12005
12153
|
}
|
|
@@ -12055,11 +12203,11 @@ function getMerkleRoot(layers) {
|
|
|
12055
12203
|
return root;
|
|
12056
12204
|
}
|
|
12057
12205
|
function hashAllowlistAddress(address) {
|
|
12058
|
-
return
|
|
12206
|
+
return keccak2563(address);
|
|
12059
12207
|
}
|
|
12060
12208
|
function hashMerklePair(a, b) {
|
|
12061
12209
|
const [left, right] = compareHex(a, b) <= 0 ? [a, b] : [b, a];
|
|
12062
|
-
return
|
|
12210
|
+
return keccak2563(`0x${left.slice(2)}${right.slice(2)}`);
|
|
12063
12211
|
}
|
|
12064
12212
|
function compareAddress(a, b) {
|
|
12065
12213
|
return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
|
|
@@ -12068,7 +12216,7 @@ function compareHex(a, b) {
|
|
|
12068
12216
|
return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
|
|
12069
12217
|
}
|
|
12070
12218
|
function addressesEqual(a, b) {
|
|
12071
|
-
return
|
|
12219
|
+
return isAddressEqual16(a, b);
|
|
12072
12220
|
}
|
|
12073
12221
|
function hexEquals(a, b) {
|
|
12074
12222
|
return a.toLocaleLowerCase() === b.toLocaleLowerCase();
|
|
@@ -12323,7 +12471,7 @@ function readMintDirectSaleTokenRange(opts) {
|
|
|
12323
12471
|
eventName: "MintDirectSale",
|
|
12324
12472
|
logs: opts.receipt.logs
|
|
12325
12473
|
}).filter(
|
|
12326
|
-
(log) =>
|
|
12474
|
+
(log) => isAddressEqual17(log.args._contractAddress, opts.contract) && isAddressEqual17(log.args._buyer, opts.buyer)
|
|
12327
12475
|
);
|
|
12328
12476
|
if (event === void 0) {
|
|
12329
12477
|
throw new Error(`MintDirectSale event was not found for ${opts.contract} and buyer ${opts.buyer}.`);
|
|
@@ -13691,152 +13839,6 @@ function contractSupportError(operation, contract, cause) {
|
|
|
13691
13839
|
);
|
|
13692
13840
|
}
|
|
13693
13841
|
|
|
13694
|
-
// src/sdk/merkle-core.ts
|
|
13695
|
-
import { Buffer } from "buffer";
|
|
13696
|
-
import { MerkleTree } from "merkletreejs";
|
|
13697
|
-
import {
|
|
13698
|
-
encodePacked as encodePacked3,
|
|
13699
|
-
getAddress as getAddress10,
|
|
13700
|
-
isAddress as isAddress6,
|
|
13701
|
-
isAddressEqual as isAddressEqual17,
|
|
13702
|
-
isHex as isHex5,
|
|
13703
|
-
keccak256 as keccak2563
|
|
13704
|
-
} from "viem";
|
|
13705
|
-
function hexBuffer(hex) {
|
|
13706
|
-
return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
|
|
13707
|
-
}
|
|
13708
|
-
function tokenLeaf(contract, tokenId) {
|
|
13709
|
-
const packed = encodePacked3(["address", "uint256"], [contract, tokenId]);
|
|
13710
|
-
return hexBuffer(keccak2563(packed));
|
|
13711
|
-
}
|
|
13712
|
-
function addressLeaf(address) {
|
|
13713
|
-
return hexBuffer(keccak2563(address));
|
|
13714
|
-
}
|
|
13715
|
-
function parseBytes32(value, field) {
|
|
13716
|
-
if (!isHex5(value, { strict: true }) || value.length !== 66) {
|
|
13717
|
-
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
13718
|
-
}
|
|
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;
|
|
13724
|
-
}
|
|
13725
|
-
function parseBytes32Array(values, field) {
|
|
13726
|
-
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
13727
|
-
}
|
|
13728
|
-
function compareTokenEntries(a, b) {
|
|
13729
|
-
if (!isAddressEqual17(a.contract, b.contract)) {
|
|
13730
|
-
return a.contract.localeCompare(b.contract);
|
|
13731
|
-
}
|
|
13732
|
-
return a.tokenId.localeCompare(b.tokenId);
|
|
13733
|
-
}
|
|
13734
|
-
function normalizeTokenEntry(token) {
|
|
13735
|
-
if (!isAddress6(token.contract)) {
|
|
13736
|
-
throw new Error(`Invalid token contract address: ${token.contract}`);
|
|
13737
|
-
}
|
|
13738
|
-
return {
|
|
13739
|
-
contract: getAddress10(token.contract),
|
|
13740
|
-
tokenId: String(token.tokenId),
|
|
13741
|
-
tokenIdBigInt: toInteger(token.tokenId, "tokenId")
|
|
13742
|
-
};
|
|
13743
|
-
}
|
|
13744
|
-
function buildBatchListingTree(tokens) {
|
|
13745
|
-
if (tokens.length < 2) {
|
|
13746
|
-
throw new Error("buildBatchListingTree requires at least two tokens");
|
|
13747
|
-
}
|
|
13748
|
-
const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
|
|
13749
|
-
const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
|
|
13750
|
-
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2563(data)), {
|
|
13751
|
-
sortPairs: true
|
|
13752
|
-
});
|
|
13753
|
-
return {
|
|
13754
|
-
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
13755
|
-
tree,
|
|
13756
|
-
sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
|
|
13757
|
-
};
|
|
13758
|
-
}
|
|
13759
|
-
function buildAllowListTree(addresses) {
|
|
13760
|
-
if (addresses.length < 2) {
|
|
13761
|
-
throw new Error("buildAllowListTree requires at least two addresses");
|
|
13762
|
-
}
|
|
13763
|
-
const sorted = addresses.map((address) => {
|
|
13764
|
-
if (!isAddress6(address)) throw new Error(`Invalid allowlist address: ${address}`);
|
|
13765
|
-
return getAddress10(address);
|
|
13766
|
-
}).sort((a, b) => a.localeCompare(b));
|
|
13767
|
-
const leaves = sorted.map(addressLeaf);
|
|
13768
|
-
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2563(data)), {
|
|
13769
|
-
sortPairs: true
|
|
13770
|
-
});
|
|
13771
|
-
return {
|
|
13772
|
-
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
13773
|
-
tree,
|
|
13774
|
-
sortedAddresses: sorted
|
|
13775
|
-
};
|
|
13776
|
-
}
|
|
13777
|
-
function getTokenProof(tree, contract, tokenId) {
|
|
13778
|
-
const leaf = tokenLeaf(getAddress10(contract), tokenId);
|
|
13779
|
-
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
13780
|
-
}
|
|
13781
|
-
function getAddressProof(tree, address) {
|
|
13782
|
-
const leaf = addressLeaf(getAddress10(address));
|
|
13783
|
-
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
13784
|
-
}
|
|
13785
|
-
function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
13786
|
-
const tokenIdBig = toInteger(tokenId, "tokenId");
|
|
13787
|
-
const contractChecksum = getAddress10(contract);
|
|
13788
|
-
const found = artifact.tokens.find(
|
|
13789
|
-
(token) => isAddressEqual17(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
|
|
13790
|
-
);
|
|
13791
|
-
if (found === void 0) {
|
|
13792
|
-
throw new Error(
|
|
13793
|
-
`Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
|
|
13794
|
-
);
|
|
13795
|
-
}
|
|
13796
|
-
const { tree, root } = buildBatchListingTree(
|
|
13797
|
-
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
13798
|
-
);
|
|
13799
|
-
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
13800
|
-
if (root !== artifactRoot) {
|
|
13801
|
-
throw new Error(
|
|
13802
|
-
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
13803
|
-
);
|
|
13804
|
-
}
|
|
13805
|
-
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
13806
|
-
return {
|
|
13807
|
-
root: artifactRoot,
|
|
13808
|
-
contract: contractChecksum,
|
|
13809
|
-
tokenId: tokenIdBig.toString(),
|
|
13810
|
-
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
13811
|
-
...allowListProofFields ?? {}
|
|
13812
|
-
};
|
|
13813
|
-
}
|
|
13814
|
-
function buildAllowListProofFields(artifact, buyer) {
|
|
13815
|
-
if (artifact.allowList === void 0) return void 0;
|
|
13816
|
-
if (buyer === void 0) {
|
|
13817
|
-
throw new Error(
|
|
13818
|
-
"This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
|
|
13819
|
-
);
|
|
13820
|
-
}
|
|
13821
|
-
if (!isAddress6(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
|
|
13822
|
-
const buyerChecksum = getAddress10(buyer);
|
|
13823
|
-
const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual17(address, buyerChecksum));
|
|
13824
|
-
if (!inAllowList) {
|
|
13825
|
-
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
13826
|
-
}
|
|
13827
|
-
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
13828
|
-
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
13829
|
-
if (root !== artifactAllowListRoot) {
|
|
13830
|
-
throw new Error(
|
|
13831
|
-
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
13832
|
-
);
|
|
13833
|
-
}
|
|
13834
|
-
return {
|
|
13835
|
-
allowListProof: getAddressProof(tree, buyerChecksum),
|
|
13836
|
-
allowListAddress: buyerChecksum
|
|
13837
|
-
};
|
|
13838
|
-
}
|
|
13839
|
-
|
|
13840
13842
|
// src/sdk/utils.ts
|
|
13841
13843
|
function createUtilsNamespace() {
|
|
13842
13844
|
return {
|