@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/index.js
CHANGED
|
@@ -5675,7 +5675,7 @@ function createListingNamespace(publicClient, config, chain, addresses) {
|
|
|
5675
5675
|
}
|
|
5676
5676
|
|
|
5677
5677
|
// src/sdk/batch-listing.ts
|
|
5678
|
-
import { isAddressEqual as
|
|
5678
|
+
import { isAddressEqual as isAddressEqual11 } from "viem";
|
|
5679
5679
|
|
|
5680
5680
|
// src/contracts/abis/batch-listing.ts
|
|
5681
5681
|
var batchListingAbi = [
|
|
@@ -5933,15 +5933,18 @@ function parseBatchTokenList(params) {
|
|
|
5933
5933
|
const rawTokens = format === "json" ? parseJsonBatchTokens(params.content) : parseCsvBatchTokens(params.content);
|
|
5934
5934
|
return normalizeBatchTokens(rawTokens, params.chainId);
|
|
5935
5935
|
}
|
|
5936
|
-
function parseBatchTokenListArtifact(content) {
|
|
5936
|
+
function parseBatchTokenListArtifact(content, chainIdInput) {
|
|
5937
5937
|
const parsed = parseJson(content, "batch token artifact");
|
|
5938
5938
|
if (!isRecord2(parsed)) {
|
|
5939
5939
|
throw new Error("Batch token artifact must be a JSON object.");
|
|
5940
5940
|
}
|
|
5941
|
-
if (parsed.type !== "rare-batch-token-list") {
|
|
5941
|
+
if (parsed.type !== void 0 && parsed.type !== "rare-batch-token-list") {
|
|
5942
5942
|
throw new Error('Batch token artifact type must be "rare-batch-token-list".');
|
|
5943
5943
|
}
|
|
5944
|
-
if (parsed.
|
|
5944
|
+
if (parsed.type === void 0 && !isUntypedBatchTokenListArtifactLike(parsed)) {
|
|
5945
|
+
throw new Error('Batch token artifact type must be "rare-batch-token-list".');
|
|
5946
|
+
}
|
|
5947
|
+
if (parsed.version !== void 0 && parsed.version !== 1) {
|
|
5945
5948
|
throw new Error("Batch token artifact version must be 1.");
|
|
5946
5949
|
}
|
|
5947
5950
|
if (typeof parsed.root !== "string") {
|
|
@@ -5950,11 +5953,19 @@ function parseBatchTokenListArtifact(content) {
|
|
|
5950
5953
|
if (!Array.isArray(parsed.tokens)) {
|
|
5951
5954
|
throw new Error("Batch token artifact tokens must be an array.");
|
|
5952
5955
|
}
|
|
5956
|
+
const parsedChainId = parsed.chainId === void 0 ? void 0 : parseUnknownInteger(parsed.chainId, "artifact chainId");
|
|
5957
|
+
const expectedChainId = chainIdInput === void 0 ? void 0 : normalizeChainId(chainIdInput, "chainId");
|
|
5958
|
+
const artifactChainId = parsedChainId ?? expectedChainId;
|
|
5959
|
+
if (parsedChainId !== void 0 && expectedChainId !== void 0 && normalizeChainId(parsedChainId, "artifact chainId") !== expectedChainId) {
|
|
5960
|
+
throw new Error(
|
|
5961
|
+
`Input chainId ${normalizeChainId(parsedChainId, "artifact chainId")} does not match --chain-id ${expectedChainId}.`
|
|
5962
|
+
);
|
|
5963
|
+
}
|
|
5953
5964
|
const artifact = buildBatchTokenTreeArtifact({
|
|
5954
5965
|
content: JSON.stringify(parsed.tokens),
|
|
5955
5966
|
format: "json",
|
|
5956
5967
|
sourceName: "batch token artifact tokens",
|
|
5957
|
-
chainId:
|
|
5968
|
+
chainId: artifactChainId
|
|
5958
5969
|
});
|
|
5959
5970
|
const root = normalizeBytes32(parsed.root, "artifact root");
|
|
5960
5971
|
if (typeof parsed.count === "number" && parsed.count !== artifact.count) {
|
|
@@ -5968,12 +5979,15 @@ function parseBatchTokenListArtifact(content) {
|
|
|
5968
5979
|
function parseBatchTokenListArtifactOrBuild(params) {
|
|
5969
5980
|
if (params.content.trimStart().startsWith("{")) {
|
|
5970
5981
|
const parsed = parseJson(params.content, "batch token JSON");
|
|
5971
|
-
if (isRecord2(parsed) && parsed.type === "rare-batch-token-list") {
|
|
5972
|
-
return parseBatchTokenListArtifact(params.content);
|
|
5982
|
+
if (isRecord2(parsed) && (parsed.type === "rare-batch-token-list" || isUntypedBatchTokenListArtifactLike(parsed))) {
|
|
5983
|
+
return parseBatchTokenListArtifact(params.content, params.chainId);
|
|
5973
5984
|
}
|
|
5974
5985
|
}
|
|
5975
5986
|
return buildBatchTokenTreeArtifact(params);
|
|
5976
5987
|
}
|
|
5988
|
+
function isUntypedBatchTokenListArtifactLike(value) {
|
|
5989
|
+
return typeof value.root === "string" && Array.isArray(value.tokens) && !("currency" in value) && !("amount" in value) && !("splitAddresses" in value) && !("splitRatios" in value);
|
|
5990
|
+
}
|
|
5977
5991
|
function getBatchTokenProof(params) {
|
|
5978
5992
|
const contractAddress = normalizeAddressValue(params.contractAddress, "contractAddress");
|
|
5979
5993
|
const tokenId = normalizeTokenId(params.tokenId, "tokenId");
|
|
@@ -6535,13 +6549,251 @@ function uniqueRoots(roots) {
|
|
|
6535
6549
|
}
|
|
6536
6550
|
|
|
6537
6551
|
// src/sdk/batch-listing-core.ts
|
|
6538
|
-
import { isAddressEqual as
|
|
6552
|
+
import { isAddressEqual as isAddressEqual10 } from "viem";
|
|
6553
|
+
|
|
6554
|
+
// src/sdk/merkle-core.ts
|
|
6555
|
+
import { Buffer } from "buffer";
|
|
6556
|
+
import { MerkleTree } from "merkletreejs";
|
|
6557
|
+
import {
|
|
6558
|
+
encodePacked as encodePacked2,
|
|
6559
|
+
getAddress as getAddress7,
|
|
6560
|
+
isAddress as isAddress6,
|
|
6561
|
+
isAddressEqual as isAddressEqual9,
|
|
6562
|
+
isHex as isHex3,
|
|
6563
|
+
keccak256 as keccak2562
|
|
6564
|
+
} from "viem";
|
|
6565
|
+
function hexBuffer(hex) {
|
|
6566
|
+
return Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex");
|
|
6567
|
+
}
|
|
6568
|
+
function tokenLeaf(contract, tokenId) {
|
|
6569
|
+
const packed = encodePacked2(["address", "uint256"], [contract, tokenId]);
|
|
6570
|
+
return hexBuffer(keccak2562(packed));
|
|
6571
|
+
}
|
|
6572
|
+
function addressLeaf(address) {
|
|
6573
|
+
return hexBuffer(keccak2562(address));
|
|
6574
|
+
}
|
|
6575
|
+
function parseBytes32(value, field) {
|
|
6576
|
+
if (!isHex3(value, { strict: true }) || value.length !== 66) {
|
|
6577
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
6578
|
+
}
|
|
6579
|
+
const normalized = value.toLowerCase();
|
|
6580
|
+
if (!isHex3(normalized, { strict: true }) || normalized.length !== 66) {
|
|
6581
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
6582
|
+
}
|
|
6583
|
+
return normalized;
|
|
6584
|
+
}
|
|
6585
|
+
function parseBytes32Array(values, field) {
|
|
6586
|
+
return values.map((value, index) => parseBytes32(value, `${field}[${index}]`));
|
|
6587
|
+
}
|
|
6588
|
+
function compareTokenEntries(a, b) {
|
|
6589
|
+
if (!isAddressEqual9(a.contract, b.contract)) {
|
|
6590
|
+
return a.contract.localeCompare(b.contract);
|
|
6591
|
+
}
|
|
6592
|
+
return a.tokenId.localeCompare(b.tokenId);
|
|
6593
|
+
}
|
|
6594
|
+
function normalizeTokenEntry(token) {
|
|
6595
|
+
if (!isAddress6(token.contract)) {
|
|
6596
|
+
throw new Error(`Invalid token contract address: ${token.contract}`);
|
|
6597
|
+
}
|
|
6598
|
+
return {
|
|
6599
|
+
contract: getAddress7(token.contract),
|
|
6600
|
+
tokenId: String(token.tokenId),
|
|
6601
|
+
tokenIdBigInt: toInteger(token.tokenId, "tokenId")
|
|
6602
|
+
};
|
|
6603
|
+
}
|
|
6604
|
+
function buildBatchListingTree(tokens) {
|
|
6605
|
+
if (tokens.length < 2) {
|
|
6606
|
+
throw new Error("buildBatchListingTree requires at least two tokens");
|
|
6607
|
+
}
|
|
6608
|
+
const sorted = tokens.map(normalizeTokenEntry).sort(compareTokenEntries);
|
|
6609
|
+
const leaves = sorted.map((token) => tokenLeaf(token.contract, token.tokenIdBigInt));
|
|
6610
|
+
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
|
|
6611
|
+
sortPairs: true
|
|
6612
|
+
});
|
|
6613
|
+
return {
|
|
6614
|
+
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
6615
|
+
tree,
|
|
6616
|
+
sortedTokens: sorted.map(({ contract, tokenId }) => ({ contract, tokenId }))
|
|
6617
|
+
};
|
|
6618
|
+
}
|
|
6619
|
+
function buildAllowListTree(addresses) {
|
|
6620
|
+
if (addresses.length < 2) {
|
|
6621
|
+
throw new Error("buildAllowListTree requires at least two addresses");
|
|
6622
|
+
}
|
|
6623
|
+
const sorted = addresses.map((address) => {
|
|
6624
|
+
if (!isAddress6(address)) throw new Error(`Invalid allowlist address: ${address}`);
|
|
6625
|
+
return getAddress7(address);
|
|
6626
|
+
}).sort((a, b) => a.localeCompare(b));
|
|
6627
|
+
const leaves = sorted.map(addressLeaf);
|
|
6628
|
+
const tree = new MerkleTree(leaves, (data) => hexBuffer(keccak2562(data)), {
|
|
6629
|
+
sortPairs: true
|
|
6630
|
+
});
|
|
6631
|
+
return {
|
|
6632
|
+
root: parseBytes32(tree.getHexRoot(), "root"),
|
|
6633
|
+
tree,
|
|
6634
|
+
sortedAddresses: sorted
|
|
6635
|
+
};
|
|
6636
|
+
}
|
|
6637
|
+
function getTokenProof(tree, contract, tokenId) {
|
|
6638
|
+
const leaf = tokenLeaf(getAddress7(contract), tokenId);
|
|
6639
|
+
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
6640
|
+
}
|
|
6641
|
+
function getAddressProof(tree, address) {
|
|
6642
|
+
const leaf = addressLeaf(getAddress7(address));
|
|
6643
|
+
return parseBytes32Array(tree.getHexProof(leaf), "proof");
|
|
6644
|
+
}
|
|
6645
|
+
function buildMerkleProofArtifact(artifact, contract, tokenId, buyer) {
|
|
6646
|
+
const tokenIdBig = toInteger(tokenId, "tokenId");
|
|
6647
|
+
const contractChecksum = getAddress7(contract);
|
|
6648
|
+
const found = artifact.tokens.find(
|
|
6649
|
+
(token) => isAddressEqual9(token.contract, contractChecksum) && BigInt(token.tokenId) === tokenIdBig
|
|
6650
|
+
);
|
|
6651
|
+
if (found === void 0) {
|
|
6652
|
+
throw new Error(
|
|
6653
|
+
`Token ${contractChecksum}/${tokenIdBig.toString()} is not in this root artifact's token set`
|
|
6654
|
+
);
|
|
6655
|
+
}
|
|
6656
|
+
const { tree, root } = buildBatchListingTree(
|
|
6657
|
+
artifact.tokens.map((token) => ({ contract: token.contract, tokenId: token.tokenId }))
|
|
6658
|
+
);
|
|
6659
|
+
const artifactRoot = parseBytes32(artifact.root, "artifact.root");
|
|
6660
|
+
if (root !== artifactRoot) {
|
|
6661
|
+
throw new Error(
|
|
6662
|
+
`Recomputed NFT tree root (${root}) does not match artifact root (${artifact.root}). Artifact is corrupt or tree encoding has drifted.`
|
|
6663
|
+
);
|
|
6664
|
+
}
|
|
6665
|
+
const allowListProofFields = buildAllowListProofFields(artifact, buyer);
|
|
6666
|
+
return {
|
|
6667
|
+
root: artifactRoot,
|
|
6668
|
+
contract: contractChecksum,
|
|
6669
|
+
tokenId: tokenIdBig.toString(),
|
|
6670
|
+
proof: getTokenProof(tree, contractChecksum, tokenIdBig),
|
|
6671
|
+
...allowListProofFields ?? {}
|
|
6672
|
+
};
|
|
6673
|
+
}
|
|
6674
|
+
function buildAllowListProofFields(artifact, buyer) {
|
|
6675
|
+
if (artifact.allowList === void 0) return void 0;
|
|
6676
|
+
if (buyer === void 0) {
|
|
6677
|
+
throw new Error(
|
|
6678
|
+
"This root has an allowlist; pass buyer address to buildMerkleProofArtifact to include allowListProof"
|
|
6679
|
+
);
|
|
6680
|
+
}
|
|
6681
|
+
if (!isAddress6(buyer)) throw new Error(`Invalid buyer address: ${buyer}`);
|
|
6682
|
+
const buyerChecksum = getAddress7(buyer);
|
|
6683
|
+
const inAllowList = artifact.allowList.addresses.some((address) => isAddressEqual9(address, buyerChecksum));
|
|
6684
|
+
if (!inAllowList) {
|
|
6685
|
+
throw new Error(`Buyer ${buyerChecksum} is not in the allowlist`);
|
|
6686
|
+
}
|
|
6687
|
+
const { tree, root } = buildAllowListTree(artifact.allowList.addresses);
|
|
6688
|
+
const artifactAllowListRoot = parseBytes32(artifact.allowList.root, "allowList.root");
|
|
6689
|
+
if (root !== artifactAllowListRoot) {
|
|
6690
|
+
throw new Error(
|
|
6691
|
+
`Recomputed allowlist root (${root}) does not match artifact (${artifact.allowList.root})`
|
|
6692
|
+
);
|
|
6693
|
+
}
|
|
6694
|
+
return {
|
|
6695
|
+
allowListProof: getAddressProof(tree, buyerChecksum),
|
|
6696
|
+
allowListAddress: buyerChecksum
|
|
6697
|
+
};
|
|
6698
|
+
}
|
|
6699
|
+
function assertRecord(value, field) {
|
|
6700
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
6701
|
+
throw new Error(`${field} must be a JSON object`);
|
|
6702
|
+
}
|
|
6703
|
+
}
|
|
6704
|
+
function assertHexRoot(value, field) {
|
|
6705
|
+
if (typeof value !== "string" || !isHex3(value, { strict: true }) || value.length !== 66) {
|
|
6706
|
+
throw new Error(`${field} must be a 0x-prefixed bytes32 hex string`);
|
|
6707
|
+
}
|
|
6708
|
+
}
|
|
6709
|
+
function assertAddress(value, field) {
|
|
6710
|
+
if (typeof value !== "string" || !isAddress6(value)) {
|
|
6711
|
+
throw new Error(`${field} must be a valid 0x address`);
|
|
6712
|
+
}
|
|
6713
|
+
}
|
|
6714
|
+
function validateRootArtifact(value) {
|
|
6715
|
+
assertRecord(value, "Root artifact");
|
|
6716
|
+
if (isBatchTokenTreeArtifactLike(value)) {
|
|
6717
|
+
throw new Error(
|
|
6718
|
+
"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."
|
|
6719
|
+
);
|
|
6720
|
+
}
|
|
6721
|
+
assertHexRoot(value.root, "root");
|
|
6722
|
+
assertAddress(value.currency, "currency");
|
|
6723
|
+
if (typeof value.amount !== "string") throw new Error("amount must be a string (base units)");
|
|
6724
|
+
if (!Array.isArray(value.splitAddresses)) throw new Error("splitAddresses must be an array");
|
|
6725
|
+
if (!Array.isArray(value.splitRatios)) throw new Error("splitRatios must be an array");
|
|
6726
|
+
if (!Array.isArray(value.tokens) || value.tokens.length < 2) {
|
|
6727
|
+
throw new Error("tokens must contain at least two entries");
|
|
6728
|
+
}
|
|
6729
|
+
value.tokens.forEach((token) => {
|
|
6730
|
+
assertRecord(token, "tokens[]");
|
|
6731
|
+
assertAddress(token.contract, "tokens[].contract");
|
|
6732
|
+
if (typeof token.tokenId !== "string") throw new Error("tokens[].tokenId must be a string");
|
|
6733
|
+
});
|
|
6734
|
+
if (value.allowList !== void 0 && value.allowList !== null) {
|
|
6735
|
+
assertRecord(value.allowList, "allowList");
|
|
6736
|
+
assertHexRoot(value.allowList.root, "allowList.root");
|
|
6737
|
+
if (!Array.isArray(value.allowList.addresses)) throw new Error("allowList.addresses must be an array");
|
|
6738
|
+
if (value.allowList.addresses.length < 2) {
|
|
6739
|
+
throw new Error("allowList.addresses must contain at least two entries");
|
|
6740
|
+
}
|
|
6741
|
+
value.allowList.addresses.forEach((address) => {
|
|
6742
|
+
assertAddress(address, "allowList.addresses entry");
|
|
6743
|
+
});
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
function isBatchTokenTreeArtifactLike(value) {
|
|
6747
|
+
if (value.type === "rare-batch-token-list") {
|
|
6748
|
+
return true;
|
|
6749
|
+
}
|
|
6750
|
+
return Array.isArray(value.tokens) && !("currency" in value) && !("amount" in value) && !("splitAddresses" in value) && !("splitRatios" in value);
|
|
6751
|
+
}
|
|
6752
|
+
function validateProofArtifact(value) {
|
|
6753
|
+
assertRecord(value, "Proof artifact");
|
|
6754
|
+
assertHexRoot(value.root, "root");
|
|
6755
|
+
assertAddress(value.contract, "contract");
|
|
6756
|
+
if (typeof value.tokenId !== "string") throw new Error("tokenId must be a string");
|
|
6757
|
+
if (!Array.isArray(value.proof)) throw new Error("proof must be an array of bytes32 hex");
|
|
6758
|
+
if (value.proof.length === 0) throw new Error("proof must not be empty");
|
|
6759
|
+
value.proof.forEach((proof) => {
|
|
6760
|
+
assertHexRoot(proof, "proof entry");
|
|
6761
|
+
});
|
|
6762
|
+
if (value.allowListProof !== void 0 && value.allowListProof !== null) {
|
|
6763
|
+
if (!Array.isArray(value.allowListProof)) throw new Error("allowListProof must be an array");
|
|
6764
|
+
value.allowListProof.forEach((proof) => {
|
|
6765
|
+
assertHexRoot(proof, "allowListProof entry");
|
|
6766
|
+
});
|
|
6767
|
+
}
|
|
6768
|
+
if (value.allowListAddress !== void 0 && value.allowListAddress !== null) {
|
|
6769
|
+
assertAddress(value.allowListAddress, "allowListAddress");
|
|
6770
|
+
}
|
|
6771
|
+
}
|
|
6772
|
+
|
|
6773
|
+
// src/sdk/batch-listing-core.ts
|
|
6539
6774
|
function uniqueAddresses(addresses) {
|
|
6540
6775
|
return addresses.reduce(
|
|
6541
|
-
(unique, address) => unique.some((existing) =>
|
|
6776
|
+
(unique, address) => unique.some((existing) => isAddressEqual10(existing, address)) ? unique : [...unique, address],
|
|
6542
6777
|
[]
|
|
6543
6778
|
);
|
|
6544
6779
|
}
|
|
6780
|
+
function parseBatchListingCreateRootArtifactInput(value) {
|
|
6781
|
+
if (!isRecord3(value)) {
|
|
6782
|
+
validateRootArtifact(value);
|
|
6783
|
+
throw new Error("unreachable: non-object root artifact validation did not throw");
|
|
6784
|
+
}
|
|
6785
|
+
if (isBatchTokenTreeInputObject(value)) {
|
|
6786
|
+
return void 0;
|
|
6787
|
+
}
|
|
6788
|
+
validateRootArtifact(value);
|
|
6789
|
+
return value;
|
|
6790
|
+
}
|
|
6791
|
+
function planBatchListingCreateArtifact(plan) {
|
|
6792
|
+
const splitOverride = planOptionalSplitOverride(plan.splitAddresses, plan.splitRatios);
|
|
6793
|
+
const artifact = plan.kind === "root-artifact" ? planBatchListingCreateRootArtifact(plan, splitOverride) : planBatchListingCreateTokenTreeArtifact(plan, splitOverride);
|
|
6794
|
+
planBatchListingRootRegistrationLocalInputs(artifact);
|
|
6795
|
+
return artifact;
|
|
6796
|
+
}
|
|
6545
6797
|
function planBatchListingRootRegistration(artifact, accountAddress) {
|
|
6546
6798
|
const local = planBatchListingRootRegistrationLocalInputs(artifact);
|
|
6547
6799
|
if (local !== void 0) {
|
|
@@ -6550,6 +6802,54 @@ function planBatchListingRootRegistration(artifact, accountAddress) {
|
|
|
6550
6802
|
const splits = planPayoutSplits(void 0, void 0, accountAddress);
|
|
6551
6803
|
return { splitAddresses: splits.addresses, splitRatios: splits.ratios };
|
|
6552
6804
|
}
|
|
6805
|
+
function planBatchListingCreateRootArtifact(plan, splitOverride) {
|
|
6806
|
+
if (plan.currencyOverride !== void 0 && plan.amountOverride === void 0) {
|
|
6807
|
+
throw new Error("--currency requires --price when overriding a batch listing root artifact.");
|
|
6808
|
+
}
|
|
6809
|
+
return {
|
|
6810
|
+
...plan.artifact,
|
|
6811
|
+
currency: plan.currencyOverride ?? plan.artifact.currency,
|
|
6812
|
+
amount: plan.amountOverride ?? plan.artifact.amount,
|
|
6813
|
+
...splitOverride === void 0 ? {} : {
|
|
6814
|
+
splitAddresses: splitOverride.addresses,
|
|
6815
|
+
splitRatios: splitOverride.ratios
|
|
6816
|
+
}
|
|
6817
|
+
};
|
|
6818
|
+
}
|
|
6819
|
+
function planBatchListingCreateTokenTreeArtifact(plan, splitOverride) {
|
|
6820
|
+
return {
|
|
6821
|
+
root: plan.artifact.root,
|
|
6822
|
+
currency: plan.currency,
|
|
6823
|
+
amount: plan.amount,
|
|
6824
|
+
splitAddresses: splitOverride?.addresses ?? [],
|
|
6825
|
+
splitRatios: splitOverride?.ratios ?? [],
|
|
6826
|
+
tokens: plan.artifact.tokens.map((token) => ({
|
|
6827
|
+
contract: token.contractAddress,
|
|
6828
|
+
tokenId: token.tokenId
|
|
6829
|
+
}))
|
|
6830
|
+
};
|
|
6831
|
+
}
|
|
6832
|
+
function planOptionalSplitOverride(splitAddresses, splitRatios) {
|
|
6833
|
+
if (splitAddresses === void 0 && splitRatios === void 0) {
|
|
6834
|
+
return void 0;
|
|
6835
|
+
}
|
|
6836
|
+
if (splitAddresses === void 0 || splitRatios === void 0) {
|
|
6837
|
+
throw new Error("splitAddresses and splitRatios must both be provided.");
|
|
6838
|
+
}
|
|
6839
|
+
return planProvidedPayoutSplits(splitAddresses, splitRatios);
|
|
6840
|
+
}
|
|
6841
|
+
function isBatchTokenTreeInputObject(value) {
|
|
6842
|
+
if (value.type === "rare-batch-token-list") {
|
|
6843
|
+
return true;
|
|
6844
|
+
}
|
|
6845
|
+
if ("currency" in value || "amount" in value || "splitAddresses" in value || "splitRatios" in value || !Array.isArray(value.tokens)) {
|
|
6846
|
+
return false;
|
|
6847
|
+
}
|
|
6848
|
+
return true;
|
|
6849
|
+
}
|
|
6850
|
+
function isRecord3(value) {
|
|
6851
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6852
|
+
}
|
|
6553
6853
|
function planBatchListingRootRegistrationLocalInputs(artifact) {
|
|
6554
6854
|
if (artifact.tokens.length < 2) {
|
|
6555
6855
|
throw new Error("Root artifact must contain at least two tokens; the batch listing contract rejects empty proofs");
|
|
@@ -6582,7 +6882,7 @@ function shapeBatchListingStatus(params) {
|
|
|
6582
6882
|
splitRecipients: [...params.listingConfig.splitRecipients],
|
|
6583
6883
|
splitRatios: [...params.listingConfig.splitRatios],
|
|
6584
6884
|
nonce: params.listingConfig.nonce,
|
|
6585
|
-
isEth:
|
|
6885
|
+
isEth: isAddressEqual10(params.listingConfig.currency, ETH_ADDRESS),
|
|
6586
6886
|
hasListing,
|
|
6587
6887
|
allowList: params.allowList,
|
|
6588
6888
|
...params.tokenStatus
|
|
@@ -6613,7 +6913,7 @@ function createBatchListingNamespace(publicClient, config, addresses) {
|
|
|
6613
6913
|
functionName: "ownerOf",
|
|
6614
6914
|
args: [BigInt(token.tokenId)]
|
|
6615
6915
|
});
|
|
6616
|
-
if (!
|
|
6916
|
+
if (!isAddressEqual11(owner, accountAddress)) {
|
|
6617
6917
|
throw new Error(
|
|
6618
6918
|
`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
6919
|
);
|
|
@@ -7061,7 +7361,7 @@ async function readTokenStatus(publicClient, batchListingAddress, params) {
|
|
|
7061
7361
|
|
|
7062
7362
|
// src/sdk/batch-auction.ts
|
|
7063
7363
|
import {
|
|
7064
|
-
isAddressEqual as
|
|
7364
|
+
isAddressEqual as isAddressEqual13,
|
|
7065
7365
|
parseUnits as parseUnits3,
|
|
7066
7366
|
parseEventLogs as parseEventLogs3
|
|
7067
7367
|
} from "viem";
|
|
@@ -7293,7 +7593,7 @@ var batchAuctionHouseAbi = [
|
|
|
7293
7593
|
];
|
|
7294
7594
|
|
|
7295
7595
|
// src/sdk/batch-auction-core.ts
|
|
7296
|
-
import { isAddressEqual as
|
|
7596
|
+
import { isAddressEqual as isAddressEqual12 } from "viem";
|
|
7297
7597
|
var zeroAddress3 = ETH_ADDRESS;
|
|
7298
7598
|
var marketplaceFeePercentage = 3n;
|
|
7299
7599
|
function planBatchAuctionCreateLocalInputs(params, nowSeconds) {
|
|
@@ -7384,7 +7684,7 @@ function planBatchAuctionStatus(params) {
|
|
|
7384
7684
|
};
|
|
7385
7685
|
}
|
|
7386
7686
|
function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
7387
|
-
const hasAuction = details.startingTime > 0n && !
|
|
7687
|
+
const hasAuction = details.startingTime > 0n && !isAddressEqual12(details.seller, zeroAddress3);
|
|
7388
7688
|
const hasCurrentRootConfig = rootContext !== void 0 && rootContext.config.duration > 0n && rootContext.rootNonce === rootContext.config.nonce;
|
|
7389
7689
|
const currentRootConfig = hasCurrentRootConfig ? rootContext.config : void 0;
|
|
7390
7690
|
const hasRootConfig = currentRootConfig !== void 0;
|
|
@@ -7392,7 +7692,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
7392
7692
|
const startingTime = hasAuction ? details.startingTime : 0n;
|
|
7393
7693
|
const endTime = hasAuction ? startingTime + duration : null;
|
|
7394
7694
|
const ended = endTime !== null && nowSeconds >= endTime;
|
|
7395
|
-
const currentBidder = currentBid.amount > 0n && !
|
|
7695
|
+
const currentBidder = currentBid.amount > 0n && !isAddressEqual12(currentBid.bidder, zeroAddress3) ? currentBid.bidder : null;
|
|
7396
7696
|
const seller = hasAuction ? details.seller : rootContext?.creator ?? zeroAddress3;
|
|
7397
7697
|
const currency = hasAuction ? details.currency : currentRootConfig?.currency ?? ETH_ADDRESS;
|
|
7398
7698
|
const reserveAmount = hasAuction ? details.reserveAmount : currentRootConfig?.reserveAmount ?? 0n;
|
|
@@ -7427,7 +7727,7 @@ function shapeBatchAuctionStatus(details, currentBid, rootContext, nowSeconds) {
|
|
|
7427
7727
|
hasRootConfig,
|
|
7428
7728
|
tokenNonceConsumed
|
|
7429
7729
|
}),
|
|
7430
|
-
isEth:
|
|
7730
|
+
isEth: isAddressEqual12(currency, ETH_ADDRESS)
|
|
7431
7731
|
};
|
|
7432
7732
|
}
|
|
7433
7733
|
function shapeBatchAuctionDetailsRead(details) {
|
|
@@ -7538,7 +7838,7 @@ function planSplitRecipients(splitAddresses, splitRatios, accountAddress) {
|
|
|
7538
7838
|
};
|
|
7539
7839
|
}
|
|
7540
7840
|
function uniqueAddresses2(addresses) {
|
|
7541
|
-
return addresses.reduce((unique, address) => unique.some((candidate) =>
|
|
7841
|
+
return addresses.reduce((unique, address) => unique.some((candidate) => isAddressEqual12(candidate, address)) ? unique : [...unique, address], []);
|
|
7542
7842
|
}
|
|
7543
7843
|
function addMinimumBidIncrease(amount) {
|
|
7544
7844
|
return amount + amount * marketplaceFeePercentage / 100n;
|
|
@@ -7712,7 +8012,7 @@ function createBatchAuctionNamespace(publicClient, config, chain) {
|
|
|
7712
8012
|
const price = requireInput(resolvedParams.price, "price");
|
|
7713
8013
|
const amount = typeof price === "bigint" ? price : parseUnits3(stringifyAmountInput(price, "price"), await resolveCurrencyDecimals(publicClient, chain, currency));
|
|
7714
8014
|
const plan = planBatchAuctionBid({ ...resolvedParams, currency, price: amount });
|
|
7715
|
-
const erc20ApprovalManager =
|
|
8015
|
+
const erc20ApprovalManager = isAddressEqual13(plan.currency, ETH_ADDRESS) ? batchAuctionHouse : requireContractAddress(chain, "erc20ApprovalManager");
|
|
7716
8016
|
const payment = await preparePaymentAmountForSpender({
|
|
7717
8017
|
publicClient,
|
|
7718
8018
|
walletClient,
|
|
@@ -8071,7 +8371,7 @@ async function resolveRootContext(opts) {
|
|
|
8071
8371
|
|
|
8072
8372
|
// src/sdk/batch-offer.ts
|
|
8073
8373
|
import {
|
|
8074
|
-
isAddressEqual as
|
|
8374
|
+
isAddressEqual as isAddressEqual15,
|
|
8075
8375
|
parseUnits as parseUnits4,
|
|
8076
8376
|
parseEventLogs as parseEventLogs4
|
|
8077
8377
|
} from "viem";
|
|
@@ -8178,7 +8478,7 @@ var batchOfferAbi = [
|
|
|
8178
8478
|
];
|
|
8179
8479
|
|
|
8180
8480
|
// src/sdk/batch-offer-core.ts
|
|
8181
|
-
import { isAddressEqual as
|
|
8481
|
+
import { isAddressEqual as isAddressEqual14 } from "viem";
|
|
8182
8482
|
var zeroAddress4 = ETH_ADDRESS;
|
|
8183
8483
|
var zeroBytes322 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
8184
8484
|
function planBatchOfferCreateLocalInputs(params, nowSeconds) {
|
|
@@ -8235,7 +8535,7 @@ function planBatchOfferAccept(params, accountAddress) {
|
|
|
8235
8535
|
};
|
|
8236
8536
|
}
|
|
8237
8537
|
function shapeBatchOfferStatus(offer, expected, nowSeconds) {
|
|
8238
|
-
const hasOffer = !
|
|
8538
|
+
const hasOffer = !isAddressEqual14(offer.creator, zeroAddress4) && offer.rootHash !== zeroBytes322 && offer.amount > 0n;
|
|
8239
8539
|
const expired = hasOffer && offer.expiry <= nowSeconds;
|
|
8240
8540
|
const state = !hasOffer ? "NONE" : expired ? "EXPIRED" : "ACTIVE";
|
|
8241
8541
|
return {
|
|
@@ -8250,7 +8550,7 @@ function shapeBatchOfferStatus(offer, expected, nowSeconds) {
|
|
|
8250
8550
|
revoked: hasOffer ? false : null,
|
|
8251
8551
|
fillable: hasOffer && !expired,
|
|
8252
8552
|
state,
|
|
8253
|
-
isEth:
|
|
8553
|
+
isEth: isAddressEqual14(offer.currency, ETH_ADDRESS)
|
|
8254
8554
|
};
|
|
8255
8555
|
}
|
|
8256
8556
|
function shapeBatchOfferRead(value) {
|
|
@@ -8440,7 +8740,7 @@ function createBatchOfferNamespace(publicClient, config, chain) {
|
|
|
8440
8740
|
functionName: "ownerOf",
|
|
8441
8741
|
args: [plan.tokenId]
|
|
8442
8742
|
});
|
|
8443
|
-
if (!
|
|
8743
|
+
if (!isAddressEqual15(owner, accountAddress)) {
|
|
8444
8744
|
throw new Error(`Connected wallet ${accountAddress} does not own token ${plan.contract} #${plan.tokenId.toString()}.`);
|
|
8445
8745
|
}
|
|
8446
8746
|
const approvalTxHash = await approveNftContractIfNeeded({
|
|
@@ -9159,7 +9459,7 @@ var CURVE_PRESET_DEFINITIONS = {
|
|
|
9159
9459
|
reserveTailStartTokenPriceUsd: 50
|
|
9160
9460
|
}
|
|
9161
9461
|
};
|
|
9162
|
-
function
|
|
9462
|
+
function isRecord4(value) {
|
|
9163
9463
|
return typeof value === "object" && value !== null;
|
|
9164
9464
|
}
|
|
9165
9465
|
function isPositiveFiniteNumber(value) {
|
|
@@ -9422,7 +9722,7 @@ function validateAndNormalizeSegments(rawSegments, totalCurveSupplyTokens, tickS
|
|
|
9422
9722
|
return { isValid: true, curves: sortedSegments };
|
|
9423
9723
|
}
|
|
9424
9724
|
function normalizeSegment(segment, tickSpacing) {
|
|
9425
|
-
if (!
|
|
9725
|
+
if (!isRecord4(segment)) {
|
|
9426
9726
|
return invalidSegmentResult();
|
|
9427
9727
|
}
|
|
9428
9728
|
const tickLower = toValidNumber(segment.tickLower);
|
|
@@ -10483,7 +10783,7 @@ var liquidRouterAbi = [
|
|
|
10483
10783
|
];
|
|
10484
10784
|
|
|
10485
10785
|
// src/swap/known-pools.ts
|
|
10486
|
-
import { getAddress as
|
|
10786
|
+
import { getAddress as getAddress8 } from "viem";
|
|
10487
10787
|
|
|
10488
10788
|
// src/swap/pool-core.ts
|
|
10489
10789
|
function normalizeAddress(value) {
|
|
@@ -10502,10 +10802,10 @@ function inferBaseCurrencyAddress(poolKey, token) {
|
|
|
10502
10802
|
|
|
10503
10803
|
// src/swap/known-pools.ts
|
|
10504
10804
|
var wrappedEthAddresses = {
|
|
10505
|
-
mainnet:
|
|
10506
|
-
sepolia:
|
|
10507
|
-
base:
|
|
10508
|
-
"base-sepolia":
|
|
10805
|
+
mainnet: getAddress8("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
|
|
10806
|
+
sepolia: getAddress8("0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"),
|
|
10807
|
+
base: getAddress8("0x4200000000000000000000000000000000000006"),
|
|
10808
|
+
"base-sepolia": getAddress8("0x4200000000000000000000000000000000000006")
|
|
10509
10809
|
};
|
|
10510
10810
|
function poolToKey(pool) {
|
|
10511
10811
|
return {
|
|
@@ -10820,8 +11120,8 @@ async function quoteRouteSteps(publicClient, quoterAddress, routeSteps, currentA
|
|
|
10820
11120
|
// src/swap/route-encoding.ts
|
|
10821
11121
|
import {
|
|
10822
11122
|
encodeAbiParameters as encodeAbiParameters2,
|
|
10823
|
-
encodePacked as
|
|
10824
|
-
getAddress as
|
|
11123
|
+
encodePacked as encodePacked3,
|
|
11124
|
+
getAddress as getAddress9,
|
|
10825
11125
|
parseAbiParameters
|
|
10826
11126
|
} from "viem";
|
|
10827
11127
|
var ROUTER_COMMANDS = {
|
|
@@ -10838,8 +11138,8 @@ var V4_ACTIONS = {
|
|
|
10838
11138
|
TAKE_ALL: 15
|
|
10839
11139
|
};
|
|
10840
11140
|
var ROUTER_RECIPIENTS = {
|
|
10841
|
-
msgSender:
|
|
10842
|
-
addressThis:
|
|
11141
|
+
msgSender: getAddress9("0x0000000000000000000000000000000000000001"),
|
|
11142
|
+
addressThis: getAddress9("0x0000000000000000000000000000000000000002")
|
|
10843
11143
|
};
|
|
10844
11144
|
var ROUTER_AMOUNT_CONSTANTS = {
|
|
10845
11145
|
openDelta: 0n,
|
|
@@ -10851,7 +11151,7 @@ function encodeRoute(quote, amountIn, currencyIn, currencyOut) {
|
|
|
10851
11151
|
}
|
|
10852
11152
|
const { commandBytes, inputs } = encodeRouteParts(quote, amountIn, currencyIn, currencyOut, 0);
|
|
10853
11153
|
return {
|
|
10854
|
-
commands:
|
|
11154
|
+
commands: encodePacked3(commandBytes.map(() => "uint8"), [...commandBytes]),
|
|
10855
11155
|
inputs
|
|
10856
11156
|
};
|
|
10857
11157
|
}
|
|
@@ -10982,7 +11282,7 @@ function encodeV4ExactIn({
|
|
|
10982
11282
|
if (singleStep === void 0) {
|
|
10983
11283
|
throw new Error("Missing V4 exact input single step.");
|
|
10984
11284
|
}
|
|
10985
|
-
const actions2 =
|
|
11285
|
+
const actions2 = encodePacked3(
|
|
10986
11286
|
["uint8", "uint8", "uint8"],
|
|
10987
11287
|
[settleAction, V4_ACTIONS.SWAP_EXACT_IN_SINGLE, takeAction]
|
|
10988
11288
|
);
|
|
@@ -10998,7 +11298,7 @@ function encodeV4ExactIn({
|
|
|
10998
11298
|
]
|
|
10999
11299
|
);
|
|
11000
11300
|
}
|
|
11001
|
-
const actions =
|
|
11301
|
+
const actions = encodePacked3(
|
|
11002
11302
|
["uint8", "uint8", "uint8"],
|
|
11003
11303
|
[V4_ACTIONS.SWAP_EXACT_IN, settleAction, takeAction]
|
|
11004
11304
|
);
|
|
@@ -11028,10 +11328,10 @@ function encodeV4ExactInSingle(step, amountIn, minAmountOut) {
|
|
|
11028
11328
|
}
|
|
11029
11329
|
|
|
11030
11330
|
// src/swap/uniswap-api.ts
|
|
11031
|
-
import { getAddress as
|
|
11331
|
+
import { getAddress as getAddress10, isHex as isHex4 } from "viem";
|
|
11032
11332
|
|
|
11033
11333
|
// src/swap/trade-core.ts
|
|
11034
|
-
import { isAddressEqual as
|
|
11334
|
+
import { isAddressEqual as isAddressEqual16 } from "viem";
|
|
11035
11335
|
function toTradeInteger(value, field) {
|
|
11036
11336
|
if (typeof value === "bigint") return value;
|
|
11037
11337
|
if (typeof value === "number") {
|
|
@@ -11099,7 +11399,7 @@ function buildLiquidRouterTradeQuote(params) {
|
|
|
11099
11399
|
}
|
|
11100
11400
|
function getQuotedRecipientAmount(quote, recipient) {
|
|
11101
11401
|
const recipientOutput = quote.aggregatedOutputs?.find(
|
|
11102
|
-
(output2) =>
|
|
11402
|
+
(output2) => isAddressEqual16(output2.recipient, recipient)
|
|
11103
11403
|
);
|
|
11104
11404
|
if (recipientOutput) {
|
|
11105
11405
|
return {
|
|
@@ -11118,7 +11418,7 @@ function assertSupportedUniswapRouting(routing) {
|
|
|
11118
11418
|
}
|
|
11119
11419
|
}
|
|
11120
11420
|
function assertRecipientSupportedForUniswapFallback(recipient, accountAddress) {
|
|
11121
|
-
if (recipient !== void 0 && !
|
|
11421
|
+
if (recipient !== void 0 && !isAddressEqual16(recipient, accountAddress)) {
|
|
11122
11422
|
throw new Error("recipient override is not supported for Uniswap API fallback routes.");
|
|
11123
11423
|
}
|
|
11124
11424
|
}
|
|
@@ -11177,7 +11477,7 @@ function requireApiKey(options) {
|
|
|
11177
11477
|
}
|
|
11178
11478
|
return apiKey;
|
|
11179
11479
|
}
|
|
11180
|
-
function
|
|
11480
|
+
function isRecord5(value) {
|
|
11181
11481
|
return typeof value === "object" && value !== null;
|
|
11182
11482
|
}
|
|
11183
11483
|
function parseString(value, field) {
|
|
@@ -11198,7 +11498,7 @@ function parseNumber(value, field) {
|
|
|
11198
11498
|
function parseAddress2(value, field) {
|
|
11199
11499
|
const raw = parseString(value, field);
|
|
11200
11500
|
try {
|
|
11201
|
-
return
|
|
11501
|
+
return getAddress10(raw);
|
|
11202
11502
|
} catch {
|
|
11203
11503
|
throw new Error(`Uniswap API response field "${field}" must be a valid EVM address.`);
|
|
11204
11504
|
}
|
|
@@ -11208,13 +11508,13 @@ function parseOptionalAddress2(value, field) {
|
|
|
11208
11508
|
}
|
|
11209
11509
|
function parseHex(value, field) {
|
|
11210
11510
|
const raw = parseString(value, field);
|
|
11211
|
-
if (!
|
|
11511
|
+
if (!isHex4(raw)) {
|
|
11212
11512
|
throw new Error(`Uniswap API response field "${field}" must be a hex string.`);
|
|
11213
11513
|
}
|
|
11214
11514
|
return raw;
|
|
11215
11515
|
}
|
|
11216
11516
|
function parseRecord(value, field) {
|
|
11217
|
-
if (!
|
|
11517
|
+
if (!isRecord5(value)) {
|
|
11218
11518
|
throw new Error(`Uniswap API response field "${field}" must be an object.`);
|
|
11219
11519
|
}
|
|
11220
11520
|
return value;
|
|
@@ -11381,7 +11681,7 @@ function parseUniswapSwapResponse(value) {
|
|
|
11381
11681
|
};
|
|
11382
11682
|
}
|
|
11383
11683
|
function getErrorMessage2(parsed) {
|
|
11384
|
-
if (
|
|
11684
|
+
if (isRecord5(parsed) && typeof parsed.message === "string") {
|
|
11385
11685
|
return parsed.message;
|
|
11386
11686
|
}
|
|
11387
11687
|
return void 0;
|
|
@@ -12060,7 +12360,7 @@ function createSwapNamespace(config, chain, chainId, addresses) {
|
|
|
12060
12360
|
import {
|
|
12061
12361
|
erc20Abi as erc20Abi2,
|
|
12062
12362
|
hexToBigInt as hexToBigInt2,
|
|
12063
|
-
isAddressEqual as
|
|
12363
|
+
isAddressEqual as isAddressEqual18,
|
|
12064
12364
|
parseEventLogs as parseEventLogs6
|
|
12065
12365
|
} from "viem";
|
|
12066
12366
|
|
|
@@ -12565,11 +12865,11 @@ function toRoyaltyPercentage(value) {
|
|
|
12565
12865
|
|
|
12566
12866
|
// src/sdk/release-core.ts
|
|
12567
12867
|
import {
|
|
12568
|
-
getAddress as
|
|
12569
|
-
isAddress as
|
|
12570
|
-
isAddressEqual as
|
|
12571
|
-
isHex as
|
|
12572
|
-
keccak256 as
|
|
12868
|
+
getAddress as getAddress11,
|
|
12869
|
+
isAddress as isAddress7,
|
|
12870
|
+
isAddressEqual as isAddressEqual17,
|
|
12871
|
+
isHex as isHex5,
|
|
12872
|
+
keccak256 as keccak2563,
|
|
12573
12873
|
parseEther as parseEther2,
|
|
12574
12874
|
parseUnits as parseUnits7
|
|
12575
12875
|
} from "viem";
|
|
@@ -12586,7 +12886,7 @@ function requireRareMinterAddress(address) {
|
|
|
12586
12886
|
}
|
|
12587
12887
|
function assertReleaseContractOwner(opts) {
|
|
12588
12888
|
const { contract, accountAddress, owner } = opts;
|
|
12589
|
-
if (!
|
|
12889
|
+
if (!isAddressEqual17(owner, accountAddress)) {
|
|
12590
12890
|
throw new Error(
|
|
12591
12891
|
`Connected wallet ${accountAddress} is not the owner of collection ${contract}. Contract owner is ${owner}.`
|
|
12592
12892
|
);
|
|
@@ -12734,7 +13034,7 @@ function parseReleaseAllowlistArtifactJson(input) {
|
|
|
12734
13034
|
return parseReleaseAllowlistArtifact(parsed);
|
|
12735
13035
|
}
|
|
12736
13036
|
function parseReleaseAllowlistArtifact(input) {
|
|
12737
|
-
if (!
|
|
13037
|
+
if (!isRecord6(input)) {
|
|
12738
13038
|
throw new Error("Allowlist artifact must be a JSON object.");
|
|
12739
13039
|
}
|
|
12740
13040
|
if (input.kind !== RELEASE_ALLOWLIST_ARTIFACT_KIND || input.version !== 1) {
|
|
@@ -12746,7 +13046,7 @@ function parseReleaseAllowlistArtifact(input) {
|
|
|
12746
13046
|
}
|
|
12747
13047
|
const wallets = normalizeAllowlistRows(
|
|
12748
13048
|
input.wallets.map((entry, index) => {
|
|
12749
|
-
if (!
|
|
13049
|
+
if (!isRecord6(entry)) {
|
|
12750
13050
|
throw new Error(`Invalid allowlist artifact wallet at index ${index}: expected an object.`);
|
|
12751
13051
|
}
|
|
12752
13052
|
return {
|
|
@@ -12775,7 +13075,7 @@ function parseReleaseAllowlistCsv(input) {
|
|
|
12775
13075
|
throw new Error("CSV allowlist is empty.");
|
|
12776
13076
|
}
|
|
12777
13077
|
const headerColumn = findAllowlistAddressColumn(firstRow.fields);
|
|
12778
|
-
if (headerColumn === -1 && !
|
|
13078
|
+
if (headerColumn === -1 && !isAddress7(firstRow.fields[0]?.trim() ?? "")) {
|
|
12779
13079
|
throw new Error("CSV allowlist must put wallet addresses in the first column or include an address/wallet header.");
|
|
12780
13080
|
}
|
|
12781
13081
|
const addressColumn = headerColumn === -1 ? 0 : headerColumn;
|
|
@@ -12790,10 +13090,10 @@ function parseReleaseAllowlistCsv(input) {
|
|
|
12790
13090
|
}
|
|
12791
13091
|
function parseReleaseAllowlistJson(input) {
|
|
12792
13092
|
const parsed = parseJsonUnknown(input, "Malformed JSON allowlist");
|
|
12793
|
-
if (
|
|
13093
|
+
if (isRecord6(parsed) && parsed.kind === RELEASE_ALLOWLIST_ARTIFACT_KIND) {
|
|
12794
13094
|
return parseReleaseAllowlistArtifact(parsed).wallets.map((wallet) => wallet.address);
|
|
12795
13095
|
}
|
|
12796
|
-
const entries = Array.isArray(parsed) ? parsed :
|
|
13096
|
+
const entries = Array.isArray(parsed) ? parsed : isRecord6(parsed) && Array.isArray(parsed.wallets) ? parsed.wallets : isRecord6(parsed) && Array.isArray(parsed.addresses) ? parsed.addresses : null;
|
|
12797
13097
|
if (!entries) {
|
|
12798
13098
|
throw new Error(
|
|
12799
13099
|
"JSON allowlist must be an array of wallet addresses, an array of objects with address/wallet, or an object with wallets/addresses."
|
|
@@ -12834,27 +13134,27 @@ function buildReleaseAllowlistArtifact(wallets) {
|
|
|
12834
13134
|
};
|
|
12835
13135
|
}
|
|
12836
13136
|
function getReleaseAllowlistProof(opts) {
|
|
12837
|
-
const address =
|
|
13137
|
+
const address = getAddress11(opts.address);
|
|
12838
13138
|
return opts.artifact.wallets.find((entry) => addressesEqual(entry.address, address)) ?? null;
|
|
12839
13139
|
}
|
|
12840
13140
|
function verifyReleaseAllowlistProof(opts) {
|
|
12841
13141
|
const root = normalizeBytes322(opts.root, "allowlist root");
|
|
12842
13142
|
const hash = opts.proof.reduce(
|
|
12843
13143
|
(current, sibling) => hashMerklePair(current, normalizeBytes322(sibling, "allowlist proof item")),
|
|
12844
|
-
hashAllowlistAddress(
|
|
13144
|
+
hashAllowlistAddress(getAddress11(opts.address))
|
|
12845
13145
|
);
|
|
12846
13146
|
return hexEquals(hash, root);
|
|
12847
13147
|
}
|
|
12848
13148
|
function preflightReleaseDirectSaleMint(params) {
|
|
12849
13149
|
const { status, plan, buyer, nowSeconds } = params;
|
|
12850
13150
|
const quantity = BigInt(plan.quantity);
|
|
12851
|
-
if (!
|
|
13151
|
+
if (!isAddressEqual17(status.contract, plan.contract)) {
|
|
12852
13152
|
throw new Error(`Release status is for ${status.contract}, but mint plan is for ${plan.contract}.`);
|
|
12853
13153
|
}
|
|
12854
13154
|
if (!status.configured) {
|
|
12855
13155
|
throw new Error("RareMinter direct sale is not configured for this contract.");
|
|
12856
13156
|
}
|
|
12857
|
-
if (plan.recipient !== void 0 && !
|
|
13157
|
+
if (plan.recipient !== void 0 && !isAddressEqual17(plan.recipient, buyer)) {
|
|
12858
13158
|
throw new Error("RareMinter direct sale mint does not support a separate recipient; it mints to the connected wallet.");
|
|
12859
13159
|
}
|
|
12860
13160
|
if (status.startTime > nowSeconds) {
|
|
@@ -12878,7 +13178,7 @@ function preflightReleaseDirectSaleMint(params) {
|
|
|
12878
13178
|
throw new Error("buyer has reached the per-wallet transaction limit.");
|
|
12879
13179
|
}
|
|
12880
13180
|
}
|
|
12881
|
-
if (plan.currency !== void 0 && !
|
|
13181
|
+
if (plan.currency !== void 0 && !isAddressEqual17(plan.currency, status.currencyAddress)) {
|
|
12882
13182
|
throw new Error(`expected currency ${plan.currency} does not match configured currency ${status.currencyAddress}.`);
|
|
12883
13183
|
}
|
|
12884
13184
|
const price = plan.price === void 0 ? status.price : normalizeReleasePrice({
|
|
@@ -13012,11 +13312,11 @@ function requireReleaseAccountCounter(value, label) {
|
|
|
13012
13312
|
return value;
|
|
13013
13313
|
}
|
|
13014
13314
|
function normalizeBytes322(value, field) {
|
|
13015
|
-
if (typeof value !== "string" || !
|
|
13315
|
+
if (typeof value !== "string" || !isHex5(value) || value.length !== 66) {
|
|
13016
13316
|
throw new Error(`${field} must be a 32-byte hex string.`);
|
|
13017
13317
|
}
|
|
13018
13318
|
const normalized = value.toLocaleLowerCase();
|
|
13019
|
-
if (!
|
|
13319
|
+
if (!isHex5(normalized) || normalized.length !== 66) {
|
|
13020
13320
|
throw new Error(`${field} must be a 32-byte hex string.`);
|
|
13021
13321
|
}
|
|
13022
13322
|
return normalized;
|
|
@@ -13086,11 +13386,11 @@ function normalizeAllowlistRows(rows) {
|
|
|
13086
13386
|
throw new Error(`Invalid allowlist address at ${row.label}: expected a string.`);
|
|
13087
13387
|
}
|
|
13088
13388
|
const raw = row.value.trim();
|
|
13089
|
-
if (!
|
|
13389
|
+
if (!isAddress7(raw)) {
|
|
13090
13390
|
throw new Error(`Invalid allowlist address at ${row.label}: "${raw}".`);
|
|
13091
13391
|
}
|
|
13092
|
-
const address =
|
|
13093
|
-
const duplicate = state.seen.find((seen) =>
|
|
13392
|
+
const address = getAddress11(raw);
|
|
13393
|
+
const duplicate = state.seen.find((seen) => isAddressEqual17(seen.address, address));
|
|
13094
13394
|
if (duplicate !== void 0) {
|
|
13095
13395
|
throw new Error(`Duplicate allowlist address at ${row.label}: "${address}" duplicates ${duplicate.label}.`);
|
|
13096
13396
|
}
|
|
@@ -13104,7 +13404,7 @@ function getAddressFromJsonAllowlistEntry(entry, label) {
|
|
|
13104
13404
|
if (typeof entry === "string") {
|
|
13105
13405
|
return entry;
|
|
13106
13406
|
}
|
|
13107
|
-
if (!
|
|
13407
|
+
if (!isRecord6(entry)) {
|
|
13108
13408
|
throw new Error(`Invalid allowlist ${label}: expected a string or object.`);
|
|
13109
13409
|
}
|
|
13110
13410
|
if ("address" in entry) return entry.address;
|
|
@@ -13146,11 +13446,11 @@ function getMerkleRoot(layers) {
|
|
|
13146
13446
|
return root;
|
|
13147
13447
|
}
|
|
13148
13448
|
function hashAllowlistAddress(address) {
|
|
13149
|
-
return
|
|
13449
|
+
return keccak2563(address);
|
|
13150
13450
|
}
|
|
13151
13451
|
function hashMerklePair(a, b) {
|
|
13152
13452
|
const [left, right] = compareHex(a, b) <= 0 ? [a, b] : [b, a];
|
|
13153
|
-
return
|
|
13453
|
+
return keccak2563(`0x${left.slice(2)}${right.slice(2)}`);
|
|
13154
13454
|
}
|
|
13155
13455
|
function compareAddress(a, b) {
|
|
13156
13456
|
return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
|
|
@@ -13159,12 +13459,12 @@ function compareHex(a, b) {
|
|
|
13159
13459
|
return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase());
|
|
13160
13460
|
}
|
|
13161
13461
|
function addressesEqual(a, b) {
|
|
13162
|
-
return
|
|
13462
|
+
return isAddressEqual17(a, b);
|
|
13163
13463
|
}
|
|
13164
13464
|
function hexEquals(a, b) {
|
|
13165
13465
|
return a.toLocaleLowerCase() === b.toLocaleLowerCase();
|
|
13166
13466
|
}
|
|
13167
|
-
function
|
|
13467
|
+
function isRecord6(value) {
|
|
13168
13468
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13169
13469
|
}
|
|
13170
13470
|
function parseJsonUnknown(input, label) {
|
|
@@ -13414,7 +13714,7 @@ function readMintDirectSaleTokenRange(opts) {
|
|
|
13414
13714
|
eventName: "MintDirectSale",
|
|
13415
13715
|
logs: opts.receipt.logs
|
|
13416
13716
|
}).filter(
|
|
13417
|
-
(log2) =>
|
|
13717
|
+
(log2) => isAddressEqual18(log2.args._contractAddress, opts.contract) && isAddressEqual18(log2.args._buyer, opts.buyer)
|
|
13418
13718
|
);
|
|
13419
13719
|
if (event === void 0) {
|
|
13420
13720
|
throw new Error(`MintDirectSale event was not found for ${opts.contract} and buyer ${opts.buyer}.`);
|
|
@@ -14782,214 +15082,6 @@ function contractSupportError(operation, contract, cause) {
|
|
|
14782
15082
|
);
|
|
14783
15083
|
}
|
|
14784
15084
|
|
|
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
15085
|
// src/sdk/utils.ts
|
|
14994
15086
|
function createUtilsNamespace() {
|
|
14995
15087
|
return {
|
|
@@ -15168,7 +15260,7 @@ function createRareClient(config) {
|
|
|
15168
15260
|
};
|
|
15169
15261
|
}
|
|
15170
15262
|
function assertNoClientChainOverride(params, method, chain) {
|
|
15171
|
-
if (!
|
|
15263
|
+
if (!isRecord7(params)) return;
|
|
15172
15264
|
if (!Object.prototype.hasOwnProperty.call(params, "chain") && !Object.prototype.hasOwnProperty.call(params, "chainId")) {
|
|
15173
15265
|
return;
|
|
15174
15266
|
}
|
|
@@ -15176,7 +15268,7 @@ function assertNoClientChainOverride(params, method, chain) {
|
|
|
15176
15268
|
`${method} uses the RareClient chain (${chain}). Create another RareClient with a different publicClient to use another chain.`
|
|
15177
15269
|
);
|
|
15178
15270
|
}
|
|
15179
|
-
function
|
|
15271
|
+
function isRecord7(value) {
|
|
15180
15272
|
return typeof value === "object" && value !== null;
|
|
15181
15273
|
}
|
|
15182
15274
|
|
|
@@ -16216,12 +16308,15 @@ function createUtilsMerkleCommand() {
|
|
|
16216
16308
|
}
|
|
16217
16309
|
function addBatchListingCommands(cmd) {
|
|
16218
16310
|
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
|
-
|
|
16311
|
+
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(
|
|
16312
|
+
"--split <addr=ratio>",
|
|
16313
|
+
"seller payout split recipient (repeatable). Format: 0xADDR=RATIO. Ratios must sum to 100. If omitted, 100% goes to the connected wallet.",
|
|
16314
|
+
collectSplit
|
|
16315
|
+
).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
16316
|
const chain = getActiveChain(opts.chain, opts.chainId);
|
|
16223
|
-
const { client } = getWalletClient(chain);
|
|
16224
16317
|
const publicClient = getPublicClient(chain);
|
|
16318
|
+
const artifact = await resolveBatchListingCreateArtifact(opts, { chain, publicClient });
|
|
16319
|
+
const { client } = getWalletClient(chain);
|
|
16225
16320
|
const rare = createRareClient({ publicClient, walletClient: client });
|
|
16226
16321
|
log(`Registering batch listing on ${chain}...`);
|
|
16227
16322
|
log(` Marketplace contract: ${rare.contracts.batchListing}`);
|
|
@@ -16230,6 +16325,15 @@ function addBatchListingCommands(cmd) {
|
|
|
16230
16325
|
log(
|
|
16231
16326
|
` Amount: ${await formatBatchAmount(publicClient, chain, artifact.currency, BigInt(artifact.amount))} ${isAddressEqual19(artifact.currency, ETH_ADDRESS) ? "ETH" : artifact.currency}`
|
|
16232
16327
|
);
|
|
16328
|
+
if (artifact.splitAddresses.length > 0) {
|
|
16329
|
+
log(" Splits:");
|
|
16330
|
+
formatSplitLines({
|
|
16331
|
+
addresses: artifact.splitAddresses,
|
|
16332
|
+
ratios: artifact.splitRatios
|
|
16333
|
+
}).forEach((line) => {
|
|
16334
|
+
log(line);
|
|
16335
|
+
});
|
|
16336
|
+
}
|
|
16233
16337
|
log(` Auto-approve NFTs: ${opts.yes === true ? "yes" : "no"}`);
|
|
16234
16338
|
const result = await runWithNftApprovalConsent({
|
|
16235
16339
|
commandName: "rare listing batch create",
|
|
@@ -16438,6 +16542,61 @@ async function readBatchTreeArtifact(opts) {
|
|
|
16438
16542
|
chainId: resolveTreeChainId(opts)
|
|
16439
16543
|
});
|
|
16440
16544
|
}
|
|
16545
|
+
async function resolveBatchListingCreateArtifact(opts, context) {
|
|
16546
|
+
const content = await readFile2(opts.input, "utf8");
|
|
16547
|
+
const parsedObject = parseJsonObjectInput(content);
|
|
16548
|
+
const splits = finalizeSplits(opts.split);
|
|
16549
|
+
const rootArtifact = parsedObject === void 0 ? void 0 : parseBatchListingCreateRootArtifactInput(parsedObject);
|
|
16550
|
+
if (rootArtifact !== void 0) {
|
|
16551
|
+
const currencyOverride = opts.currency === void 0 ? void 0 : resolveCurrency(opts.currency, context.chain);
|
|
16552
|
+
const amountOverride = opts.price === void 0 ? void 0 : (await parseBatchAmount(
|
|
16553
|
+
context.publicClient,
|
|
16554
|
+
context.chain,
|
|
16555
|
+
currencyOverride ?? rootArtifact.currency,
|
|
16556
|
+
opts.price
|
|
16557
|
+
)).toString();
|
|
16558
|
+
return planBatchListingCreateArtifact({
|
|
16559
|
+
kind: "root-artifact",
|
|
16560
|
+
artifact: rootArtifact,
|
|
16561
|
+
currencyOverride,
|
|
16562
|
+
amountOverride,
|
|
16563
|
+
splitAddresses: splits?.addresses,
|
|
16564
|
+
splitRatios: splits?.ratios
|
|
16565
|
+
});
|
|
16566
|
+
}
|
|
16567
|
+
if (opts.price === void 0) {
|
|
16568
|
+
throw new Error(
|
|
16569
|
+
"rare listing batch create requires --price when --input is a token tree artifact from rare utils tree build."
|
|
16570
|
+
);
|
|
16571
|
+
}
|
|
16572
|
+
const currency = opts.currency === void 0 ? ETH_ADDRESS : resolveCurrency(opts.currency, context.chain);
|
|
16573
|
+
const amount = await parseBatchAmount(context.publicClient, context.chain, currency, opts.price);
|
|
16574
|
+
const tokenTreeArtifact = parseBatchTokenListArtifactOrBuild({
|
|
16575
|
+
content,
|
|
16576
|
+
format: parseFormatOption(opts.format),
|
|
16577
|
+
sourceName: opts.input,
|
|
16578
|
+
chainId: resolveTreeChainId(opts)
|
|
16579
|
+
});
|
|
16580
|
+
return planBatchListingCreateArtifact({
|
|
16581
|
+
kind: "token-tree",
|
|
16582
|
+
artifact: tokenTreeArtifact,
|
|
16583
|
+
currency,
|
|
16584
|
+
amount: amount.toString(),
|
|
16585
|
+
splitAddresses: splits?.addresses,
|
|
16586
|
+
splitRatios: splits?.ratios
|
|
16587
|
+
});
|
|
16588
|
+
}
|
|
16589
|
+
function parseJsonObjectInput(content) {
|
|
16590
|
+
const trimmed = content.trimStart();
|
|
16591
|
+
if (!trimmed.startsWith("{")) {
|
|
16592
|
+
return void 0;
|
|
16593
|
+
}
|
|
16594
|
+
const parsed = JSON.parse(content);
|
|
16595
|
+
return isRecord8(parsed) ? parsed : void 0;
|
|
16596
|
+
}
|
|
16597
|
+
function isRecord8(value) {
|
|
16598
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16599
|
+
}
|
|
16441
16600
|
function resolveTreeChainId(opts) {
|
|
16442
16601
|
if (opts.chain === void 0) {
|
|
16443
16602
|
return opts.chainId;
|
|
@@ -17472,7 +17631,7 @@ function writeJsonFile(filePath, data) {
|
|
|
17472
17631
|
function errorMessage3(error) {
|
|
17473
17632
|
return error instanceof Error ? error.message : String(error);
|
|
17474
17633
|
}
|
|
17475
|
-
function
|
|
17634
|
+
function isRecord9(value) {
|
|
17476
17635
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17477
17636
|
}
|
|
17478
17637
|
function detectAllowlistFormat(filePath, format) {
|
|
@@ -17503,7 +17662,7 @@ function loadAllowlistArtifact(filePath) {
|
|
|
17503
17662
|
function readProofFile(filePath) {
|
|
17504
17663
|
const content = readTextFile(filePath, "allowlist proof");
|
|
17505
17664
|
const parsed = parseProofJson(content);
|
|
17506
|
-
const proof = Array.isArray(parsed) ? parsed :
|
|
17665
|
+
const proof = Array.isArray(parsed) ? parsed : isRecord9(parsed) && Array.isArray(parsed.proof) ? parsed.proof : void 0;
|
|
17507
17666
|
if (proof === void 0) {
|
|
17508
17667
|
throw new Error("--proof must be a JSON array or an object with a proof array.");
|
|
17509
17668
|
}
|
|
@@ -18196,7 +18355,7 @@ var MintMetadataOptionsError = class extends Error {
|
|
|
18196
18355
|
function parseMintAttribute(raw) {
|
|
18197
18356
|
if (raw.startsWith("{")) {
|
|
18198
18357
|
const parsed = JSON.parse(raw);
|
|
18199
|
-
if (
|
|
18358
|
+
if (isRecord10(parsed)) {
|
|
18200
18359
|
assertFiniteAttributeNumber(parsed.value, "value", raw);
|
|
18201
18360
|
assertFiniteAttributeNumber(parsed.max_value, "max_value", raw);
|
|
18202
18361
|
}
|
|
@@ -18224,7 +18383,7 @@ function assertFiniteAttributeNumber(value, field, raw) {
|
|
|
18224
18383
|
}
|
|
18225
18384
|
}
|
|
18226
18385
|
function isMintAttribute(value) {
|
|
18227
|
-
if (!
|
|
18386
|
+
if (!isRecord10(value) || !isAttributeValue(value.value)) {
|
|
18228
18387
|
return false;
|
|
18229
18388
|
}
|
|
18230
18389
|
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 +18394,7 @@ function isAttributeValue(value) {
|
|
|
18235
18394
|
function isDisplayType(value) {
|
|
18236
18395
|
return value === "number" || value === "boost_number" || value === "boost_percentage" || value === "date";
|
|
18237
18396
|
}
|
|
18238
|
-
function
|
|
18397
|
+
function isRecord10(value) {
|
|
18239
18398
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18240
18399
|
}
|
|
18241
18400
|
function planMintTokenUri(params) {
|
|
@@ -18470,7 +18629,7 @@ var DISPLAY_TYPES = [
|
|
|
18470
18629
|
function isDisplayType2(value) {
|
|
18471
18630
|
return DISPLAY_TYPES.some((displayType) => displayType === value);
|
|
18472
18631
|
}
|
|
18473
|
-
function
|
|
18632
|
+
function isRecord11(value) {
|
|
18474
18633
|
return typeof value === "object" && value !== null;
|
|
18475
18634
|
}
|
|
18476
18635
|
function parseAttributeValue(value, raw) {
|
|
@@ -18514,7 +18673,7 @@ function parseDisplayType(value, raw) {
|
|
|
18514
18673
|
}
|
|
18515
18674
|
function parseAttributeJson(raw) {
|
|
18516
18675
|
const parsed = parseJson3(raw);
|
|
18517
|
-
if (!
|
|
18676
|
+
if (!isRecord11(parsed) || parsed.value === void 0) {
|
|
18518
18677
|
throw new Error(`Attribute JSON must include "value": ${raw}`);
|
|
18519
18678
|
}
|
|
18520
18679
|
const trait_type = parseOptionalString2(parsed.trait_type, "trait_type", raw) ?? "value";
|
|
@@ -20556,7 +20715,7 @@ function serializeForMcp(value) {
|
|
|
20556
20715
|
if (Array.isArray(value)) {
|
|
20557
20716
|
return value.map(serializeForMcp);
|
|
20558
20717
|
}
|
|
20559
|
-
if (
|
|
20718
|
+
if (isRecord12(value)) {
|
|
20560
20719
|
return Object.fromEntries(
|
|
20561
20720
|
Object.entries(value).map(([key, nested]) => [key, serializeForMcp(nested)]).filter(([, nested]) => nested !== void 0)
|
|
20562
20721
|
);
|
|
@@ -20564,11 +20723,11 @@ function serializeForMcp(value) {
|
|
|
20564
20723
|
return value;
|
|
20565
20724
|
}
|
|
20566
20725
|
function shapeMcpTransactionResult(value, extra = {}) {
|
|
20567
|
-
if (!
|
|
20726
|
+
if (!isRecord12(value)) {
|
|
20568
20727
|
return value;
|
|
20569
20728
|
}
|
|
20570
20729
|
const { receipt, ...shaped } = value;
|
|
20571
|
-
if (
|
|
20730
|
+
if (isRecord12(receipt) && Object.prototype.hasOwnProperty.call(receipt, "blockNumber")) {
|
|
20572
20731
|
return { ...shaped, blockNumber: receipt.blockNumber, ...extra };
|
|
20573
20732
|
}
|
|
20574
20733
|
return { ...shaped, ...extra };
|
|
@@ -20579,7 +20738,7 @@ function maskSecret2(value) {
|
|
|
20579
20738
|
function camelToSnake(value) {
|
|
20580
20739
|
return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
|
|
20581
20740
|
}
|
|
20582
|
-
function
|
|
20741
|
+
function isRecord12(value) {
|
|
20583
20742
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20584
20743
|
}
|
|
20585
20744
|
|
|
@@ -21238,7 +21397,7 @@ function requiresExplicitConfirmation(commandPath2) {
|
|
|
21238
21397
|
// package.json
|
|
21239
21398
|
var package_default = {
|
|
21240
21399
|
name: "@rareprotocol/rare-cli",
|
|
21241
|
-
version: "1.2.
|
|
21400
|
+
version: "1.2.1",
|
|
21242
21401
|
description: "CLI tool for interacting with the RARE protocol smart contracts",
|
|
21243
21402
|
type: "module",
|
|
21244
21403
|
license: "MIT",
|