@rareprotocol/rare-cli 1.2.0 → 1.2.2
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 +213 -205
- package/dist/contracts.js +11 -5
- package/dist/index.js +467 -302
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -374,12 +374,18 @@ var contractAddresses = {
|
|
|
374
374
|
base: {
|
|
375
375
|
factory: getAddress("0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd"),
|
|
376
376
|
auction: getAddress("0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2"),
|
|
377
|
-
rareBridge: getAddress("0x3b41e21094611d152a08d3691a70837f1a077dae")
|
|
377
|
+
rareBridge: getAddress("0x3b41e21094611d152a08d3691a70837f1a077dae"),
|
|
378
|
+
liquidFactory: getAddress("0x54016106A92895a38E54cA286216416750e517b1"),
|
|
379
|
+
swapRouter: getAddress("0x6d078A410ee2AD08cACD8d22b486365433e98b7b"),
|
|
380
|
+
v4Quoter: getAddress("0x0d5e0f971ed27fbff6c2837bf31316121532048d")
|
|
378
381
|
},
|
|
379
382
|
"base-sepolia": {
|
|
380
383
|
factory: getAddress("0x2b181ae0f1aea6fed75591b04991b1a3f9868d51"),
|
|
381
384
|
auction: getAddress("0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2"),
|
|
382
|
-
rareBridge: getAddress("0xca491bb62A7730E97F500510132C47633DDD0229")
|
|
385
|
+
rareBridge: getAddress("0xca491bb62A7730E97F500510132C47633DDD0229"),
|
|
386
|
+
liquidFactory: getAddress("0x912ecC55445d87149d09d83426D0aC41379bB643"),
|
|
387
|
+
swapRouter: getAddress("0x92438008608949E2C7eCef34c474792bAFe8a971"),
|
|
388
|
+
v4Quoter: getAddress("0x4a6513c898fe1b2d0e78d3b0e0a4a151589b1cba")
|
|
383
389
|
}
|
|
384
390
|
};
|
|
385
391
|
var ccipChainSelectors = {
|
|
@@ -5675,7 +5681,7 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
5675
5681
|
}
|
|
5676
5682
|
|
|
5677
5683
|
// src/sdk/batch-listing.ts
|
|
5678
|
-
import { isAddressEqual as
|
|
5684
|
+
import { isAddressEqual as isAddressEqual11 } from "viem";
|
|
5679
5685
|
|
|
5680
5686
|
// src/contracts/abis/batch-listing.ts
|
|
5681
5687
|
var batchListingAbi = [
|
|
@@ -5933,15 +5939,18 @@ function parseBatchTokenList(params) {
|
|
|
5933
5939
|
const rawTokens = format === "json" ? parseJsonBatchTokens(params.content) : parseCsvBatchTokens(params.content);
|
|
5934
5940
|
return normalizeBatchTokens(rawTokens, params.chainId);
|
|
5935
5941
|
}
|
|
5936
|
-
function parseBatchTokenListArtifact(content) {
|
|
5942
|
+
function parseBatchTokenListArtifact(content, chainIdInput) {
|
|
5937
5943
|
const parsed = parseJson(content, "batch token artifact");
|
|
5938
5944
|
if (!isRecord2(parsed)) {
|
|
5939
5945
|
throw new Error("Batch token artifact must be a JSON object.");
|
|
5940
5946
|
}
|
|
5941
|
-
if (parsed.type !== "rare-batch-token-list") {
|
|
5947
|
+
if (parsed.type !== void 0 && parsed.type !== "rare-batch-token-list") {
|
|
5942
5948
|
throw new Error('Batch token artifact type must be "rare-batch-token-list".');
|
|
5943
5949
|
}
|
|
5944
|
-
if (parsed.
|
|
5950
|
+
if (parsed.type === void 0 && !isUntypedBatchTokenListArtifactLike(parsed)) {
|
|
5951
|
+
throw new Error('Batch token artifact type must be "rare-batch-token-list".');
|
|
5952
|
+
}
|
|
5953
|
+
if (parsed.version !== void 0 && parsed.version !== 1) {
|
|
5945
5954
|
throw new Error("Batch token artifact version must be 1.");
|
|
5946
5955
|
}
|
|
5947
5956
|
if (typeof parsed.root !== "string") {
|
|
@@ -5950,11 +5959,19 @@ function parseBatchTokenListArtifact(content) {
|
|
|
5950
5959
|
if (!Array.isArray(parsed.tokens)) {
|
|
5951
5960
|
throw new Error("Batch token artifact tokens must be an array.");
|
|
5952
5961
|
}
|
|
5962
|
+
const parsedChainId = parsed.chainId === void 0 ? void 0 : parseUnknownInteger(parsed.chainId, "artifact chainId");
|
|
5963
|
+
const expectedChainId = chainIdInput === void 0 ? void 0 : normalizeChainId(chainIdInput, "chainId");
|
|
5964
|
+
const artifactChainId = parsedChainId ?? expectedChainId;
|
|
5965
|
+
if (parsedChainId !== void 0 && expectedChainId !== void 0 && normalizeChainId(parsedChainId, "artifact chainId") !== expectedChainId) {
|
|
5966
|
+
throw new Error(
|
|
5967
|
+
`Input chainId ${normalizeChainId(parsedChainId, "artifact chainId")} does not match --chain-id ${expectedChainId}.`
|
|
5968
|
+
);
|
|
5969
|
+
}
|
|
5953
5970
|
const artifact = buildBatchTokenTreeArtifact({
|
|
5954
5971
|
content: JSON.stringify(parsed.tokens),
|
|
5955
5972
|
format: "json",
|
|
5956
5973
|
sourceName: "batch token artifact tokens",
|
|
5957
|
-
chainId:
|
|
5974
|
+
chainId: artifactChainId
|
|
5958
5975
|
});
|
|
5959
5976
|
const root = normalizeBytes32(parsed.root, "artifact root");
|
|
5960
5977
|
if (typeof parsed.count === "number" && parsed.count !== artifact.count) {
|
|
@@ -5968,12 +5985,15 @@ function parseBatchTokenListArtifact(content) {
|
|
|
5968
5985
|
function parseBatchTokenListArtifactOrBuild(params) {
|
|
5969
5986
|
if (params.content.trimStart().startsWith("{")) {
|
|
5970
5987
|
const parsed = parseJson(params.content, "batch token JSON");
|
|
5971
|
-
if (isRecord2(parsed) && parsed.type === "rare-batch-token-list") {
|
|
5972
|
-
return parseBatchTokenListArtifact(params.content);
|
|
5988
|
+
if (isRecord2(parsed) && (parsed.type === "rare-batch-token-list" || isUntypedBatchTokenListArtifactLike(parsed))) {
|
|
5989
|
+
return parseBatchTokenListArtifact(params.content, params.chainId);
|
|
5973
5990
|
}
|
|
5974
5991
|
}
|
|
5975
5992
|
return buildBatchTokenTreeArtifact(params);
|
|
5976
5993
|
}
|
|
5994
|
+
function isUntypedBatchTokenListArtifactLike(value) {
|
|
5995
|
+
return typeof value.root === "string" && Array.isArray(value.tokens) && !("currency" in value) && !("amount" in value) && !("splitAddresses" in value) && !("splitRatios" in value);
|
|
5996
|
+
}
|
|
5977
5997
|
function getBatchTokenProof(params) {
|
|
5978
5998
|
const contractAddress = normalizeAddressValue(params.contractAddress, "contractAddress");
|
|
5979
5999
|
const tokenId = normalizeTokenId(params.tokenId, "tokenId");
|
|
@@ -6535,13 +6555,251 @@ function uniqueRoots(roots) {
|
|
|
6535
6555
|
}
|
|
6536
6556
|
|
|
6537
6557
|
// src/sdk/batch-listing-core.ts
|
|
6538
|
-
import { isAddressEqual as
|
|
6558
|
+
import { isAddressEqual as isAddressEqual10 } from "viem";
|
|
6559
|
+
|
|
6560
|
+
// src/sdk/merkle-core.ts
|
|
6561
|
+
import { Buffer } from "buffer";
|
|
6562
|
+
import { MerkleTree } from "merkletreejs";
|
|
6563
|
+
import {
|
|
6564
|
+
encodePacked as encodePacked2,
|
|
6565
|
+
getAddress as getAddress7,
|
|
6566
|
+
isAddress as isAddress6,
|
|
6567
|
+
isAddressEqual as isAddressEqual9,
|
|
6568
|
+
isHex as isHex3,
|
|
6569
|
+
keccak256 as keccak2562
|
|
6570
|
+
} from "viem";
|
|
6571
|
+
function hexBuffer(hex) {
|
|
6572
|
+
return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
|
|
6573
|
+
}
|
|
6574
|
+
function tokenLeaf(contract, tokenId) {
|
|
6575
|
+
const packed = encodePacked2(["address", "uint256"], [contract, tokenId]);
|
|
6576
|
+
return hexBuffer(keccak2562(packed));
|
|
6577
|
+
}
|
|
6578
|
+
function addressLeaf(address) {
|
|
6579
|
+
return hexBuffer(keccak2562(address));
|
|
6580
|
+
}
|
|
6581
|
+
function parseBytes32(value, field) {
|
|
6582
|
+
if (!isHex3(value, { strict: true }) || value.length !== 66) {
|
|
6583
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
6584
|
+
}
|
|
6585
|
+
const normalized = value.toLowerCase();
|
|
6586
|
+
if (!isHex3(normalized, { strict: true }) || normalized.length !== 66) {
|
|
6587
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
6588
|
+
}
|
|
6589
|
+
return normalized;
|
|
6590
|
+
}
|
|
6591
|
+
function parseBytes32Array(values, field) {
|
|
6592
|
+
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
6593
|
+
}
|
|
6594
|
+
function compareTokenEntries(a, b) {
|
|
6595
|
+
if (!isAddressEqual9(a.contract, b.contract)) {
|
|
6596
|
+
return a.contract.localeCompare(b.contract);
|
|
6597
|
+
}
|
|
6598
|
+
return a.tokenId.localeCompare(b.tokenId);
|
|
6599
|
+
}
|
|
6600
|
+
function normalizeTokenEntry(token) {
|
|
6601
|
+
if (!isAddress6(token.contract)) {
|
|
6602
|
+
throw new Error(`Invalid token contract address: ${token.contract}`);
|
|
6603
|
+
}
|
|
6604
|
+
return {
|
|
6605
|
+
contract: getAddress7(token.contract),
|
|
6606
|
+
tokenId: String(token.tokenId),
|
|
6607
|
+
tokenIdBigInt: toInteger(token.tokenId, "tokenId")
|
|
6608
|
+
};
|
|
6609
|
+
}
|
|
6610
|
+
function buildBatchListingTree(tokens) {
|
|
6611
|
+
if (tokens.length < 2) {
|
|
6612
|
+
throw new Error("buildBatchListingTree requires at least two tokens");
|
|
6613
|
+
}
|
|
6614
|
+
const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
|
|
6615
|
+
const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
|
|
6616
|
+
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
|
|
6617
|
+
sortPairs: true
|
|
6618
|
+
});
|
|
6619
|
+
return {
|
|
6620
|
+
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
6621
|
+
tree,
|
|
6622
|
+
sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
|
|
6623
|
+
};
|
|
6624
|
+
}
|
|
6625
|
+
function buildAllowListTree(addresses) {
|
|
6626
|
+
if (addresses.length < 2) {
|
|
6627
|
+
throw new Error("buildAllowListTree requires at least two addresses");
|
|
6628
|
+
}
|
|
6629
|
+
const sorted = addresses.map((address) => {
|
|
6630
|
+
if (!isAddress6(address)) throw new Error(`Invalid allowlist address: ${address}`);
|
|
6631
|
+
return getAddress7(address);
|
|
6632
|
+
}).sort((a, b) => a.localeCompare(b));
|
|
6633
|
+
const leaves = sorted.map(addressLeaf);
|
|
6634
|
+
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
|
|
6635
|
+
sortPairs: true
|
|
6636
|
+
});
|
|
6637
|
+
return {
|
|
6638
|
+
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
6639
|
+
tree,
|
|
6640
|
+
sortedAddresses: sorted
|
|
6641
|
+
};
|
|
6642
|
+
}
|
|
6643
|
+
function getTokenProof(tree, contract, tokenId) {
|
|
6644
|
+
const leaf = tokenLeaf(getAddress7(contract), tokenId);
|
|
6645
|
+
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
6646
|
+
}
|
|
6647
|
+
function getAddressProof(tree, address) {
|
|
6648
|
+
const leaf = addressLeaf(getAddress7(address));
|
|
6649
|
+
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
6650
|
+
}
|
|
6651
|
+
function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
6652
|
+
const tokenIdBig = toInteger(tokenId, "tokenId");
|
|
6653
|
+
const contractChecksum = getAddress7(contract);
|
|
6654
|
+
const found = artifact.tokens.find(
|
|
6655
|
+
(token) => isAddressEqual9(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
|
|
6656
|
+
);
|
|
6657
|
+
if (found === void 0) {
|
|
6658
|
+
throw new Error(
|
|
6659
|
+
`Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
|
|
6660
|
+
);
|
|
6661
|
+
}
|
|
6662
|
+
const { tree, root } = buildBatchListingTree(
|
|
6663
|
+
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
6664
|
+
);
|
|
6665
|
+
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
6666
|
+
if (root !== artifactRoot) {
|
|
6667
|
+
throw new Error(
|
|
6668
|
+
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
6669
|
+
);
|
|
6670
|
+
}
|
|
6671
|
+
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
6672
|
+
return {
|
|
6673
|
+
root: artifactRoot,
|
|
6674
|
+
contract: contractChecksum,
|
|
6675
|
+
tokenId: tokenIdBig.toString(),
|
|
6676
|
+
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
6677
|
+
...allowListProofFields ?? {}
|
|
6678
|
+
};
|
|
6679
|
+
}
|
|
6680
|
+
function buildAllowListProofFields(artifact, buyer) {
|
|
6681
|
+
if (artifact.allowList === void 0) return void 0;
|
|
6682
|
+
if (buyer === void 0) {
|
|
6683
|
+
throw new Error(
|
|
6684
|
+
"This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
|
|
6685
|
+
);
|
|
6686
|
+
}
|
|
6687
|
+
if (!isAddress6(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
|
|
6688
|
+
const buyerChecksum = getAddress7(buyer);
|
|
6689
|
+
const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual9(address, buyerChecksum));
|
|
6690
|
+
if (!inAllowList) {
|
|
6691
|
+
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
6692
|
+
}
|
|
6693
|
+
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
6694
|
+
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
6695
|
+
if (root !== artifactAllowListRoot) {
|
|
6696
|
+
throw new Error(
|
|
6697
|
+
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
6698
|
+
);
|
|
6699
|
+
}
|
|
6700
|
+
return {
|
|
6701
|
+
allowListProof: getAddressProof(tree, buyerChecksum),
|
|
6702
|
+
allowListAddress: buyerChecksum
|
|
6703
|
+
};
|
|
6704
|
+
}
|
|
6705
|
+
function assertRecord(value, field) {
|
|
6706
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
6707
|
+
throw new Error(`${field} must be a JSON object`);
|
|
6708
|
+
}
|
|
6709
|
+
}
|
|
6710
|
+
function assertHexRoot(value, field) {
|
|
6711
|
+
if (typeof value !== "string" || !isHex3(value, { strict: true }) || value.length !== 66) {
|
|
6712
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
6713
|
+
}
|
|
6714
|
+
}
|
|
6715
|
+
function assertAddress(value, field) {
|
|
6716
|
+
if (typeof value !== "string" || !isAddress6(value)) {
|
|
6717
|
+
throw new Error(`${field} must be a valid 0x address`);
|
|
6718
|
+
}
|
|
6719
|
+
}
|
|
6720
|
+
function validateRootArtifact(value) {
|
|
6721
|
+
assertRecord(value, "Root artifact");
|
|
6722
|
+
if (isBatchTokenTreeArtifactLike(value)) {
|
|
6723
|
+
throw new Error(
|
|
6724
|
+
"Input looks like a token tree artifact from rare utils tree build, not a batch listing root artifact. For rare listing batch create, pass --price and optionally --currency/--split with the token tree artifact."
|
|
6725
|
+
);
|
|
6726
|
+
}
|
|
6727
|
+
assertHexRoot(value.root, "root");
|
|
6728
|
+
assertAddress(value.currency, "currency");
|
|
6729
|
+
if (typeof value.amount !== "string") throw new Error("amount must be a string (base units)");
|
|
6730
|
+
if (!Array.isArray(value.splitAddresses)) throw new Error("splitAddresses must be an array");
|
|
6731
|
+
if (!Array.isArray(value.splitRatios)) throw new Error("splitRatios must be an array");
|
|
6732
|
+
if (!Array.isArray(value.tokens) || value.tokens.length < 2) {
|
|
6733
|
+
throw new Error("tokens must contain at least two entries");
|
|
6734
|
+
}
|
|
6735
|
+
value.tokens.forEach((token) => {
|
|
6736
|
+
assertRecord(token, "tokens[]");
|
|
6737
|
+
assertAddress(token.contract, "tokens[].contract");
|
|
6738
|
+
if (typeof token.tokenId !== "string") throw new Error("tokens[].tokenId must be a string");
|
|
6739
|
+
});
|
|
6740
|
+
if (value.allowList !== void 0 && value.allowList !== null) {
|
|
6741
|
+
assertRecord(value.allowList, "allowList");
|
|
6742
|
+
assertHexRoot(value.allowList.root, "allowList.root");
|
|
6743
|
+
if (!Array.isArray(value.allowList.addresses)) throw new Error("allowList.addresses must be an array");
|
|
6744
|
+
if (value.allowList.addresses.length < 2) {
|
|
6745
|
+
throw new Error("allowList.addresses must contain at least two entries");
|
|
6746
|
+
}
|
|
6747
|
+
value.allowList.addresses.forEach((address) => {
|
|
6748
|
+
assertAddress(address, "allowList.addresses entry");
|
|
6749
|
+
});
|
|
6750
|
+
}
|
|
6751
|
+
}
|
|
6752
|
+
function isBatchTokenTreeArtifactLike(value) {
|
|
6753
|
+
if (value.type === "rare-batch-token-list") {
|
|
6754
|
+
return true;
|
|
6755
|
+
}
|
|
6756
|
+
return Array.isArray(value.tokens) && !("currency" in value) && !("amount" in value) && !("splitAddresses" in value) && !("splitRatios" in value);
|
|
6757
|
+
}
|
|
6758
|
+
function validateProofArtifact(value) {
|
|
6759
|
+
assertRecord(value, "Proof artifact");
|
|
6760
|
+
assertHexRoot(value.root, "root");
|
|
6761
|
+
assertAddress(value.contract, "contract");
|
|
6762
|
+
if (typeof value.tokenId !== "string") throw new Error("tokenId must be a string");
|
|
6763
|
+
if (!Array.isArray(value.proof)) throw new Error("proof must be an array of bytes32 hex");
|
|
6764
|
+
if (value.proof.length === 0) throw new Error("proof must not be empty");
|
|
6765
|
+
value.proof.forEach((proof) => {
|
|
6766
|
+
assertHexRoot(proof, "proof entry");
|
|
6767
|
+
});
|
|
6768
|
+
if (value.allowListProof !== void 0 && value.allowListProof !== null) {
|
|
6769
|
+
if (!Array.isArray(value.allowListProof)) throw new Error("allowListProof must be an array");
|
|
6770
|
+
value.allowListProof.forEach((proof) => {
|
|
6771
|
+
assertHexRoot(proof, "allowListProof entry");
|
|
6772
|
+
});
|
|
6773
|
+
}
|
|
6774
|
+
if (value.allowListAddress !== void 0 && value.allowListAddress !== null) {
|
|
6775
|
+
assertAddress(value.allowListAddress, "allowListAddress");
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
|
|
6779
|
+
// src/sdk/batch-listing-core.ts
|
|
6539
6780
|
function uniqueAddresses(addresses) {
|
|
6540
6781
|
return addresses.reduce(
|
|
6541
|
-
(unique, address) => unique.some((existing) =>
|
|
6782
|
+
(unique, address) => unique.some((existing) => isAddressEqual10(existing, address)) ? unique : [...unique, address],
|
|
6542
6783
|
[]
|
|
6543
6784
|
);
|
|
6544
6785
|
}
|
|
6786
|
+
function parseBatchListingCreateRootArtifactInput(value) {
|
|
6787
|
+
if (!isRecord3(value)) {
|
|
6788
|
+
validateRootArtifact(value);
|
|
6789
|
+
throw new Error("unreachable: non-object root artifact validation did not throw");
|
|
6790
|
+
}
|
|
6791
|
+
if (isBatchTokenTreeInputObject(value)) {
|
|
6792
|
+
return void 0;
|
|
6793
|
+
}
|
|
6794
|
+
validateRootArtifact(value);
|
|
6795
|
+
return value;
|
|
6796
|
+
}
|
|
6797
|
+
function planBatchListingCreateArtifact(plan) {
|
|
6798
|
+
const splitOverride = planOptionalSplitOverride(plan.splitAddresses, plan.splitRatios);
|
|
6799
|
+
const artifact = plan.kind === "root-artifact" ? planBatchListingCreateRootArtifact(plan, splitOverride) : planBatchListingCreateTokenTreeArtifact(plan, splitOverride);
|
|
6800
|
+
planBatchListingRootRegistrationLocalInputs(artifact);
|
|
6801
|
+
return artifact;
|
|
6802
|
+
}
|
|
6545
6803
|
function planBatchListingRootRegistration(artifact, accountAddress) {
|
|
6546
6804
|
const local = planBatchListingRootRegistrationLocalInputs(artifact);
|
|
6547
6805
|
if (local !== void 0) {
|
|
@@ -6550,6 +6808,54 @@ function planBatchListingRootRegistration(artifact, accountAddress) {
|
|
|
6550
6808
|
const splits = planPayoutSplits(void 0, void 0, accountAddress);
|
|
6551
6809
|
return { splitAddresses: splits.addresses, splitRatios: splits.ratios };
|
|
6552
6810
|
}
|
|
6811
|
+
function planBatchListingCreateRootArtifact(plan, splitOverride) {
|
|
6812
|
+
if (plan.currencyOverride !== void 0 && plan.amountOverride === void 0) {
|
|
6813
|
+
throw new Error("--currency requires --price when overriding a batch listing root artifact.");
|
|
6814
|
+
}
|
|
6815
|
+
return {
|
|
6816
|
+
...plan.artifact,
|
|
6817
|
+
currency: plan.currencyOverride ?? plan.artifact.currency,
|
|
6818
|
+
amount: plan.amountOverride ?? plan.artifact.amount,
|
|
6819
|
+
...splitOverride === void 0 ? {} : {
|
|
6820
|
+
splitAddresses: splitOverride.addresses,
|
|
6821
|
+
splitRatios: splitOverride.ratios
|
|
6822
|
+
}
|
|
6823
|
+
};
|
|
6824
|
+
}
|
|
6825
|
+
function planBatchListingCreateTokenTreeArtifact(plan, splitOverride) {
|
|
6826
|
+
return {
|
|
6827
|
+
root: plan.artifact.root,
|
|
6828
|
+
currency: plan.currency,
|
|
6829
|
+
amount: plan.amount,
|
|
6830
|
+
splitAddresses: splitOverride?.addresses ?? [],
|
|
6831
|
+
splitRatios: splitOverride?.ratios ?? [],
|
|
6832
|
+
tokens: plan.artifact.tokens.map((token) => ({
|
|
6833
|
+
contract: token.contractAddress,
|
|
6834
|
+
tokenId: token.tokenId
|
|
6835
|
+
}))
|
|
6836
|
+
};
|
|
6837
|
+
}
|
|
6838
|
+
function planOptionalSplitOverride(splitAddresses, splitRatios) {
|
|
6839
|
+
if (splitAddresses === void 0 && splitRatios === void 0) {
|
|
6840
|
+
return void 0;
|
|
6841
|
+
}
|
|
6842
|
+
if (splitAddresses === void 0 || splitRatios === void 0) {
|
|
6843
|
+
throw new Error("splitAddresses and splitRatios must both be provided.");
|
|
6844
|
+
}
|
|
6845
|
+
return planProvidedPayoutSplits(splitAddresses, splitRatios);
|
|
6846
|
+
}
|
|
6847
|
+
function isBatchTokenTreeInputObject(value) {
|
|
6848
|
+
if (value.type === "rare-batch-token-list") {
|
|
6849
|
+
return true;
|
|
6850
|
+
}
|
|
6851
|
+
if ("currency" in value || "amount" in value || "splitAddresses" in value || "splitRatios" in value || !Array.isArray(value.tokens)) {
|
|
6852
|
+
return false;
|
|
6853
|
+
}
|
|
6854
|
+
return true;
|
|
6855
|
+
}
|
|
6856
|
+
function isRecord3(value) {
|
|
6857
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6858
|
+
}
|
|
6553
6859
|
function planBatchListingRootRegistrationLocalInputs(artifact) {
|
|
6554
6860
|
if (artifact.tokens.length < 2) {
|
|
6555
6861
|
throw new Error("Root artifact must contain at least two tokens; the batch listing contract rejects empty proofs");
|
|
@@ -6582,7 +6888,7 @@ function shapeBatchListingStatus(params) {
|
|
|
6582
6888
|
splitRecipients: [...params.listingConfig.splitRecipients],
|
|
6583
6889
|
splitRatios: [...params.listingConfig.splitRatios],
|
|
6584
6890
|
nonce: params.listingConfig.nonce,
|
|
6585
|
-
isEth:
|
|
6891
|
+
isEth: isAddressEqual10(params.listingConfig.currency, ETH_ADDRESS),
|
|
6586
6892
|
hasListing,
|
|
6587
6893
|
allowList: params.allowList,
|
|
6588
6894
|
...params.tokenStatus
|
|
@@ -6613,7 +6919,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6613
6919
|
functionName: "ownerOf",
|
|
6614
6920
|
args: [BigInt(token.tokenId)]
|
|
6615
6921
|
});
|
|
6616
|
-
if (!
|
|
6922
|
+
if (!isAddressEqual11(owner, accountAddress)) {
|
|
6617
6923
|
throw new Error(
|
|
6618
6924
|
`Token ${token.contract}/${token.tokenId} is owned by ${owner}, not the configured account ${accountAddress}. Re-check the token set before registering this batch listing.`
|
|
6619
6925
|
);
|
|
@@ -7061,7 +7367,7 @@ async function readTokenStatus(publicClient, batchListingAddress, params) {
|
|
|
7061
7367
|
|
|
7062
7368
|
// src/sdk/batch-auction.ts
|
|
7063
7369
|
import {
|
|
7064
|
-
isAddressEqual as
|
|
7370
|
+
isAddressEqual as isAddressEqual13,
|
|
7065
7371
|
parseUnits as parseUnits3,
|
|
7066
7372
|
parseEventLogs as parseEventLogs3
|
|
7067
7373
|
} from "viem";
|
|
@@ -7293,7 +7599,7 @@ var batchAuctionHouseAbi = [
|
|
|
7293
7599
|
];
|
|
7294
7600
|
|
|
7295
7601
|
// src/sdk/batch-auction-core.ts
|
|
7296
|
-
import { isAddressEqual as
|
|
7602
|
+
import { isAddressEqual as isAddressEqual12 } from "viem";
|
|
7297
7603
|
var zeroAddress3 = ETH_ADDRESS;
|
|
7298
7604
|
var marketplaceFeePercentage = 3n;
|
|
7299
7605
|
function planBatchAuctionCreateLocalInputs(params, nowSeconds) {
|
|
@@ -7384,7 +7690,7 @@ function planBatchAuctionStatus(params) {
|
|
|
7384
7690
|
};
|
|
7385
7691
|
}
|
|
7386
7692
|
function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
7387
|
-
const hasAuction = details.startingTime > 0n && !
|
|
7693
|
+
const hasAuction = details.startingTime > 0n && !isAddressEqual12(details.seller, zeroAddress3);
|
|
7388
7694
|
const hasCurrentRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n && rootContext.rootNonce === rootContext.config.nonce;
|
|
7389
7695
|
const currentRootConfig = hasCurrentRootConfig ? rootContext.config : void 0;
|
|
7390
7696
|
const hasRootConfig = currentRootConfig !== void 0;
|
|
@@ -7392,7 +7698,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
7392
7698
|
const startingTime = hasAuction ? details.startingTime : 0n;
|
|
7393
7699
|
const endTime = hasAuction ? startingTime + duration : null;
|
|
7394
7700
|
const ended = endTime !== null && nowSeconds >= endTime;
|
|
7395
|
-
const currentBidder = currentBid.amount > 0n && !
|
|
7701
|
+
const currentBidder = currentBid.amount > 0n && !isAddressEqual12(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
|
|
7396
7702
|
const seller = hasAuction ? details.seller : rootContext?.creator ?? zeroAddress3;
|
|
7397
7703
|
const currency = hasAuction ? details.currency : currentRootConfig?.currency ?? ETH_ADDRESS;
|
|
7398
7704
|
const reserveAmount = hasAuction ? details.reserveAmount : currentRootConfig?.reserveAmount ?? 0n;
|
|
@@ -7427,7 +7733,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
7427
7733
|
hasRootConfig,
|
|
7428
7734
|
tokenNonceConsumed
|
|
7429
7735
|
}),
|
|
7430
|
-
isEth:
|
|
7736
|
+
isEth: isAddressEqual12(currency, ETH_ADDRESS)
|
|
7431
7737
|
};
|
|
7432
7738
|
}
|
|
7433
7739
|
function shapeBatchAuctionDetailsRead(details) {
|
|
@@ -7538,7 +7844,7 @@ function planSplitRecipients(splitAddresses, splitRatios, accountAddress) {
|
|
|
7538
7844
|
};
|
|
7539
7845
|
}
|
|
7540
7846
|
function uniqueAddresses2(addresses) {
|
|
7541
|
-
return addresses.reduce((unique, address) => unique.some((candidate) =>
|
|
7847
|
+
return addresses.reduce((unique, address) => unique.some((candidate) => isAddressEqual12(candidate, address)) ? unique : [...unique, address], []);
|
|
7542
7848
|
}
|
|
7543
7849
|
function addMinimumBidIncrease(amount) {
|
|
7544
7850
|
return amount + amount * marketplaceFeePercentage / 100n;
|
|
@@ -7712,7 +8018,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7712
8018
|
const price = requireInput(resolvedParams.price, "price");
|
|
7713
8019
|
const amount = typeof price === "bigint" ? price : parseUnits3(stringifyAmountInput(price, "price"), await resolveCurrencyDecimals(publicClient, chain, currency));
|
|
7714
8020
|
const plan = planBatchAuctionBid({ ...resolvedParams, currency, price: amount });
|
|
7715
|
-
const erc20ApprovalManager =
|
|
8021
|
+
const erc20ApprovalManager = isAddressEqual13(plan.currency, ETH_ADDRESS) ? batchAuctionHouse : requireContractAddress(chain, "erc20ApprovalManager");
|
|
7716
8022
|
const payment = await preparePaymentAmountForSpender({
|
|
7717
8023
|
publicClient,
|
|
7718
8024
|
walletClient,
|
|
@@ -8071,7 +8377,7 @@ async function resolveRootContext(opts) {
|
|
|
8071
8377
|
|
|
8072
8378
|
// src/sdk/batch-offer.ts
|
|
8073
8379
|
import {
|
|
8074
|
-
isAddressEqual as
|
|
8380
|
+
isAddressEqual as isAddressEqual15,
|
|
8075
8381
|
parseUnits as parseUnits4,
|
|
8076
8382
|
parseEventLogs as parseEventLogs4
|
|
8077
8383
|
} from "viem";
|
|
@@ -8178,7 +8484,7 @@ var batchOfferAbi = [
|
|
|
8178
8484
|
];
|
|
8179
8485
|
|
|
8180
8486
|
// src/sdk/batch-offer-core.ts
|
|
8181
|
-
import { isAddressEqual as
|
|
8487
|
+
import { isAddressEqual as isAddressEqual14 } from "viem";
|
|
8182
8488
|
var zeroAddress4 = ETH_ADDRESS;
|
|
8183
8489
|
var zeroBytes322 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
8184
8490
|
function planBatchOfferCreateLocalInputs(params, nowSeconds) {
|
|
@@ -8235,7 +8541,7 @@ function planBatchOfferAccept(params, accountAddress) {
|
|
|
8235
8541
|
};
|
|
8236
8542
|
}
|
|
8237
8543
|
function shapeBatchOfferStatus(offer, expected, nowSeconds) {
|
|
8238
|
-
const hasOffer = !
|
|
8544
|
+
const hasOffer = !isAddressEqual14(offer.creator, zeroAddress4) && offer.rootHash !== zeroBytes322 && offer.amount > 0n;
|
|
8239
8545
|
const expired = hasOffer && offer.expiry <= nowSeconds;
|
|
8240
8546
|
const state = !hasOffer ? "NONE" : expired ? "EXPIRED" : "ACTIVE";
|
|
8241
8547
|
return {
|
|
@@ -8250,7 +8556,7 @@ function shapeBatchOfferStatus(offer, expected, nowSeconds) {
|
|
|
8250
8556
|
revoked: hasOffer ? false : null,
|
|
8251
8557
|
fillable: hasOffer && !expired,
|
|
8252
8558
|
state,
|
|
8253
|
-
isEth:
|
|
8559
|
+
isEth: isAddressEqual14(offer.currency, ETH_ADDRESS)
|
|
8254
8560
|
};
|
|
8255
8561
|
}
|
|
8256
8562
|
function shapeBatchOfferRead(value) {
|
|
@@ -8440,7 +8746,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8440
8746
|
functionName: "ownerOf",
|
|
8441
8747
|
args: [plan.tokenId]
|
|
8442
8748
|
});
|
|
8443
|
-
if (!
|
|
8749
|
+
if (!isAddressEqual15(owner, accountAddress)) {
|
|
8444
8750
|
throw new Error(`Connected wallet ${accountAddress} does not own token ${plan.contract} #${plan.tokenId.toString()}.`);
|
|
8445
8751
|
}
|
|
8446
8752
|
const approvalTxHash = await approveNftContractIfNeeded({
|
|
@@ -9159,7 +9465,7 @@ var CURVE_PRESET_DEFINITIONS = {
|
|
|
9159
9465
|
reserveTailStartTokenPriceUsd: 50
|
|
9160
9466
|
}
|
|
9161
9467
|
};
|
|
9162
|
-
function
|
|
9468
|
+
function isRecord4(value) {
|
|
9163
9469
|
return typeof value === "object" && value !== null;
|
|
9164
9470
|
}
|
|
9165
9471
|
function isPositiveFiniteNumber(value) {
|
|
@@ -9422,7 +9728,7 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
9422
9728
|
return { isValid: true, curves: sortedSegments };
|
|
9423
9729
|
}
|
|
9424
9730
|
function normalizeSegment(segment, tickSpacing) {
|
|
9425
|
-
if (!
|
|
9731
|
+
if (!isRecord4(segment)) {
|
|
9426
9732
|
return invalidSegmentResult();
|
|
9427
9733
|
}
|
|
9428
9734
|
const tickLower = toValidNumber(segment.tickLower);
|
|
@@ -10483,7 +10789,7 @@ var liquidRouterAbi = [
|
|
|
10483
10789
|
];
|
|
10484
10790
|
|
|
10485
10791
|
// src/swap/known-pools.ts
|
|
10486
|
-
import { getAddress as
|
|
10792
|
+
import { getAddress as getAddress8 } from "viem";
|
|
10487
10793
|
|
|
10488
10794
|
// src/swap/pool-core.ts
|
|
10489
10795
|
function normalizeAddress(value) {
|
|
@@ -10502,10 +10808,10 @@ function inferBaseCurrencyAddress(poolKey, token) {
|
|
|
10502
10808
|
|
|
10503
10809
|
// src/swap/known-pools.ts
|
|
10504
10810
|
var wrappedEthAddresses = {
|
|
10505
|
-
mainnet:
|
|
10506
|
-
sepolia:
|
|
10507
|
-
base:
|
|
10508
|
-
"base-sepolia":
|
|
10811
|
+
mainnet: getAddress8("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
|
|
10812
|
+
sepolia: getAddress8("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"),
|
|
10813
|
+
base: getAddress8("0x4200000000000000000000000000000000000006"),
|
|
10814
|
+
"base-sepolia": getAddress8("0x4200000000000000000000000000000000000006")
|
|
10509
10815
|
};
|
|
10510
10816
|
function poolToKey(pool) {
|
|
10511
10817
|
return {
|
|
@@ -10820,8 +11126,8 @@ async function quoteRouteSteps(publicClient, quoterAddress, routeSteps, currentA
|
|
|
10820
11126
|
// src/swap/route-encoding.ts
|
|
10821
11127
|
import {
|
|
10822
11128
|
encodeAbiParameters as encodeAbiParameters2,
|
|
10823
|
-
encodePacked as
|
|
10824
|
-
getAddress as
|
|
11129
|
+
encodePacked as encodePacked3,
|
|
11130
|
+
getAddress as getAddress9,
|
|
10825
11131
|
parseAbiParameters
|
|
10826
11132
|
} from "viem";
|
|
10827
11133
|
var ROUTER_COMMANDS = {
|
|
@@ -10838,8 +11144,8 @@ var V4_ACTIONS = {
|
|
|
10838
11144
|
TAKE_ALL: 15
|
|
10839
11145
|
};
|
|
10840
11146
|
var ROUTER_RECIPIENTS = {
|
|
10841
|
-
msgSender:
|
|
10842
|
-
addressThis:
|
|
11147
|
+
msgSender: getAddress9("0x0000000000000000000000000000000000000001"),
|
|
11148
|
+
addressThis: getAddress9("0x0000000000000000000000000000000000000002")
|
|
10843
11149
|
};
|
|
10844
11150
|
var ROUTER_AMOUNT_CONSTANTS = {
|
|
10845
11151
|
openDelta: 0n,
|
|
@@ -10851,7 +11157,7 @@ function encodeRoute(quote, amountIn, currencyIn, currencyOut) {
|
|
|
10851
11157
|
}
|
|
10852
11158
|
const { commandBytes, inputs } = encodeRouteParts(quote, amountIn, currencyIn, currencyOut, 0);
|
|
10853
11159
|
return {
|
|
10854
|
-
commands:
|
|
11160
|
+
commands: encodePacked3(commandBytes.map(() => "uint8"), [...commandBytes]),
|
|
10855
11161
|
inputs
|
|
10856
11162
|
};
|
|
10857
11163
|
}
|
|
@@ -10982,7 +11288,7 @@ function encodeV4ExactIn({
|
|
|
10982
11288
|
if (singleStep === void 0) {
|
|
10983
11289
|
throw new Error("Missing V4 exact input single step.");
|
|
10984
11290
|
}
|
|
10985
|
-
const actions2 =
|
|
11291
|
+
const actions2 = encodePacked3(
|
|
10986
11292
|
["uint8", "uint8", "uint8"],
|
|
10987
11293
|
[settleAction, V4_ACTIONS.SWAP_EXACT_IN_SINGLE, takeAction]
|
|
10988
11294
|
);
|
|
@@ -10998,7 +11304,7 @@ function encodeV4ExactIn({
|
|
|
10998
11304
|
]
|
|
10999
11305
|
);
|
|
11000
11306
|
}
|
|
11001
|
-
const actions =
|
|
11307
|
+
const actions = encodePacked3(
|
|
11002
11308
|
["uint8", "uint8", "uint8"],
|
|
11003
11309
|
[V4_ACTIONS.SWAP_EXACT_IN, settleAction, takeAction]
|
|
11004
11310
|
);
|
|
@@ -11028,10 +11334,10 @@ function encodeV4ExactInSingle(step, amountIn, minAmountOut) {
|
|
|
11028
11334
|
}
|
|
11029
11335
|
|
|
11030
11336
|
// src/swap/uniswap-api.ts
|
|
11031
|
-
import { getAddress as
|
|
11337
|
+
import { getAddress as getAddress10, isHex as isHex4 } from "viem";
|
|
11032
11338
|
|
|
11033
11339
|
// src/swap/trade-core.ts
|
|
11034
|
-
import { isAddressEqual as
|
|
11340
|
+
import { isAddressEqual as isAddressEqual16 } from "viem";
|
|
11035
11341
|
function toTradeInteger(value, field) {
|
|
11036
11342
|
if (typeof value === "bigint") return value;
|
|
11037
11343
|
if (typeof value === "number") {
|
|
@@ -11099,7 +11405,7 @@ function buildLiquidRouterTradeQuote(params) {
|
|
|
11099
11405
|
}
|
|
11100
11406
|
function getQuotedRecipientAmount(quote, recipient) {
|
|
11101
11407
|
const recipientOutput = quote.aggregatedOutputs?.find(
|
|
11102
|
-
(output2) =>
|
|
11408
|
+
(output2) => isAddressEqual16(output2.recipient, recipient)
|
|
11103
11409
|
);
|
|
11104
11410
|
if (recipientOutput) {
|
|
11105
11411
|
return {
|
|
@@ -11118,7 +11424,7 @@ function assertSupportedUniswapRouting(routing) {
|
|
|
11118
11424
|
}
|
|
11119
11425
|
}
|
|
11120
11426
|
function assertRecipientSupportedForUniswapFallback(recipient, accountAddress) {
|
|
11121
|
-
if (recipient !== void 0 && !
|
|
11427
|
+
if (recipient !== void 0 && !isAddressEqual16(recipient, accountAddress)) {
|
|
11122
11428
|
throw new Error("recipient override is not supported for Uniswap API fallback routes.");
|
|
11123
11429
|
}
|
|
11124
11430
|
}
|
|
@@ -11177,7 +11483,7 @@ function requireApiKey(options) {
|
|
|
11177
11483
|
}
|
|
11178
11484
|
return apiKey;
|
|
11179
11485
|
}
|
|
11180
|
-
function
|
|
11486
|
+
function isRecord5(value) {
|
|
11181
11487
|
return typeof value === "object" && value !== null;
|
|
11182
11488
|
}
|
|
11183
11489
|
function parseString(value, field) {
|
|
@@ -11198,7 +11504,7 @@ function parseNumber(value, field) {
|
|
|
11198
11504
|
function parseAddress2(value, field) {
|
|
11199
11505
|
const raw = parseString(value, field);
|
|
11200
11506
|
try {
|
|
11201
|
-
return
|
|
11507
|
+
return getAddress10(raw);
|
|
11202
11508
|
} catch {
|
|
11203
11509
|
throw new Error(`Uniswap API response field "${field}" must be a valid EVM address.`);
|
|
11204
11510
|
}
|
|
@@ -11208,13 +11514,13 @@ function parseOptionalAddress2(value, field) {
|
|
|
11208
11514
|
}
|
|
11209
11515
|
function parseHex(value, field) {
|
|
11210
11516
|
const raw = parseString(value, field);
|
|
11211
|
-
if (!
|
|
11517
|
+
if (!isHex4(raw)) {
|
|
11212
11518
|
throw new Error(`Uniswap API response field "${field}" must be a hex string.`);
|
|
11213
11519
|
}
|
|
11214
11520
|
return raw;
|
|
11215
11521
|
}
|
|
11216
11522
|
function parseRecord(value, field) {
|
|
11217
|
-
if (!
|
|
11523
|
+
if (!isRecord5(value)) {
|
|
11218
11524
|
throw new Error(`Uniswap API response field "${field}" must be an object.`);
|
|
11219
11525
|
}
|
|
11220
11526
|
return value;
|
|
@@ -11381,7 +11687,7 @@ function parseUniswapSwapResponse(value) {
|
|
|
11381
11687
|
};
|
|
11382
11688
|
}
|
|
11383
11689
|
function getErrorMessage2(parsed) {
|
|
11384
|
-
if (
|
|
11690
|
+
if (isRecord5(parsed) && typeof parsed.message === "string") {
|
|
11385
11691
|
return parsed.message;
|
|
11386
11692
|
}
|
|
11387
11693
|
return void 0;
|
|
@@ -12060,7 +12366,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
12060
12366
|
import {
|
|
12061
12367
|
erc20Abi as erc20Abi2,
|
|
12062
12368
|
hexToBigInt as hexToBigInt2,
|
|
12063
|
-
isAddressEqual as
|
|
12369
|
+
isAddressEqual as isAddressEqual18,
|
|
12064
12370
|
parseEventLogs as parseEventLogs6
|
|
12065
12371
|
} from "viem";
|
|
12066
12372
|
|
|
@@ -12565,11 +12871,11 @@ function toRoyaltyPercentage(value) {
|
|
|
12565
12871
|
|
|
12566
12872
|
// src/sdk/release-core.ts
|
|
12567
12873
|
import {
|
|
12568
|
-
getAddress as
|
|
12569
|
-
isAddress as
|
|
12570
|
-
isAddressEqual as
|
|
12571
|
-
isHex as
|
|
12572
|
-
keccak256 as
|
|
12874
|
+
getAddress as getAddress11,
|
|
12875
|
+
isAddress as isAddress7,
|
|
12876
|
+
isAddressEqual as isAddressEqual17,
|
|
12877
|
+
isHex as isHex5,
|
|
12878
|
+
keccak256 as keccak2563,
|
|
12573
12879
|
parseEther as parseEther2,
|
|
12574
12880
|
parseUnits as parseUnits7
|
|
12575
12881
|
} from "viem";
|
|
@@ -12586,7 +12892,7 @@ function requireRareMinterAddress(address) {
|
|
|
12586
12892
|
}
|
|
12587
12893
|
function assertReleaseContractOwner(opts) {
|
|
12588
12894
|
const { contract, accountAddress, owner } = opts;
|
|
12589
|
-
if (!
|
|
12895
|
+
if (!isAddressEqual17(owner, accountAddress)) {
|
|
12590
12896
|
throw new Error(
|
|
12591
12897
|
`Connected wallet ${accountAddress} is not the owner of collection ${contract}. Contract owner is ${owner}.`
|
|
12592
12898
|
);
|
|
@@ -12734,7 +13040,7 @@ function parseReleaseAllowlistArtifactJson(input) {
|
|
|
12734
13040
|
return parseReleaseAllowlistArtifact(parsed);
|
|
12735
13041
|
}
|
|
12736
13042
|
function parseReleaseAllowlistArtifact(input) {
|
|
12737
|
-
if (!
|
|
13043
|
+
if (!isRecord6(input)) {
|
|
12738
13044
|
throw new Error("Allowlist artifact must be a JSON object.");
|
|
12739
13045
|
}
|
|
12740
13046
|
if (input.kind !== RELEASE_ALLOWLIST_ARTIFACT_KIND || input.version !== 1) {
|
|
@@ -12746,7 +13052,7 @@ function parseReleaseAllowlistArtifact(input) {
|
|
|
12746
13052
|
}
|
|
12747
13053
|
const wallets = normalizeAllowlistRows(
|
|
12748
13054
|
input.wallets.map((entry, index) => {
|
|
12749
|
-
if (!
|
|
13055
|
+
if (!isRecord6(entry)) {
|
|
12750
13056
|
throw new Error(`Invalid allowlist artifact wallet at index ${index}: expected an object.`);
|
|
12751
13057
|
}
|
|
12752
13058
|
return {
|
|
@@ -12775,7 +13081,7 @@ function parseReleaseAllowlistCsv(input) {
|
|
|
12775
13081
|
throw new Error("CSV allowlist is empty.");
|
|
12776
13082
|
}
|
|
12777
13083
|
const headerColumn = findAllowlistAddressColumn(firstRow.fields);
|
|
12778
|
-
if (headerColumn === -1 && !
|
|
13084
|
+
if (headerColumn === -1 && !isAddress7(firstRow.fields[0]?.trim() ?? "")) {
|
|
12779
13085
|
throw new Error("CSV allowlist must put wallet addresses in the first column or include an address/wallet header.");
|
|
12780
13086
|
}
|
|
12781
13087
|
const addressColumn = headerColumn === -1 ? 0 : headerColumn;
|
|
@@ -12790,10 +13096,10 @@ function parseReleaseAllowlistCsv(input) {
|
|
|
12790
13096
|
}
|
|
12791
13097
|
function parseReleaseAllowlistJson(input) {
|
|
12792
13098
|
const parsed = parseJsonUnknown(input, "Malformed JSON allowlist");
|
|
12793
|
-
if (
|
|
13099
|
+
if (isRecord6(parsed) && parsed.kind === RELEASE_ALLOWLIST_ARTIFACT_KIND) {
|
|
12794
13100
|
return parseReleaseAllowlistArtifact(parsed).wallets.map((wallet) => wallet.address);
|
|
12795
13101
|
}
|
|
12796
|
-
const entries = Array.isArray(parsed) ? parsed :
|
|
13102
|
+
const entries = Array.isArray(parsed) ? parsed : isRecord6(parsed) && Array.isArray(parsed.wallets) ? parsed.wallets : isRecord6(parsed) && Array.isArray(parsed.addresses) ? parsed.addresses : null;
|
|
12797
13103
|
if (!entries) {
|
|
12798
13104
|
throw new Error(
|
|
12799
13105
|
"JSON allowlist must be an array of wallet addresses, an array of objects with address/wallet, or an object with wallets/addresses."
|
|
@@ -12834,27 +13140,27 @@ function buildReleaseAllowlistArtifact(wallets) {
|
|
|
12834
13140
|
};
|
|
12835
13141
|
}
|
|
12836
13142
|
function getReleaseAllowlistProof(opts) {
|
|
12837
|
-
const address =
|
|
13143
|
+
const address = getAddress11(opts.address);
|
|
12838
13144
|
return opts.artifact.wallets.find((entry) => addressesEqual(entry.address, address)) ?? null;
|
|
12839
13145
|
}
|
|
12840
13146
|
function verifyReleaseAllowlistProof(opts) {
|
|
12841
13147
|
const root = normalizeBytes322(opts.root, "allowlist root");
|
|
12842
13148
|
const hash = opts.proof.reduce(
|
|
12843
13149
|
(current, sibling) => hashMerklePair(current, normalizeBytes322(sibling, "allowlist proof item")),
|
|
12844
|
-
hashAllowlistAddress(
|
|
13150
|
+
hashAllowlistAddress(getAddress11(opts.address))
|
|
12845
13151
|
);
|
|
12846
13152
|
return hexEquals(hash, root);
|
|
12847
13153
|
}
|
|
12848
13154
|
function preflightReleaseDirectSaleMint(params) {
|
|
12849
13155
|
const { status, plan, buyer, nowSeconds } = params;
|
|
12850
13156
|
const quantity = BigInt(plan.quantity);
|
|
12851
|
-
if (!
|
|
13157
|
+
if (!isAddressEqual17(status.contract, plan.contract)) {
|
|
12852
13158
|
throw new Error(`Release status is for ${status.contract}, but mint plan is for ${plan.contract}.`);
|
|
12853
13159
|
}
|
|
12854
13160
|
if (!status.configured) {
|
|
12855
13161
|
throw new Error("RareMinter direct sale is not configured for this contract.");
|
|
12856
13162
|
}
|
|
12857
|
-
if (plan.recipient !== void 0 && !
|
|
13163
|
+
if (plan.recipient !== void 0 && !isAddressEqual17(plan.recipient, buyer)) {
|
|
12858
13164
|
throw new Error("RareMinter direct sale mint does not support a separate recipient; it mints to the connected wallet.");
|
|
12859
13165
|
}
|
|
12860
13166
|
if (status.startTime > nowSeconds) {
|
|
@@ -12878,7 +13184,7 @@ function preflightReleaseDirectSaleMint(params) {
|
|
|
12878
13184
|
throw new Error("buyer has reached the per-wallet transaction limit.");
|
|
12879
13185
|
}
|
|
12880
13186
|
}
|
|
12881
|
-
if (plan.currency !== void 0 && !
|
|
13187
|
+
if (plan.currency !== void 0 && !isAddressEqual17(plan.currency, status.currencyAddress)) {
|
|
12882
13188
|
throw new Error(`expected currency ${plan.currency} does not match configured currency ${status.currencyAddress}.`);
|
|
12883
13189
|
}
|
|
12884
13190
|
const price = plan.price === void 0 ? status.price : normalizeReleasePrice({
|
|
@@ -13012,11 +13318,11 @@ function requireReleaseAccountCounter(value, label) {
|
|
|
13012
13318
|
return value;
|
|
13013
13319
|
}
|
|
13014
13320
|
function normalizeBytes322(value, field) {
|
|
13015
|
-
if (typeof value !== "string" || !
|
|
13321
|
+
if (typeof value !== "string" || !isHex5(value) || value.length !== 66) {
|
|
13016
13322
|
throw new Error(`${field} must be a 32-byte hex string.`);
|
|
13017
13323
|
}
|
|
13018
13324
|
const normalized = value.toLocaleLowerCase();
|
|
13019
|
-
if (!
|
|
13325
|
+
if (!isHex5(normalized) || normalized.length !== 66) {
|
|
13020
13326
|
throw new Error(`${field} must be a 32-byte hex string.`);
|
|
13021
13327
|
}
|
|
13022
13328
|
return normalized;
|
|
@@ -13086,11 +13392,11 @@ function normalizeAllowlistRows(rows) {
|
|
|
13086
13392
|
throw new Error(`Invalid allowlist address at ${row.label}: expected a string.`);
|
|
13087
13393
|
}
|
|
13088
13394
|
const raw = row.value.trim();
|
|
13089
|
-
if (!
|
|
13395
|
+
if (!isAddress7(raw)) {
|
|
13090
13396
|
throw new Error(`Invalid allowlist address at ${row.label}: "${raw}".`);
|
|
13091
13397
|
}
|
|
13092
|
-
const address =
|
|
13093
|
-
const duplicate = state.seen.find((seen) =>
|
|
13398
|
+
const address = getAddress11(raw);
|
|
13399
|
+
const duplicate = state.seen.find((seen) => isAddressEqual17(seen.address, address));
|
|
13094
13400
|
if (duplicate !== void 0) {
|
|
13095
13401
|
throw new Error(`Duplicate allowlist address at ${row.label}: "${address}" duplicates ${duplicate.label}.`);
|
|
13096
13402
|
}
|
|
@@ -13104,7 +13410,7 @@ function getAddressFromJsonAllowlistEntry(entry, label) {
|
|
|
13104
13410
|
if (typeof entry === "string") {
|
|
13105
13411
|
return entry;
|
|
13106
13412
|
}
|
|
13107
|
-
if (!
|
|
13413
|
+
if (!isRecord6(entry)) {
|
|
13108
13414
|
throw new Error(`Invalid allowlist ${label}: expected a string or object.`);
|
|
13109
13415
|
}
|
|
13110
13416
|
if ("address" in entry) return entry.address;
|
|
@@ -13146,11 +13452,11 @@ function getMerkleRoot(layers) {
|
|
|
13146
13452
|
return root;
|
|
13147
13453
|
}
|
|
13148
13454
|
function hashAllowlistAddress(address) {
|
|
13149
|
-
return
|
|
13455
|
+
return keccak2563(address);
|
|
13150
13456
|
}
|
|
13151
13457
|
function hashMerklePair(a, b) {
|
|
13152
13458
|
const [left, right] = compareHex(a, b) <= 0 ? [a, b] : [b, a];
|
|
13153
|
-
return
|
|
13459
|
+
return keccak2563(`0x${left.slice(2)}${right.slice(2)}`);
|
|
13154
13460
|
}
|
|
13155
13461
|
function compareAddress(a, b) {
|
|
13156
13462
|
return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
|
|
@@ -13159,12 +13465,12 @@ function compareHex(a, b) {
|
|
|
13159
13465
|
return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
|
|
13160
13466
|
}
|
|
13161
13467
|
function addressesEqual(a, b) {
|
|
13162
|
-
return
|
|
13468
|
+
return isAddressEqual17(a, b);
|
|
13163
13469
|
}
|
|
13164
13470
|
function hexEquals(a, b) {
|
|
13165
13471
|
return a.toLocaleLowerCase() === b.toLocaleLowerCase();
|
|
13166
13472
|
}
|
|
13167
|
-
function
|
|
13473
|
+
function isRecord6(value) {
|
|
13168
13474
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13169
13475
|
}
|
|
13170
13476
|
function parseJsonUnknown(input, label) {
|
|
@@ -13414,7 +13720,7 @@ function readMintDirectSaleTokenRange(opts) {
|
|
|
13414
13720
|
eventName: "MintDirectSale",
|
|
13415
13721
|
logs: opts.receipt.logs
|
|
13416
13722
|
}).filter(
|
|
13417
|
-
(log2) =>
|
|
13723
|
+
(log2) => isAddressEqual18(log2.args._contractAddress, opts.contract) && isAddressEqual18(log2.args._buyer, opts.buyer)
|
|
13418
13724
|
);
|
|
13419
13725
|
if (event === void 0) {
|
|
13420
13726
|
throw new Error(`MintDirectSale event was not found for ${opts.contract} and buyer ${opts.buyer}.`);
|
|
@@ -14782,214 +15088,6 @@ function contractSupportError(operation, contract, cause) {
|
|
|
14782
15088
|
);
|
|
14783
15089
|
}
|
|
14784
15090
|
|
|
14785
|
-
// src/sdk/merkle-core.ts
|
|
14786
|
-
import { Buffer } from "buffer";
|
|
14787
|
-
import { MerkleTree } from "merkletreejs";
|
|
14788
|
-
import {
|
|
14789
|
-
encodePacked as encodePacked3,
|
|
14790
|
-
getAddress as getAddress11,
|
|
14791
|
-
isAddress as isAddress7,
|
|
14792
|
-
isAddressEqual as isAddressEqual18,
|
|
14793
|
-
isHex as isHex5,
|
|
14794
|
-
keccak256 as keccak2563
|
|
14795
|
-
} from "viem";
|
|
14796
|
-
function hexBuffer(hex) {
|
|
14797
|
-
return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
|
|
14798
|
-
}
|
|
14799
|
-
function tokenLeaf(contract, tokenId) {
|
|
14800
|
-
const packed = encodePacked3(["address", "uint256"], [contract, tokenId]);
|
|
14801
|
-
return hexBuffer(keccak2563(packed));
|
|
14802
|
-
}
|
|
14803
|
-
function addressLeaf(address) {
|
|
14804
|
-
return hexBuffer(keccak2563(address));
|
|
14805
|
-
}
|
|
14806
|
-
function parseBytes32(value, field) {
|
|
14807
|
-
if (!isHex5(value, { strict: true }) || value.length !== 66) {
|
|
14808
|
-
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
14809
|
-
}
|
|
14810
|
-
const normalized = value.toLowerCase();
|
|
14811
|
-
if (!isHex5(normalized, { strict: true }) || normalized.length !== 66) {
|
|
14812
|
-
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
14813
|
-
}
|
|
14814
|
-
return normalized;
|
|
14815
|
-
}
|
|
14816
|
-
function parseBytes32Array(values, field) {
|
|
14817
|
-
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
14818
|
-
}
|
|
14819
|
-
function compareTokenEntries(a, b) {
|
|
14820
|
-
if (!isAddressEqual18(a.contract, b.contract)) {
|
|
14821
|
-
return a.contract.localeCompare(b.contract);
|
|
14822
|
-
}
|
|
14823
|
-
return a.tokenId.localeCompare(b.tokenId);
|
|
14824
|
-
}
|
|
14825
|
-
function normalizeTokenEntry(token) {
|
|
14826
|
-
if (!isAddress7(token.contract)) {
|
|
14827
|
-
throw new Error(`Invalid token contract address: ${token.contract}`);
|
|
14828
|
-
}
|
|
14829
|
-
return {
|
|
14830
|
-
contract: getAddress11(token.contract),
|
|
14831
|
-
tokenId: String(token.tokenId),
|
|
14832
|
-
tokenIdBigInt: toInteger(token.tokenId, "tokenId")
|
|
14833
|
-
};
|
|
14834
|
-
}
|
|
14835
|
-
function buildBatchListingTree(tokens) {
|
|
14836
|
-
if (tokens.length < 2) {
|
|
14837
|
-
throw new Error("buildBatchListingTree requires at least two tokens");
|
|
14838
|
-
}
|
|
14839
|
-
const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
|
|
14840
|
-
const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
|
|
14841
|
-
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2563(data)), {
|
|
14842
|
-
sortPairs: true
|
|
14843
|
-
});
|
|
14844
|
-
return {
|
|
14845
|
-
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
14846
|
-
tree,
|
|
14847
|
-
sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
|
|
14848
|
-
};
|
|
14849
|
-
}
|
|
14850
|
-
function buildAllowListTree(addresses) {
|
|
14851
|
-
if (addresses.length < 2) {
|
|
14852
|
-
throw new Error("buildAllowListTree requires at least two addresses");
|
|
14853
|
-
}
|
|
14854
|
-
const sorted = addresses.map((address) => {
|
|
14855
|
-
if (!isAddress7(address)) throw new Error(`Invalid allowlist address: ${address}`);
|
|
14856
|
-
return getAddress11(address);
|
|
14857
|
-
}).sort((a, b) => a.localeCompare(b));
|
|
14858
|
-
const leaves = sorted.map(addressLeaf);
|
|
14859
|
-
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2563(data)), {
|
|
14860
|
-
sortPairs: true
|
|
14861
|
-
});
|
|
14862
|
-
return {
|
|
14863
|
-
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
14864
|
-
tree,
|
|
14865
|
-
sortedAddresses: sorted
|
|
14866
|
-
};
|
|
14867
|
-
}
|
|
14868
|
-
function getTokenProof(tree, contract, tokenId) {
|
|
14869
|
-
const leaf = tokenLeaf(getAddress11(contract), tokenId);
|
|
14870
|
-
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
14871
|
-
}
|
|
14872
|
-
function getAddressProof(tree, address) {
|
|
14873
|
-
const leaf = addressLeaf(getAddress11(address));
|
|
14874
|
-
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
14875
|
-
}
|
|
14876
|
-
function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
14877
|
-
const tokenIdBig = toInteger(tokenId, "tokenId");
|
|
14878
|
-
const contractChecksum = getAddress11(contract);
|
|
14879
|
-
const found = artifact.tokens.find(
|
|
14880
|
-
(token) => isAddressEqual18(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
|
|
14881
|
-
);
|
|
14882
|
-
if (found === void 0) {
|
|
14883
|
-
throw new Error(
|
|
14884
|
-
`Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
|
|
14885
|
-
);
|
|
14886
|
-
}
|
|
14887
|
-
const { tree, root } = buildBatchListingTree(
|
|
14888
|
-
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
14889
|
-
);
|
|
14890
|
-
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
14891
|
-
if (root !== artifactRoot) {
|
|
14892
|
-
throw new Error(
|
|
14893
|
-
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
14894
|
-
);
|
|
14895
|
-
}
|
|
14896
|
-
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
14897
|
-
return {
|
|
14898
|
-
root: artifactRoot,
|
|
14899
|
-
contract: contractChecksum,
|
|
14900
|
-
tokenId: tokenIdBig.toString(),
|
|
14901
|
-
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
14902
|
-
...allowListProofFields ?? {}
|
|
14903
|
-
};
|
|
14904
|
-
}
|
|
14905
|
-
function buildAllowListProofFields(artifact, buyer) {
|
|
14906
|
-
if (artifact.allowList === void 0) return void 0;
|
|
14907
|
-
if (buyer === void 0) {
|
|
14908
|
-
throw new Error(
|
|
14909
|
-
"This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
|
|
14910
|
-
);
|
|
14911
|
-
}
|
|
14912
|
-
if (!isAddress7(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
|
|
14913
|
-
const buyerChecksum = getAddress11(buyer);
|
|
14914
|
-
const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual18(address, buyerChecksum));
|
|
14915
|
-
if (!inAllowList) {
|
|
14916
|
-
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
14917
|
-
}
|
|
14918
|
-
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
14919
|
-
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
14920
|
-
if (root !== artifactAllowListRoot) {
|
|
14921
|
-
throw new Error(
|
|
14922
|
-
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
14923
|
-
);
|
|
14924
|
-
}
|
|
14925
|
-
return {
|
|
14926
|
-
allowListProof: getAddressProof(tree, buyerChecksum),
|
|
14927
|
-
allowListAddress: buyerChecksum
|
|
14928
|
-
};
|
|
14929
|
-
}
|
|
14930
|
-
function assertRecord(value, field) {
|
|
14931
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
14932
|
-
throw new Error(`${field} must be a JSON object`);
|
|
14933
|
-
}
|
|
14934
|
-
}
|
|
14935
|
-
function assertHexRoot(value, field) {
|
|
14936
|
-
if (typeof value !== "string" || !isHex5(value, { strict: true }) || value.length !== 66) {
|
|
14937
|
-
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
14938
|
-
}
|
|
14939
|
-
}
|
|
14940
|
-
function assertAddress(value, field) {
|
|
14941
|
-
if (typeof value !== "string" || !isAddress7(value)) {
|
|
14942
|
-
throw new Error(`${field} must be a valid 0x address`);
|
|
14943
|
-
}
|
|
14944
|
-
}
|
|
14945
|
-
function validateRootArtifact(value) {
|
|
14946
|
-
assertRecord(value, "Root artifact");
|
|
14947
|
-
assertHexRoot(value.root, "root");
|
|
14948
|
-
assertAddress(value.currency, "currency");
|
|
14949
|
-
if (typeof value.amount !== "string") throw new Error("amount must be a string (base units)");
|
|
14950
|
-
if (!Array.isArray(value.splitAddresses)) throw new Error("splitAddresses must be an array");
|
|
14951
|
-
if (!Array.isArray(value.splitRatios)) throw new Error("splitRatios must be an array");
|
|
14952
|
-
if (!Array.isArray(value.tokens) || value.tokens.length < 2) {
|
|
14953
|
-
throw new Error("tokens must contain at least two entries");
|
|
14954
|
-
}
|
|
14955
|
-
value.tokens.forEach((token) => {
|
|
14956
|
-
assertRecord(token, "tokens[]");
|
|
14957
|
-
assertAddress(token.contract, "tokens[].contract");
|
|
14958
|
-
if (typeof token.tokenId !== "string") throw new Error("tokens[].tokenId must be a string");
|
|
14959
|
-
});
|
|
14960
|
-
if (value.allowList !== void 0 && value.allowList !== null) {
|
|
14961
|
-
assertRecord(value.allowList, "allowList");
|
|
14962
|
-
assertHexRoot(value.allowList.root, "allowList.root");
|
|
14963
|
-
if (!Array.isArray(value.allowList.addresses)) throw new Error("allowList.addresses must be an array");
|
|
14964
|
-
if (value.allowList.addresses.length < 2) {
|
|
14965
|
-
throw new Error("allowList.addresses must contain at least two entries");
|
|
14966
|
-
}
|
|
14967
|
-
value.allowList.addresses.forEach((address) => {
|
|
14968
|
-
assertAddress(address, "allowList.addresses entry");
|
|
14969
|
-
});
|
|
14970
|
-
}
|
|
14971
|
-
}
|
|
14972
|
-
function validateProofArtifact(value) {
|
|
14973
|
-
assertRecord(value, "Proof artifact");
|
|
14974
|
-
assertHexRoot(value.root, "root");
|
|
14975
|
-
assertAddress(value.contract, "contract");
|
|
14976
|
-
if (typeof value.tokenId !== "string") throw new Error("tokenId must be a string");
|
|
14977
|
-
if (!Array.isArray(value.proof)) throw new Error("proof must be an array of bytes32 hex");
|
|
14978
|
-
if (value.proof.length === 0) throw new Error("proof must not be empty");
|
|
14979
|
-
value.proof.forEach((proof) => {
|
|
14980
|
-
assertHexRoot(proof, "proof entry");
|
|
14981
|
-
});
|
|
14982
|
-
if (value.allowListProof !== void 0 && value.allowListProof !== null) {
|
|
14983
|
-
if (!Array.isArray(value.allowListProof)) throw new Error("allowListProof must be an array");
|
|
14984
|
-
value.allowListProof.forEach((proof) => {
|
|
14985
|
-
assertHexRoot(proof, "allowListProof entry");
|
|
14986
|
-
});
|
|
14987
|
-
}
|
|
14988
|
-
if (value.allowListAddress !== void 0 && value.allowListAddress !== null) {
|
|
14989
|
-
assertAddress(value.allowListAddress, "allowListAddress");
|
|
14990
|
-
}
|
|
14991
|
-
}
|
|
14992
|
-
|
|
14993
15091
|
// src/sdk/utils.ts
|
|
14994
15092
|
function createUtilsNamespace() {
|
|
14995
15093
|
return {
|
|
@@ -15168,7 +15266,7 @@ function createRareClient(config) {
|
|
|
15168
15266
|
};
|
|
15169
15267
|
}
|
|
15170
15268
|
function assertNoClientChainOverride(params, method, chain) {
|
|
15171
|
-
if (!
|
|
15269
|
+
if (!isRecord7(params)) return;
|
|
15172
15270
|
if (!Object.prototype.hasOwnProperty.call(params, "chain") && !Object.prototype.hasOwnProperty.call(params, "chainId")) {
|
|
15173
15271
|
return;
|
|
15174
15272
|
}
|
|
@@ -15176,7 +15274,7 @@ function assertNoClientChainOverride(params, method, chain) {
|
|
|
15176
15274
|
`${method} uses the RareClient chain (${chain}). Create another RareClient with a different publicClient to use another chain.`
|
|
15177
15275
|
);
|
|
15178
15276
|
}
|
|
15179
|
-
function
|
|
15277
|
+
function isRecord7(value) {
|
|
15180
15278
|
return typeof value === "object" && value !== null;
|
|
15181
15279
|
}
|
|
15182
15280
|
|
|
@@ -16216,12 +16314,15 @@ function createUtilsMerkleCommand() {
|
|
|
16216
16314
|
}
|
|
16217
16315
|
function addBatchListingCommands(cmd) {
|
|
16218
16316
|
cmd.addCommand(createBatchListingListCommand());
|
|
16219
|
-
cmd.command("create").description("Register a sale-price Merkle root from a root artifact").requiredOption("--input <path>", "path to a root artifact JSON file").option("--
|
|
16220
|
-
|
|
16221
|
-
|
|
16317
|
+
cmd.command("create").description("Register a sale-price Merkle root from a root artifact or token tree artifact").requiredOption("--input <path>", "path to a root artifact JSON file, token tree artifact, CSV, or JSON token list").option("--format <format>", "input format for --input (csv, json)").option("--currency <currency>", "currency: eth, usdc, rare, or ERC20 address (defaults to eth for token tree inputs)").option("--price <amount>", "listing price in ETH or token units (required for token tree inputs)").option(
|
|
16318
|
+
"--split <addr=ratio>",
|
|
16319
|
+
"seller payout split recipient (repeatable). Format: 0xADDR=RATIO. Ratios must sum to 100. If omitted, 100% goes to the connected wallet.",
|
|
16320
|
+
collectSplit
|
|
16321
|
+
).option("--yes", "yes to all prompts and required approvals").option("--chain <chain>", "chain to use (mainnet, sepolia)").option("--chain-id <id>", "chain ID (1, 11155111)").action(async (opts) => {
|
|
16222
16322
|
const chain = getActiveChain(opts.chain, opts.chainId);
|
|
16223
|
-
const { client } = getWalletClient(chain);
|
|
16224
16323
|
const publicClient = getPublicClient(chain);
|
|
16324
|
+
const artifact = await resolveBatchListingCreateArtifact(opts, { chain, publicClient });
|
|
16325
|
+
const { client } = getWalletClient(chain);
|
|
16225
16326
|
const rare = createRareClient({ publicClient, walletClient: client });
|
|
16226
16327
|
log(`Registering batch listing on ${chain}...`);
|
|
16227
16328
|
log(` Marketplace contract: ${rare.contracts.batchListing}`);
|
|
@@ -16230,6 +16331,15 @@ function addBatchListingCommands(cmd) {
|
|
|
16230
16331
|
log(
|
|
16231
16332
|
` Amount: ${await formatBatchAmount(publicClient, chain, artifact.currency, BigInt(artifact.amount))} ${isAddressEqual19(artifact.currency, ETH_ADDRESS) ? "ETH" : artifact.currency}`
|
|
16232
16333
|
);
|
|
16334
|
+
if (artifact.splitAddresses.length > 0) {
|
|
16335
|
+
log(" Splits:");
|
|
16336
|
+
formatSplitLines({
|
|
16337
|
+
addresses: artifact.splitAddresses,
|
|
16338
|
+
ratios: artifact.splitRatios
|
|
16339
|
+
}).forEach((line) => {
|
|
16340
|
+
log(line);
|
|
16341
|
+
});
|
|
16342
|
+
}
|
|
16233
16343
|
log(` Auto-approve NFTs: ${opts.yes === true ? "yes" : "no"}`);
|
|
16234
16344
|
const result = await runWithNftApprovalConsent({
|
|
16235
16345
|
commandName: "rare listing batch create",
|
|
@@ -16438,6 +16548,61 @@ async function readBatchTreeArtifact(opts) {
|
|
|
16438
16548
|
chainId: resolveTreeChainId(opts)
|
|
16439
16549
|
});
|
|
16440
16550
|
}
|
|
16551
|
+
async function resolveBatchListingCreateArtifact(opts, context) {
|
|
16552
|
+
const content = await readFile2(opts.input, "utf8");
|
|
16553
|
+
const parsedObject = parseJsonObjectInput(content);
|
|
16554
|
+
const splits = finalizeSplits(opts.split);
|
|
16555
|
+
const rootArtifact = parsedObject === void 0 ? void 0 : parseBatchListingCreateRootArtifactInput(parsedObject);
|
|
16556
|
+
if (rootArtifact !== void 0) {
|
|
16557
|
+
const currencyOverride = opts.currency === void 0 ? void 0 : resolveCurrency(opts.currency, context.chain);
|
|
16558
|
+
const amountOverride = opts.price === void 0 ? void 0 : (await parseBatchAmount(
|
|
16559
|
+
context.publicClient,
|
|
16560
|
+
context.chain,
|
|
16561
|
+
currencyOverride ?? rootArtifact.currency,
|
|
16562
|
+
opts.price
|
|
16563
|
+
)).toString();
|
|
16564
|
+
return planBatchListingCreateArtifact({
|
|
16565
|
+
kind: "root-artifact",
|
|
16566
|
+
artifact: rootArtifact,
|
|
16567
|
+
currencyOverride,
|
|
16568
|
+
amountOverride,
|
|
16569
|
+
splitAddresses: splits?.addresses,
|
|
16570
|
+
splitRatios: splits?.ratios
|
|
16571
|
+
});
|
|
16572
|
+
}
|
|
16573
|
+
if (opts.price === void 0) {
|
|
16574
|
+
throw new Error(
|
|
16575
|
+
"rare listing batch create requires --price when --input is a token tree artifact from rare utils tree build."
|
|
16576
|
+
);
|
|
16577
|
+
}
|
|
16578
|
+
const currency = opts.currency === void 0 ? ETH_ADDRESS : resolveCurrency(opts.currency, context.chain);
|
|
16579
|
+
const amount = await parseBatchAmount(context.publicClient, context.chain, currency, opts.price);
|
|
16580
|
+
const tokenTreeArtifact = parseBatchTokenListArtifactOrBuild({
|
|
16581
|
+
content,
|
|
16582
|
+
format: parseFormatOption(opts.format),
|
|
16583
|
+
sourceName: opts.input,
|
|
16584
|
+
chainId: resolveTreeChainId(opts)
|
|
16585
|
+
});
|
|
16586
|
+
return planBatchListingCreateArtifact({
|
|
16587
|
+
kind: "token-tree",
|
|
16588
|
+
artifact: tokenTreeArtifact,
|
|
16589
|
+
currency,
|
|
16590
|
+
amount: amount.toString(),
|
|
16591
|
+
splitAddresses: splits?.addresses,
|
|
16592
|
+
splitRatios: splits?.ratios
|
|
16593
|
+
});
|
|
16594
|
+
}
|
|
16595
|
+
function parseJsonObjectInput(content) {
|
|
16596
|
+
const trimmed = content.trimStart();
|
|
16597
|
+
if (!trimmed.startsWith("{")) {
|
|
16598
|
+
return void 0;
|
|
16599
|
+
}
|
|
16600
|
+
const parsed = JSON.parse(content);
|
|
16601
|
+
return isRecord8(parsed) ? parsed : void 0;
|
|
16602
|
+
}
|
|
16603
|
+
function isRecord8(value) {
|
|
16604
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16605
|
+
}
|
|
16441
16606
|
function resolveTreeChainId(opts) {
|
|
16442
16607
|
if (opts.chain === void 0) {
|
|
16443
16608
|
return opts.chainId;
|
|
@@ -17472,7 +17637,7 @@ function writeJsonFile(filePath, data) {
|
|
|
17472
17637
|
function errorMessage3(error) {
|
|
17473
17638
|
return error instanceof Error ? error.message : String(error);
|
|
17474
17639
|
}
|
|
17475
|
-
function
|
|
17640
|
+
function isRecord9(value) {
|
|
17476
17641
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17477
17642
|
}
|
|
17478
17643
|
function detectAllowlistFormat(filePath, format) {
|
|
@@ -17503,7 +17668,7 @@ function loadAllowlistArtifact(filePath) {
|
|
|
17503
17668
|
function readProofFile(filePath) {
|
|
17504
17669
|
const content = readTextFile(filePath, "allowlist proof");
|
|
17505
17670
|
const parsed = parseProofJson(content);
|
|
17506
|
-
const proof = Array.isArray(parsed) ? parsed :
|
|
17671
|
+
const proof = Array.isArray(parsed) ? parsed : isRecord9(parsed) && Array.isArray(parsed.proof) ? parsed.proof : void 0;
|
|
17507
17672
|
if (proof === void 0) {
|
|
17508
17673
|
throw new Error("--proof must be a JSON array or an object with a proof array.");
|
|
17509
17674
|
}
|
|
@@ -18196,7 +18361,7 @@ var MintMetadataOptionsError = class extends Error {
|
|
|
18196
18361
|
function parseMintAttribute(raw) {
|
|
18197
18362
|
if (raw.startsWith("{")) {
|
|
18198
18363
|
const parsed = JSON.parse(raw);
|
|
18199
|
-
if (
|
|
18364
|
+
if (isRecord10(parsed)) {
|
|
18200
18365
|
assertFiniteAttributeNumber(parsed.value, "value", raw);
|
|
18201
18366
|
assertFiniteAttributeNumber(parsed.max_value, "max_value", raw);
|
|
18202
18367
|
}
|
|
@@ -18224,7 +18389,7 @@ function assertFiniteAttributeNumber(value, field, raw) {
|
|
|
18224
18389
|
}
|
|
18225
18390
|
}
|
|
18226
18391
|
function isMintAttribute(value) {
|
|
18227
|
-
if (!
|
|
18392
|
+
if (!isRecord10(value) || !isAttributeValue(value.value)) {
|
|
18228
18393
|
return false;
|
|
18229
18394
|
}
|
|
18230
18395
|
return typeof value.trait_type === "string" && (value.display_type === void 0 || isDisplayType(value.display_type)) && (value.max_value === void 0 || typeof value.max_value === "number" && Number.isFinite(value.max_value));
|
|
@@ -18235,7 +18400,7 @@ function isAttributeValue(value) {
|
|
|
18235
18400
|
function isDisplayType(value) {
|
|
18236
18401
|
return value === "number" || value === "boost_number" || value === "boost_percentage" || value === "date";
|
|
18237
18402
|
}
|
|
18238
|
-
function
|
|
18403
|
+
function isRecord10(value) {
|
|
18239
18404
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18240
18405
|
}
|
|
18241
18406
|
function planMintTokenUri(params) {
|
|
@@ -18470,7 +18635,7 @@ var DISPLAY_TYPES = [
|
|
|
18470
18635
|
function isDisplayType2(value) {
|
|
18471
18636
|
return DISPLAY_TYPES.some((displayType) => displayType === value);
|
|
18472
18637
|
}
|
|
18473
|
-
function
|
|
18638
|
+
function isRecord11(value) {
|
|
18474
18639
|
return typeof value === "object" && value !== null;
|
|
18475
18640
|
}
|
|
18476
18641
|
function parseAttributeValue(value, raw) {
|
|
@@ -18514,7 +18679,7 @@ function parseDisplayType(value, raw) {
|
|
|
18514
18679
|
}
|
|
18515
18680
|
function parseAttributeJson(raw) {
|
|
18516
18681
|
const parsed = parseJson3(raw);
|
|
18517
|
-
if (!
|
|
18682
|
+
if (!isRecord11(parsed) || parsed.value === void 0) {
|
|
18518
18683
|
throw new Error(`Attribute JSON must include "value": ${raw}`);
|
|
18519
18684
|
}
|
|
18520
18685
|
const trait_type = parseOptionalString2(parsed.trait_type, "trait_type", raw) ?? "value";
|
|
@@ -20556,7 +20721,7 @@ function serializeForMcp(value) {
|
|
|
20556
20721
|
if (Array.isArray(value)) {
|
|
20557
20722
|
return value.map(serializeForMcp);
|
|
20558
20723
|
}
|
|
20559
|
-
if (
|
|
20724
|
+
if (isRecord12(value)) {
|
|
20560
20725
|
return Object.fromEntries(
|
|
20561
20726
|
Object.entries(value).map(([key, nested]) => [key, serializeForMcp(nested)]).filter(([, nested]) => nested !== void 0)
|
|
20562
20727
|
);
|
|
@@ -20564,11 +20729,11 @@ function serializeForMcp(value) {
|
|
|
20564
20729
|
return value;
|
|
20565
20730
|
}
|
|
20566
20731
|
function shapeMcpTransactionResult(value, extra = {}) {
|
|
20567
|
-
if (!
|
|
20732
|
+
if (!isRecord12(value)) {
|
|
20568
20733
|
return value;
|
|
20569
20734
|
}
|
|
20570
20735
|
const { receipt, ...shaped } = value;
|
|
20571
|
-
if (
|
|
20736
|
+
if (isRecord12(receipt) && Object.prototype.hasOwnProperty.call(receipt, "blockNumber")) {
|
|
20572
20737
|
return { ...shaped, blockNumber: receipt.blockNumber, ...extra };
|
|
20573
20738
|
}
|
|
20574
20739
|
return { ...shaped, ...extra };
|
|
@@ -20579,7 +20744,7 @@ function maskSecret2(value) {
|
|
|
20579
20744
|
function camelToSnake(value) {
|
|
20580
20745
|
return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
|
|
20581
20746
|
}
|
|
20582
|
-
function
|
|
20747
|
+
function isRecord12(value) {
|
|
20583
20748
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20584
20749
|
}
|
|
20585
20750
|
|
|
@@ -21238,7 +21403,7 @@ function requiresExplicitConfirmation(commandPath2) {
|
|
|
21238
21403
|
// package.json
|
|
21239
21404
|
var package_default = {
|
|
21240
21405
|
name: "@rareprotocol/rare-cli",
|
|
21241
|
-
version: "1.2.
|
|
21406
|
+
version: "1.2.2",
|
|
21242
21407
|
description: "CLI tool for interacting with the RARE protocol smart contracts",
|
|
21243
21408
|
type: "module",
|
|
21244
21409
|
license: "MIT",
|