@net-protocol/cli 0.1.48 → 0.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/dist/cli/index.mjs +587 -29
- package/dist/cli/index.mjs.map +1 -1
- package/dist/upvote/index.d.ts +3 -1
- package/dist/upvote/index.mjs +152 -2
- package/dist/upvote/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/cli/index.mjs
CHANGED
|
@@ -22,7 +22,7 @@ import { BazaarClient } from '@net-protocol/bazaar';
|
|
|
22
22
|
import * as os from 'os';
|
|
23
23
|
import { homedir } from 'os';
|
|
24
24
|
import * as readline from 'readline';
|
|
25
|
-
import { discoverTokenPool, PURE_ALPHA_STRATEGY, UNIV234_POOLS_STRATEGY, encodePoolKey, DYNAMIC_SPLIT_STRATEGY, getTokenScoreKey, UPVOTE_PRICE_ETH, UPVOTE_APP, ScoreClient, ALL_STRATEGY_ADDRESSES, NULL_ADDRESS as NULL_ADDRESS$1, UserUpvoteClient, calculateUpvoteCost, USER_UPVOTE_CONTRACT } from '@net-protocol/score';
|
|
25
|
+
import { discoverTokenPool, PURE_ALPHA_STRATEGY, UNIV234_POOLS_STRATEGY, encodePoolKey, DYNAMIC_SPLIT_STRATEGY, getTokenScoreKey, UPVOTE_PRICE_ETH, UPVOTE_APP, ScoreClient, ALL_STRATEGY_ADDRESSES, NULL_ADDRESS as NULL_ADDRESS$1, UserUpvoteClient, calculateUpvoteCost, USER_UPVOTE_CONTRACT, getTokenRankings } from '@net-protocol/score';
|
|
26
26
|
import { RELAY_ACCESS_KEY, generateAgentChatTopic, AgentClient, isAgentChatTopic, parseAgentAddressFromTopic, buildSessionTypedData, NET_API_URL, exchangeSessionSignature, buildConversationAuthTypedData, NET_TESTNET_API_URL } from '@net-protocol/agents';
|
|
27
27
|
|
|
28
28
|
var DEFAULT_CHAIN_ID = 8453;
|
|
@@ -1641,8 +1641,8 @@ function registerStorageCommand(program2) {
|
|
|
1641
1641
|
console.log(chalk4.blue(`\u{1F4C1} Reading file: ${options.file}`));
|
|
1642
1642
|
console.log(chalk4.blue(`\u{1F517} Using relay API: ${options.apiUrl}`));
|
|
1643
1643
|
const result = await uploadFileWithRelay(uploadRelayOptions);
|
|
1644
|
-
const { privateKeyToAccount:
|
|
1645
|
-
const userAccount =
|
|
1644
|
+
const { privateKeyToAccount: privateKeyToAccount32 } = await import('viem/accounts');
|
|
1645
|
+
const userAccount = privateKeyToAccount32(commonOptions.privateKey);
|
|
1646
1646
|
const storageUrl2 = generateStorageUrl(
|
|
1647
1647
|
userAccount.address,
|
|
1648
1648
|
commonOptions.chainId,
|
|
@@ -4795,7 +4795,8 @@ async function executeCreateErc20Listing(options) {
|
|
|
4795
4795
|
tokenAddress: options.tokenAddress,
|
|
4796
4796
|
tokenAmount,
|
|
4797
4797
|
priceWei,
|
|
4798
|
-
offerer: account.address
|
|
4798
|
+
offerer: account.address,
|
|
4799
|
+
targetFulfiller: options.targetFulfiller
|
|
4799
4800
|
});
|
|
4800
4801
|
const rpcUrls = getChainRpcUrls({
|
|
4801
4802
|
chainId: commonOptions.chainId,
|
|
@@ -4879,7 +4880,8 @@ async function executeKeylessMode3(options) {
|
|
|
4879
4880
|
tokenAddress: options.tokenAddress,
|
|
4880
4881
|
tokenAmount,
|
|
4881
4882
|
priceWei,
|
|
4882
|
-
offerer: options.offerer
|
|
4883
|
+
offerer: options.offerer,
|
|
4884
|
+
targetFulfiller: options.targetFulfiller
|
|
4883
4885
|
});
|
|
4884
4886
|
const output = {
|
|
4885
4887
|
eip712: {
|
|
@@ -5487,6 +5489,386 @@ async function executeEncodeOnly10(options) {
|
|
|
5487
5489
|
);
|
|
5488
5490
|
}
|
|
5489
5491
|
}
|
|
5492
|
+
function createWallet(privateKey, chainId, rpcUrl) {
|
|
5493
|
+
const account = privateKeyToAccount(privateKey);
|
|
5494
|
+
const rpcUrls = getChainRpcUrls({
|
|
5495
|
+
chainId,
|
|
5496
|
+
rpcUrl
|
|
5497
|
+
});
|
|
5498
|
+
return createWalletClient({
|
|
5499
|
+
account,
|
|
5500
|
+
transport: http(rpcUrls[0]),
|
|
5501
|
+
dataSuffix: getBaseDataSuffix(chainId)
|
|
5502
|
+
});
|
|
5503
|
+
}
|
|
5504
|
+
async function executeTransaction(walletClient, txConfig) {
|
|
5505
|
+
const hash = await walletClient.writeContract({
|
|
5506
|
+
address: txConfig.to,
|
|
5507
|
+
abi: txConfig.abi,
|
|
5508
|
+
functionName: txConfig.functionName,
|
|
5509
|
+
args: txConfig.args,
|
|
5510
|
+
value: txConfig.value,
|
|
5511
|
+
chain: null
|
|
5512
|
+
});
|
|
5513
|
+
return hash;
|
|
5514
|
+
}
|
|
5515
|
+
|
|
5516
|
+
// src/commands/bazaar/cancel-listing.ts
|
|
5517
|
+
async function executeCancelListing(options) {
|
|
5518
|
+
if (options.encodeOnly) {
|
|
5519
|
+
await executeEncodeOnly11(options);
|
|
5520
|
+
return;
|
|
5521
|
+
}
|
|
5522
|
+
const commonOptions = parseCommonOptions(
|
|
5523
|
+
{
|
|
5524
|
+
privateKey: options.privateKey,
|
|
5525
|
+
chainId: options.chainId,
|
|
5526
|
+
rpcUrl: options.rpcUrl
|
|
5527
|
+
},
|
|
5528
|
+
true
|
|
5529
|
+
);
|
|
5530
|
+
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
5531
|
+
const bazaarClient = new BazaarClient({
|
|
5532
|
+
chainId: commonOptions.chainId,
|
|
5533
|
+
rpcUrl: commonOptions.rpcUrl
|
|
5534
|
+
});
|
|
5535
|
+
try {
|
|
5536
|
+
console.log(chalk4.blue("Fetching listing..."));
|
|
5537
|
+
const listings = await bazaarClient.getListings({
|
|
5538
|
+
nftAddress: options.nftAddress,
|
|
5539
|
+
maker: account.address,
|
|
5540
|
+
includeExpired: true
|
|
5541
|
+
});
|
|
5542
|
+
const listing = listings.find(
|
|
5543
|
+
(l) => l.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5544
|
+
);
|
|
5545
|
+
if (!listing) {
|
|
5546
|
+
exitWithError(
|
|
5547
|
+
`Listing with order hash ${options.orderHash} not found for maker ${account.address}`
|
|
5548
|
+
);
|
|
5549
|
+
}
|
|
5550
|
+
const cancelTx = bazaarClient.prepareCancelListing(listing);
|
|
5551
|
+
const walletClient = createWallet(
|
|
5552
|
+
commonOptions.privateKey,
|
|
5553
|
+
commonOptions.chainId,
|
|
5554
|
+
commonOptions.rpcUrl
|
|
5555
|
+
);
|
|
5556
|
+
console.log(chalk4.blue("Sending cancel transaction..."));
|
|
5557
|
+
const hash = await executeTransaction(walletClient, cancelTx);
|
|
5558
|
+
console.log(
|
|
5559
|
+
chalk4.green(
|
|
5560
|
+
`Listing cancelled successfully!
|
|
5561
|
+
Transaction: ${hash}
|
|
5562
|
+
NFT: ${listing.nftAddress} #${listing.tokenId}`
|
|
5563
|
+
)
|
|
5564
|
+
);
|
|
5565
|
+
} catch (error) {
|
|
5566
|
+
exitWithError(
|
|
5567
|
+
`Failed to cancel listing: ${error instanceof Error ? error.message : String(error)}`
|
|
5568
|
+
);
|
|
5569
|
+
}
|
|
5570
|
+
}
|
|
5571
|
+
async function executeEncodeOnly11(options) {
|
|
5572
|
+
if (!options.maker) {
|
|
5573
|
+
exitWithError("--maker is required when using --encode-only without --private-key");
|
|
5574
|
+
}
|
|
5575
|
+
const readOnlyOptions = parseReadOnlyOptions({
|
|
5576
|
+
chainId: options.chainId,
|
|
5577
|
+
rpcUrl: options.rpcUrl
|
|
5578
|
+
});
|
|
5579
|
+
const makerAddress = options.maker;
|
|
5580
|
+
const bazaarClient = new BazaarClient({
|
|
5581
|
+
chainId: readOnlyOptions.chainId,
|
|
5582
|
+
rpcUrl: readOnlyOptions.rpcUrl
|
|
5583
|
+
});
|
|
5584
|
+
try {
|
|
5585
|
+
const listings = await bazaarClient.getListings({
|
|
5586
|
+
nftAddress: options.nftAddress,
|
|
5587
|
+
maker: makerAddress,
|
|
5588
|
+
includeExpired: true
|
|
5589
|
+
});
|
|
5590
|
+
const listing = listings.find(
|
|
5591
|
+
(l) => l.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5592
|
+
);
|
|
5593
|
+
if (!listing) {
|
|
5594
|
+
exitWithError(
|
|
5595
|
+
`Listing with order hash ${options.orderHash} not found for maker ${makerAddress}`
|
|
5596
|
+
);
|
|
5597
|
+
}
|
|
5598
|
+
const cancelTx = bazaarClient.prepareCancelListing(listing);
|
|
5599
|
+
console.log(JSON.stringify(encodeTransaction(cancelTx, readOnlyOptions.chainId), null, 2));
|
|
5600
|
+
} catch (error) {
|
|
5601
|
+
exitWithError(
|
|
5602
|
+
`Failed to encode cancel listing: ${error instanceof Error ? error.message : String(error)}`
|
|
5603
|
+
);
|
|
5604
|
+
}
|
|
5605
|
+
}
|
|
5606
|
+
async function executeCancelOffer(options) {
|
|
5607
|
+
if (options.encodeOnly) {
|
|
5608
|
+
await executeEncodeOnly12(options);
|
|
5609
|
+
return;
|
|
5610
|
+
}
|
|
5611
|
+
const commonOptions = parseCommonOptions(
|
|
5612
|
+
{
|
|
5613
|
+
privateKey: options.privateKey,
|
|
5614
|
+
chainId: options.chainId,
|
|
5615
|
+
rpcUrl: options.rpcUrl
|
|
5616
|
+
},
|
|
5617
|
+
true
|
|
5618
|
+
);
|
|
5619
|
+
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
5620
|
+
const bazaarClient = new BazaarClient({
|
|
5621
|
+
chainId: commonOptions.chainId,
|
|
5622
|
+
rpcUrl: commonOptions.rpcUrl
|
|
5623
|
+
});
|
|
5624
|
+
try {
|
|
5625
|
+
console.log(chalk4.blue("Fetching collection offer..."));
|
|
5626
|
+
const offers = await bazaarClient.getCollectionOffers({
|
|
5627
|
+
nftAddress: options.nftAddress,
|
|
5628
|
+
maker: account.address
|
|
5629
|
+
});
|
|
5630
|
+
const offer = offers.find(
|
|
5631
|
+
(o) => o.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5632
|
+
);
|
|
5633
|
+
if (!offer) {
|
|
5634
|
+
exitWithError(
|
|
5635
|
+
`Offer with order hash ${options.orderHash} not found for maker ${account.address}`
|
|
5636
|
+
);
|
|
5637
|
+
}
|
|
5638
|
+
const cancelTx = bazaarClient.prepareCancelCollectionOffer(offer);
|
|
5639
|
+
const walletClient = createWallet(
|
|
5640
|
+
commonOptions.privateKey,
|
|
5641
|
+
commonOptions.chainId,
|
|
5642
|
+
commonOptions.rpcUrl
|
|
5643
|
+
);
|
|
5644
|
+
console.log(chalk4.blue("Sending cancel transaction..."));
|
|
5645
|
+
const hash = await executeTransaction(walletClient, cancelTx);
|
|
5646
|
+
console.log(
|
|
5647
|
+
chalk4.green(
|
|
5648
|
+
`Offer cancelled successfully!
|
|
5649
|
+
Transaction: ${hash}
|
|
5650
|
+
NFT: ${offer.nftAddress}
|
|
5651
|
+
Price: ${offer.price} ${offer.currency.toUpperCase()}`
|
|
5652
|
+
)
|
|
5653
|
+
);
|
|
5654
|
+
} catch (error) {
|
|
5655
|
+
exitWithError(
|
|
5656
|
+
`Failed to cancel offer: ${error instanceof Error ? error.message : String(error)}`
|
|
5657
|
+
);
|
|
5658
|
+
}
|
|
5659
|
+
}
|
|
5660
|
+
async function executeEncodeOnly12(options) {
|
|
5661
|
+
if (!options.maker) {
|
|
5662
|
+
exitWithError("--maker is required when using --encode-only without --private-key");
|
|
5663
|
+
}
|
|
5664
|
+
const readOnlyOptions = parseReadOnlyOptions({
|
|
5665
|
+
chainId: options.chainId,
|
|
5666
|
+
rpcUrl: options.rpcUrl
|
|
5667
|
+
});
|
|
5668
|
+
const makerAddress = options.maker;
|
|
5669
|
+
const bazaarClient = new BazaarClient({
|
|
5670
|
+
chainId: readOnlyOptions.chainId,
|
|
5671
|
+
rpcUrl: readOnlyOptions.rpcUrl
|
|
5672
|
+
});
|
|
5673
|
+
try {
|
|
5674
|
+
const offers = await bazaarClient.getCollectionOffers({
|
|
5675
|
+
nftAddress: options.nftAddress,
|
|
5676
|
+
maker: makerAddress
|
|
5677
|
+
});
|
|
5678
|
+
const offer = offers.find(
|
|
5679
|
+
(o) => o.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5680
|
+
);
|
|
5681
|
+
if (!offer) {
|
|
5682
|
+
exitWithError(
|
|
5683
|
+
`Offer with order hash ${options.orderHash} not found for maker ${makerAddress}`
|
|
5684
|
+
);
|
|
5685
|
+
}
|
|
5686
|
+
const cancelTx = bazaarClient.prepareCancelCollectionOffer(offer);
|
|
5687
|
+
console.log(JSON.stringify(encodeTransaction(cancelTx, readOnlyOptions.chainId), null, 2));
|
|
5688
|
+
} catch (error) {
|
|
5689
|
+
exitWithError(
|
|
5690
|
+
`Failed to encode cancel offer: ${error instanceof Error ? error.message : String(error)}`
|
|
5691
|
+
);
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
async function executeCancelErc20Listing(options) {
|
|
5695
|
+
if (options.encodeOnly) {
|
|
5696
|
+
await executeEncodeOnly13(options);
|
|
5697
|
+
return;
|
|
5698
|
+
}
|
|
5699
|
+
const commonOptions = parseCommonOptions(
|
|
5700
|
+
{
|
|
5701
|
+
privateKey: options.privateKey,
|
|
5702
|
+
chainId: options.chainId,
|
|
5703
|
+
rpcUrl: options.rpcUrl
|
|
5704
|
+
},
|
|
5705
|
+
true
|
|
5706
|
+
);
|
|
5707
|
+
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
5708
|
+
const bazaarClient = new BazaarClient({
|
|
5709
|
+
chainId: commonOptions.chainId,
|
|
5710
|
+
rpcUrl: commonOptions.rpcUrl
|
|
5711
|
+
});
|
|
5712
|
+
try {
|
|
5713
|
+
console.log(chalk4.blue("Fetching ERC20 listing..."));
|
|
5714
|
+
const listings = await bazaarClient.getErc20Listings({
|
|
5715
|
+
tokenAddress: options.tokenAddress,
|
|
5716
|
+
maker: account.address,
|
|
5717
|
+
includeExpired: true
|
|
5718
|
+
});
|
|
5719
|
+
const listing = listings.find(
|
|
5720
|
+
(l) => l.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5721
|
+
);
|
|
5722
|
+
if (!listing) {
|
|
5723
|
+
exitWithError(
|
|
5724
|
+
`ERC20 listing with order hash ${options.orderHash} not found for maker ${account.address}`
|
|
5725
|
+
);
|
|
5726
|
+
}
|
|
5727
|
+
const cancelTx = bazaarClient.prepareCancelErc20Listing(listing);
|
|
5728
|
+
const walletClient = createWallet(
|
|
5729
|
+
commonOptions.privateKey,
|
|
5730
|
+
commonOptions.chainId,
|
|
5731
|
+
commonOptions.rpcUrl
|
|
5732
|
+
);
|
|
5733
|
+
console.log(chalk4.blue("Sending cancel transaction..."));
|
|
5734
|
+
const hash = await executeTransaction(walletClient, cancelTx);
|
|
5735
|
+
console.log(
|
|
5736
|
+
chalk4.green(
|
|
5737
|
+
`ERC20 listing cancelled successfully!
|
|
5738
|
+
Transaction: ${hash}
|
|
5739
|
+
Token: ${listing.tokenAddress}
|
|
5740
|
+
Amount: ${listing.tokenAmount.toString()}`
|
|
5741
|
+
)
|
|
5742
|
+
);
|
|
5743
|
+
} catch (error) {
|
|
5744
|
+
exitWithError(
|
|
5745
|
+
`Failed to cancel ERC20 listing: ${error instanceof Error ? error.message : String(error)}`
|
|
5746
|
+
);
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
async function executeEncodeOnly13(options) {
|
|
5750
|
+
if (!options.maker) {
|
|
5751
|
+
exitWithError("--maker is required when using --encode-only without --private-key");
|
|
5752
|
+
}
|
|
5753
|
+
const readOnlyOptions = parseReadOnlyOptions({
|
|
5754
|
+
chainId: options.chainId,
|
|
5755
|
+
rpcUrl: options.rpcUrl
|
|
5756
|
+
});
|
|
5757
|
+
const makerAddress = options.maker;
|
|
5758
|
+
const bazaarClient = new BazaarClient({
|
|
5759
|
+
chainId: readOnlyOptions.chainId,
|
|
5760
|
+
rpcUrl: readOnlyOptions.rpcUrl
|
|
5761
|
+
});
|
|
5762
|
+
try {
|
|
5763
|
+
const listings = await bazaarClient.getErc20Listings({
|
|
5764
|
+
tokenAddress: options.tokenAddress,
|
|
5765
|
+
maker: makerAddress,
|
|
5766
|
+
includeExpired: true
|
|
5767
|
+
});
|
|
5768
|
+
const listing = listings.find(
|
|
5769
|
+
(l) => l.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5770
|
+
);
|
|
5771
|
+
if (!listing) {
|
|
5772
|
+
exitWithError(
|
|
5773
|
+
`ERC20 listing with order hash ${options.orderHash} not found for maker ${makerAddress}`
|
|
5774
|
+
);
|
|
5775
|
+
}
|
|
5776
|
+
const cancelTx = bazaarClient.prepareCancelErc20Listing(listing);
|
|
5777
|
+
console.log(JSON.stringify(encodeTransaction(cancelTx, readOnlyOptions.chainId), null, 2));
|
|
5778
|
+
} catch (error) {
|
|
5779
|
+
exitWithError(
|
|
5780
|
+
`Failed to encode cancel ERC20 listing: ${error instanceof Error ? error.message : String(error)}`
|
|
5781
|
+
);
|
|
5782
|
+
}
|
|
5783
|
+
}
|
|
5784
|
+
async function executeCancelErc20Offer(options) {
|
|
5785
|
+
if (options.encodeOnly) {
|
|
5786
|
+
await executeEncodeOnly14(options);
|
|
5787
|
+
return;
|
|
5788
|
+
}
|
|
5789
|
+
const commonOptions = parseCommonOptions(
|
|
5790
|
+
{
|
|
5791
|
+
privateKey: options.privateKey,
|
|
5792
|
+
chainId: options.chainId,
|
|
5793
|
+
rpcUrl: options.rpcUrl
|
|
5794
|
+
},
|
|
5795
|
+
true
|
|
5796
|
+
);
|
|
5797
|
+
const account = privateKeyToAccount(commonOptions.privateKey);
|
|
5798
|
+
const bazaarClient = new BazaarClient({
|
|
5799
|
+
chainId: commonOptions.chainId,
|
|
5800
|
+
rpcUrl: commonOptions.rpcUrl
|
|
5801
|
+
});
|
|
5802
|
+
try {
|
|
5803
|
+
console.log(chalk4.blue("Fetching ERC20 offer..."));
|
|
5804
|
+
const offers = await bazaarClient.getErc20Offers({
|
|
5805
|
+
tokenAddress: options.tokenAddress,
|
|
5806
|
+
maker: account.address
|
|
5807
|
+
});
|
|
5808
|
+
const offer = offers.find(
|
|
5809
|
+
(o) => o.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5810
|
+
);
|
|
5811
|
+
if (!offer) {
|
|
5812
|
+
exitWithError(
|
|
5813
|
+
`ERC20 offer with order hash ${options.orderHash} not found for maker ${account.address}`
|
|
5814
|
+
);
|
|
5815
|
+
}
|
|
5816
|
+
const cancelTx = bazaarClient.prepareCancelErc20Offer(offer);
|
|
5817
|
+
const walletClient = createWallet(
|
|
5818
|
+
commonOptions.privateKey,
|
|
5819
|
+
commonOptions.chainId,
|
|
5820
|
+
commonOptions.rpcUrl
|
|
5821
|
+
);
|
|
5822
|
+
console.log(chalk4.blue("Sending cancel transaction..."));
|
|
5823
|
+
const hash = await executeTransaction(walletClient, cancelTx);
|
|
5824
|
+
console.log(
|
|
5825
|
+
chalk4.green(
|
|
5826
|
+
`ERC20 offer cancelled successfully!
|
|
5827
|
+
Transaction: ${hash}
|
|
5828
|
+
Token: ${offer.tokenAddress}
|
|
5829
|
+
Amount: ${offer.tokenAmount.toString()}`
|
|
5830
|
+
)
|
|
5831
|
+
);
|
|
5832
|
+
} catch (error) {
|
|
5833
|
+
exitWithError(
|
|
5834
|
+
`Failed to cancel ERC20 offer: ${error instanceof Error ? error.message : String(error)}`
|
|
5835
|
+
);
|
|
5836
|
+
}
|
|
5837
|
+
}
|
|
5838
|
+
async function executeEncodeOnly14(options) {
|
|
5839
|
+
if (!options.maker) {
|
|
5840
|
+
exitWithError("--maker is required when using --encode-only without --private-key");
|
|
5841
|
+
}
|
|
5842
|
+
const readOnlyOptions = parseReadOnlyOptions({
|
|
5843
|
+
chainId: options.chainId,
|
|
5844
|
+
rpcUrl: options.rpcUrl
|
|
5845
|
+
});
|
|
5846
|
+
const makerAddress = options.maker;
|
|
5847
|
+
const bazaarClient = new BazaarClient({
|
|
5848
|
+
chainId: readOnlyOptions.chainId,
|
|
5849
|
+
rpcUrl: readOnlyOptions.rpcUrl
|
|
5850
|
+
});
|
|
5851
|
+
try {
|
|
5852
|
+
const offers = await bazaarClient.getErc20Offers({
|
|
5853
|
+
tokenAddress: options.tokenAddress,
|
|
5854
|
+
maker: makerAddress
|
|
5855
|
+
});
|
|
5856
|
+
const offer = offers.find(
|
|
5857
|
+
(o) => o.orderHash.toLowerCase() === options.orderHash.toLowerCase()
|
|
5858
|
+
);
|
|
5859
|
+
if (!offer) {
|
|
5860
|
+
exitWithError(
|
|
5861
|
+
`ERC20 offer with order hash ${options.orderHash} not found for maker ${makerAddress}`
|
|
5862
|
+
);
|
|
5863
|
+
}
|
|
5864
|
+
const cancelTx = bazaarClient.prepareCancelErc20Offer(offer);
|
|
5865
|
+
console.log(JSON.stringify(encodeTransaction(cancelTx, readOnlyOptions.chainId), null, 2));
|
|
5866
|
+
} catch (error) {
|
|
5867
|
+
exitWithError(
|
|
5868
|
+
`Failed to encode cancel ERC20 offer: ${error instanceof Error ? error.message : String(error)}`
|
|
5869
|
+
);
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5490
5872
|
|
|
5491
5873
|
// src/commands/bazaar/index.ts
|
|
5492
5874
|
var chainIdOption = [
|
|
@@ -5620,11 +6002,12 @@ function registerBazaarCommand(program2) {
|
|
|
5620
6002
|
json: options.json
|
|
5621
6003
|
});
|
|
5622
6004
|
});
|
|
5623
|
-
const createErc20ListingCommand = new Command("create-erc20-listing").description("Create an ERC-20 token listing (with --private-key: full flow; without: output EIP-712 data)").requiredOption("--token-address <address>", "ERC-20 token contract address").requiredOption("--token-amount <amount>", "Token amount in raw units (bigint string)").requiredOption("--price <eth>", "Total price in ETH for the token amount").option("--offerer <address>", "Offerer address (required without --private-key)").option(...privateKeyOption).option(...chainIdOption).option(...rpcUrlOption).action(async (options) => {
|
|
6005
|
+
const createErc20ListingCommand = new Command("create-erc20-listing").description("Create an ERC-20 token listing (with --private-key: full flow; without: output EIP-712 data)").requiredOption("--token-address <address>", "ERC-20 token contract address").requiredOption("--token-amount <amount>", "Token amount in raw units (bigint string)").requiredOption("--price <eth>", "Total price in ETH for the token amount").option("--target-fulfiller <address>", "Make a private listing for this address").option("--offerer <address>", "Offerer address (required without --private-key)").option(...privateKeyOption).option(...chainIdOption).option(...rpcUrlOption).action(async (options) => {
|
|
5624
6006
|
await executeCreateErc20Listing({
|
|
5625
6007
|
tokenAddress: options.tokenAddress,
|
|
5626
6008
|
tokenAmount: options.tokenAmount,
|
|
5627
6009
|
price: options.price,
|
|
6010
|
+
targetFulfiller: options.targetFulfiller,
|
|
5628
6011
|
offerer: options.offerer,
|
|
5629
6012
|
privateKey: options.privateKey,
|
|
5630
6013
|
chainId: options.chainId,
|
|
@@ -5684,6 +6067,50 @@ function registerBazaarCommand(program2) {
|
|
|
5684
6067
|
encodeOnly: options.encodeOnly
|
|
5685
6068
|
});
|
|
5686
6069
|
});
|
|
6070
|
+
const cancelListingCommand = new Command("cancel-listing").description("Cancel an NFT listing you created").requiredOption("--order-hash <hash>", "Order hash of the listing to cancel").requiredOption("--nft-address <address>", "NFT contract address").option("--maker <address>", "Maker address (required with --encode-only)").option(...privateKeyOption).option(...chainIdOption).option(...rpcUrlOption).option("--encode-only", "Output transaction data as JSON instead of executing").action(async (options) => {
|
|
6071
|
+
await executeCancelListing({
|
|
6072
|
+
orderHash: options.orderHash,
|
|
6073
|
+
nftAddress: options.nftAddress,
|
|
6074
|
+
maker: options.maker,
|
|
6075
|
+
privateKey: options.privateKey,
|
|
6076
|
+
chainId: options.chainId,
|
|
6077
|
+
rpcUrl: options.rpcUrl,
|
|
6078
|
+
encodeOnly: options.encodeOnly
|
|
6079
|
+
});
|
|
6080
|
+
});
|
|
6081
|
+
const cancelOfferCommand = new Command("cancel-offer").description("Cancel a collection offer you created").requiredOption("--order-hash <hash>", "Order hash of the offer to cancel").requiredOption("--nft-address <address>", "NFT contract address").option("--maker <address>", "Maker address (required with --encode-only)").option(...privateKeyOption).option(...chainIdOption).option(...rpcUrlOption).option("--encode-only", "Output transaction data as JSON instead of executing").action(async (options) => {
|
|
6082
|
+
await executeCancelOffer({
|
|
6083
|
+
orderHash: options.orderHash,
|
|
6084
|
+
nftAddress: options.nftAddress,
|
|
6085
|
+
maker: options.maker,
|
|
6086
|
+
privateKey: options.privateKey,
|
|
6087
|
+
chainId: options.chainId,
|
|
6088
|
+
rpcUrl: options.rpcUrl,
|
|
6089
|
+
encodeOnly: options.encodeOnly
|
|
6090
|
+
});
|
|
6091
|
+
});
|
|
6092
|
+
const cancelErc20ListingCommand = new Command("cancel-erc20-listing").description("Cancel an ERC-20 listing you created").requiredOption("--order-hash <hash>", "Order hash of the listing to cancel").requiredOption("--token-address <address>", "ERC-20 token contract address").option("--maker <address>", "Maker address (required with --encode-only)").option(...privateKeyOption).option(...chainIdOption).option(...rpcUrlOption).option("--encode-only", "Output transaction data as JSON instead of executing").action(async (options) => {
|
|
6093
|
+
await executeCancelErc20Listing({
|
|
6094
|
+
orderHash: options.orderHash,
|
|
6095
|
+
tokenAddress: options.tokenAddress,
|
|
6096
|
+
maker: options.maker,
|
|
6097
|
+
privateKey: options.privateKey,
|
|
6098
|
+
chainId: options.chainId,
|
|
6099
|
+
rpcUrl: options.rpcUrl,
|
|
6100
|
+
encodeOnly: options.encodeOnly
|
|
6101
|
+
});
|
|
6102
|
+
});
|
|
6103
|
+
const cancelErc20OfferCommand = new Command("cancel-erc20-offer").description("Cancel an ERC-20 offer you created").requiredOption("--order-hash <hash>", "Order hash of the offer to cancel").requiredOption("--token-address <address>", "ERC-20 token contract address").option("--maker <address>", "Maker address (required with --encode-only)").option(...privateKeyOption).option(...chainIdOption).option(...rpcUrlOption).option("--encode-only", "Output transaction data as JSON instead of executing").action(async (options) => {
|
|
6104
|
+
await executeCancelErc20Offer({
|
|
6105
|
+
orderHash: options.orderHash,
|
|
6106
|
+
tokenAddress: options.tokenAddress,
|
|
6107
|
+
maker: options.maker,
|
|
6108
|
+
privateKey: options.privateKey,
|
|
6109
|
+
chainId: options.chainId,
|
|
6110
|
+
rpcUrl: options.rpcUrl,
|
|
6111
|
+
encodeOnly: options.encodeOnly
|
|
6112
|
+
});
|
|
6113
|
+
});
|
|
5687
6114
|
bazaarCommand.addCommand(listListingsCommand);
|
|
5688
6115
|
bazaarCommand.addCommand(listOffersCommand);
|
|
5689
6116
|
bazaarCommand.addCommand(listSalesCommand);
|
|
@@ -5702,6 +6129,10 @@ function registerBazaarCommand(program2) {
|
|
|
5702
6129
|
bazaarCommand.addCommand(submitErc20OfferCommand);
|
|
5703
6130
|
bazaarCommand.addCommand(buyErc20ListingCommand);
|
|
5704
6131
|
bazaarCommand.addCommand(acceptErc20OfferCommand);
|
|
6132
|
+
bazaarCommand.addCommand(cancelListingCommand);
|
|
6133
|
+
bazaarCommand.addCommand(cancelOfferCommand);
|
|
6134
|
+
bazaarCommand.addCommand(cancelErc20ListingCommand);
|
|
6135
|
+
bazaarCommand.addCommand(cancelErc20OfferCommand);
|
|
5705
6136
|
}
|
|
5706
6137
|
function truncateAddress(address) {
|
|
5707
6138
|
if (address.length <= 12) return address;
|
|
@@ -6172,29 +6603,6 @@ function registerFeedReadCommand(parent) {
|
|
|
6172
6603
|
await executeFeedRead(feed, options);
|
|
6173
6604
|
});
|
|
6174
6605
|
}
|
|
6175
|
-
function createWallet(privateKey, chainId, rpcUrl) {
|
|
6176
|
-
const account = privateKeyToAccount(privateKey);
|
|
6177
|
-
const rpcUrls = getChainRpcUrls({
|
|
6178
|
-
chainId,
|
|
6179
|
-
rpcUrl
|
|
6180
|
-
});
|
|
6181
|
-
return createWalletClient({
|
|
6182
|
-
account,
|
|
6183
|
-
transport: http(rpcUrls[0]),
|
|
6184
|
-
dataSuffix: getBaseDataSuffix(chainId)
|
|
6185
|
-
});
|
|
6186
|
-
}
|
|
6187
|
-
async function executeTransaction(walletClient, txConfig) {
|
|
6188
|
-
const hash = await walletClient.writeContract({
|
|
6189
|
-
address: txConfig.to,
|
|
6190
|
-
abi: txConfig.abi,
|
|
6191
|
-
functionName: txConfig.functionName,
|
|
6192
|
-
args: txConfig.args,
|
|
6193
|
-
value: txConfig.value,
|
|
6194
|
-
chain: null
|
|
6195
|
-
});
|
|
6196
|
-
return hash;
|
|
6197
|
-
}
|
|
6198
6606
|
async function getMessageIndicesFromTx(params) {
|
|
6199
6607
|
const publicClient = getPublicClient({
|
|
6200
6608
|
chainId: params.chainId,
|
|
@@ -7872,6 +8280,155 @@ function registerGetUserUpvotesCommand(parent, commandName = "user-info") {
|
|
|
7872
8280
|
await executeGetUserUpvotes(options);
|
|
7873
8281
|
});
|
|
7874
8282
|
}
|
|
8283
|
+
var VALID_SORTS = ["trending", "recent", "top"];
|
|
8284
|
+
function formatNumber(n, digits = 2) {
|
|
8285
|
+
if (n == null || !Number.isFinite(n)) return "-";
|
|
8286
|
+
if (n >= 1e9) return `${(n / 1e9).toFixed(digits)}B`;
|
|
8287
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(digits)}M`;
|
|
8288
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(digits)}K`;
|
|
8289
|
+
return n.toFixed(digits);
|
|
8290
|
+
}
|
|
8291
|
+
function formatPrice(price) {
|
|
8292
|
+
if (price == null || !Number.isFinite(price)) return "-";
|
|
8293
|
+
if (price < 1e-6) return price.toExponential(2);
|
|
8294
|
+
if (price < 1) return `$${price.toFixed(6)}`;
|
|
8295
|
+
return `$${price.toFixed(4)}`;
|
|
8296
|
+
}
|
|
8297
|
+
async function executeRankings(options) {
|
|
8298
|
+
const sort = (options.sort ?? "trending").toLowerCase();
|
|
8299
|
+
if (!VALID_SORTS.includes(sort)) {
|
|
8300
|
+
exitWithError(
|
|
8301
|
+
`Invalid --sort "${options.sort}". Must be one of: ${VALID_SORTS.join(", ")}`
|
|
8302
|
+
);
|
|
8303
|
+
return;
|
|
8304
|
+
}
|
|
8305
|
+
const limit = options.limit ?? 10;
|
|
8306
|
+
if (!Number.isFinite(limit) || limit < 1 || limit > 100) {
|
|
8307
|
+
exitWithError("Invalid --limit. Must be an integer between 1 and 100.");
|
|
8308
|
+
return;
|
|
8309
|
+
}
|
|
8310
|
+
const optionalPositiveInt = (value, name, { allowZero = false } = {}) => {
|
|
8311
|
+
if (value === void 0) return void 0;
|
|
8312
|
+
if (!Number.isFinite(value) || (allowZero ? value < 0 : value < 1)) {
|
|
8313
|
+
exitWithError(
|
|
8314
|
+
`Invalid ${name}. Must be a ${allowZero ? "non-negative" : "positive"} integer.`
|
|
8315
|
+
);
|
|
8316
|
+
}
|
|
8317
|
+
return value;
|
|
8318
|
+
};
|
|
8319
|
+
const scanWindow = optionalPositiveInt(options.scanWindow, "--scan-window");
|
|
8320
|
+
const minUpvotes = optionalPositiveInt(options.minUpvotes, "--min-upvotes", {
|
|
8321
|
+
allowZero: true
|
|
8322
|
+
});
|
|
8323
|
+
const minMarketCap = optionalPositiveInt(
|
|
8324
|
+
options.minMarketCap,
|
|
8325
|
+
"--min-market-cap",
|
|
8326
|
+
{ allowZero: true }
|
|
8327
|
+
);
|
|
8328
|
+
const recencyHours = optionalPositiveInt(
|
|
8329
|
+
options.recencyHours,
|
|
8330
|
+
"--recency-hours",
|
|
8331
|
+
{ allowZero: true }
|
|
8332
|
+
);
|
|
8333
|
+
if (options.chainId !== void 0 && !Number.isFinite(options.chainId)) {
|
|
8334
|
+
exitWithError("Invalid --chain-id. Must be an integer.");
|
|
8335
|
+
return;
|
|
8336
|
+
}
|
|
8337
|
+
const readOnlyOptions = parseReadOnlyOptionsWithDefault({
|
|
8338
|
+
chainId: options.chainId,
|
|
8339
|
+
rpcUrl: options.rpcUrl
|
|
8340
|
+
});
|
|
8341
|
+
try {
|
|
8342
|
+
const tokens = await getTokenRankings({
|
|
8343
|
+
chainId: readOnlyOptions.chainId,
|
|
8344
|
+
sort,
|
|
8345
|
+
maxTokens: limit,
|
|
8346
|
+
messageScanWindow: scanWindow,
|
|
8347
|
+
thresholds: minUpvotes != null || minMarketCap != null || recencyHours != null ? {
|
|
8348
|
+
minUpvotes,
|
|
8349
|
+
minMarketCap,
|
|
8350
|
+
recencyHours
|
|
8351
|
+
} : void 0,
|
|
8352
|
+
rpcUrl: readOnlyOptions.rpcUrl
|
|
8353
|
+
});
|
|
8354
|
+
if (options.json) {
|
|
8355
|
+
console.log(
|
|
8356
|
+
JSON.stringify(
|
|
8357
|
+
{
|
|
8358
|
+
chainId: readOnlyOptions.chainId,
|
|
8359
|
+
sort,
|
|
8360
|
+
count: tokens.length,
|
|
8361
|
+
tokens: tokens.map((t) => ({
|
|
8362
|
+
...t,
|
|
8363
|
+
url: tokenUrl(readOnlyOptions.chainId, t.address)
|
|
8364
|
+
}))
|
|
8365
|
+
},
|
|
8366
|
+
null,
|
|
8367
|
+
2
|
|
8368
|
+
)
|
|
8369
|
+
);
|
|
8370
|
+
return;
|
|
8371
|
+
}
|
|
8372
|
+
if (tokens.length === 0) {
|
|
8373
|
+
console.log(chalk4.yellow("No tokens found."));
|
|
8374
|
+
return;
|
|
8375
|
+
}
|
|
8376
|
+
console.log(
|
|
8377
|
+
chalk4.white(
|
|
8378
|
+
`Top ${tokens.length} tokens by ${sort} on chain ${readOnlyOptions.chainId}:`
|
|
8379
|
+
)
|
|
8380
|
+
);
|
|
8381
|
+
console.log();
|
|
8382
|
+
tokens.forEach((t, i) => {
|
|
8383
|
+
const rank = chalk4.dim(`#${(i + 1).toString().padStart(2, " ")}`);
|
|
8384
|
+
const symbol = chalk4.cyan((t.symbol || "?").padEnd(10, " "));
|
|
8385
|
+
const upvotes = chalk4.white(`${t.upvotes} upvotes`.padEnd(18, " "));
|
|
8386
|
+
const fdv = chalk4.dim(`FDV ${formatNumber(t.fdv)}`.padEnd(14, " "));
|
|
8387
|
+
const price = chalk4.dim(`${formatPrice(t.priceInUsdc)}`.padEnd(14, " "));
|
|
8388
|
+
console.log(`${rank} ${symbol} ${upvotes} ${fdv} ${price} ${t.address}`);
|
|
8389
|
+
});
|
|
8390
|
+
} catch (error) {
|
|
8391
|
+
exitWithError(
|
|
8392
|
+
`Failed to fetch token rankings: ${error instanceof Error ? error.message : String(error)}`
|
|
8393
|
+
);
|
|
8394
|
+
}
|
|
8395
|
+
}
|
|
8396
|
+
function registerRankingsCommand(parent, commandName = "rankings") {
|
|
8397
|
+
parent.command(commandName).description(
|
|
8398
|
+
"List tokens ranked by upvote activity (trending / recent / top)"
|
|
8399
|
+
).option(
|
|
8400
|
+
"--sort <sort>",
|
|
8401
|
+
`Ranking strategy: ${VALID_SORTS.join(" | ")} (default: trending)`,
|
|
8402
|
+
"trending"
|
|
8403
|
+
).option(
|
|
8404
|
+
"--limit <n>",
|
|
8405
|
+
"Number of tokens to return (1-100, default: 50)",
|
|
8406
|
+
(v) => parseInt(v, 10),
|
|
8407
|
+
50
|
|
8408
|
+
).option(
|
|
8409
|
+
"--scan-window <n>",
|
|
8410
|
+
"Messages to scan per contract (default: 150)",
|
|
8411
|
+
(v) => parseInt(v, 10)
|
|
8412
|
+
).option(
|
|
8413
|
+
"--min-upvotes <n>",
|
|
8414
|
+
"Floor for two-tier filter (default: 500)",
|
|
8415
|
+
(v) => parseInt(v, 10)
|
|
8416
|
+
).option(
|
|
8417
|
+
"--min-market-cap <n>",
|
|
8418
|
+
"FDV floor in USDC (default: 40000)",
|
|
8419
|
+
(v) => parseInt(v, 10)
|
|
8420
|
+
).option(
|
|
8421
|
+
"--recency-hours <n>",
|
|
8422
|
+
"Drop below-floor tokens with no upvote within N hours (default: 48)",
|
|
8423
|
+
(v) => parseInt(v, 10)
|
|
8424
|
+
).option(
|
|
8425
|
+
"--chain-id <id>",
|
|
8426
|
+
"Chain ID (default: 8453 for Base)",
|
|
8427
|
+
(v) => parseInt(v, 10)
|
|
8428
|
+
).option("--rpc-url <url>", "Custom RPC URL").option("--json", "Output in JSON format").action(async (options) => {
|
|
8429
|
+
await executeRankings(options);
|
|
8430
|
+
});
|
|
8431
|
+
}
|
|
7875
8432
|
|
|
7876
8433
|
// src/commands/upvote/index.ts
|
|
7877
8434
|
function registerUpvoteCommand(program2) {
|
|
@@ -7880,6 +8437,7 @@ function registerUpvoteCommand(program2) {
|
|
|
7880
8437
|
registerGetUpvotesCommand(upvoteCommand);
|
|
7881
8438
|
registerUpvoteUserCommand(upvoteCommand);
|
|
7882
8439
|
registerGetUserUpvotesCommand(upvoteCommand);
|
|
8440
|
+
registerRankingsCommand(upvoteCommand);
|
|
7883
8441
|
}
|
|
7884
8442
|
var VALID_RUN_MODES = ["auto", "feeds", "chats"];
|
|
7885
8443
|
function addAuthOptions(cmd) {
|