Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions lib/price.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export const mcv2BondAbi = [
{ name: "token", type: "address" },
{ name: "tokensToMint", type: "uint256" },
],
outputs: [{ name: "reserveAmount", type: "uint256" }],
outputs: [
{ name: "reserveAmount", type: "uint256" },
{ name: "royalty", type: "uint256" },
],
},
{
type: "function",
Expand All @@ -31,7 +34,10 @@ export const mcv2BondAbi = [
{ name: "token", type: "address" },
{ name: "tokensToBurn", type: "uint256" },
],
outputs: [{ name: "refundAmount", type: "uint256" }],
outputs: [
{ name: "refundAmount", type: "uint256" },
{ name: "royalty", type: "uint256" },
],
},
{
type: "function",
Expand All @@ -43,7 +49,7 @@ export const mcv2BondAbi = [
{ name: "maxReserveAmount", type: "uint256" },
{ name: "receiver", type: "address" },
],
outputs: [],
outputs: [{ name: "", type: "uint256" }],
},
{
type: "function",
Expand All @@ -55,7 +61,7 @@ export const mcv2BondAbi = [
{ name: "minRefund", type: "uint256" },
{ name: "receiver", type: "address" },
],
outputs: [],
outputs: [{ name: "", type: "uint256" }],
},
{
type: "function",
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/commands/claim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ export function registerClaim(program: Command): void {
// Default to 18/TOKEN if calls fail
}

const info = await client.getRoyaltyInfo(tokenAddress, creator);
const formatted = formatUnits(info.unclaimed, decimals);
const info = await client.getRoyaltyInfo(creator, reserveToken);
const formatted = formatUnits(info.balance, decimals);
console.log(` Unclaimed: ${formatted} ${symbol}`);
console.log(` Beneficiary: ${creator}`);

if (info.unclaimed === 0n) {
if (info.balance === 0n) {
console.log("No royalties to claim.");
return;
}

console.log("Claiming royalties...");
const txHash = await client.claimRoyalties(tokenAddress);
const txHash = await client.claimRoyalties(reserveToken);
console.log(`Royalties claimed! TX: ${txHash}`);
} catch (err) {
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
Expand Down
8 changes: 5 additions & 3 deletions packages/cli/src/commands/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function registerStatus(program: Command): void {
let tokenSymbol = "TOKEN";
let tokenDecimals = 18;
let bondCreator: Address | null = null;
let bondReserveToken: Address | null = null;
try {
const bond = await client.publicClient.readContract({
address: MCV2_BOND_ADDRESS,
Expand All @@ -65,6 +66,7 @@ export function registerStatus(program: Command): void {
});
bondCreator = (bond as readonly unknown[])[0] as Address;
const reserveToken = (bond as readonly unknown[])[4] as Address;
bondReserveToken = reserveToken;
const [sym, dec] = await Promise.all([
client.publicClient.readContract({
address: reserveToken,
Expand Down Expand Up @@ -93,9 +95,9 @@ export function registerStatus(program: Command): void {
// -----------------------------------------------------------------
let unclaimedRoyalty: bigint | null = null;
try {
if (bondCreator) {
const royalty = await client.getRoyaltyInfo(info.tokenAddress, bondCreator);
unclaimedRoyalty = royalty.unclaimed;
if (bondCreator && bondReserveToken) {
const royalty = await client.getRoyaltyInfo(bondCreator, bondReserveToken);
unclaimedRoyalty = royalty.balance;
}
} catch {
// Token may not have a bond yet
Expand Down
11 changes: 7 additions & 4 deletions packages/sdk/src/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,19 @@ export const mcv2BondAbi = [
name: "getRoyaltyInfo",
stateMutability: "view",
inputs: [
{ name: "token", type: "address" },
{ name: "beneficiary", type: "address" },
{ name: "wallet", type: "address" },
{ name: "reserveToken", type: "address" },
],
outputs: [
{ name: "balance", type: "uint256" },
{ name: "claimed", type: "uint256" },
],
outputs: [{ name: "unclaimed", type: "uint256" }],
},
{
type: "function",
name: "claimRoyalties",
stateMutability: "nonpayable",
inputs: [{ name: "token", type: "address" }],
inputs: [{ name: "reserveToken", type: "address" }],
outputs: [],
},
{
Expand Down
27 changes: 14 additions & 13 deletions packages/sdk/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ export interface SetAgentWalletResult {
}

export interface RoyaltyInfo {
unclaimed: bigint;
balance: bigint;
claimed: bigint;
}

export interface TokenPriceInfo {
Expand Down Expand Up @@ -493,37 +494,37 @@ export class PlotLink {
// -------------------------------------------------------------------------

/**
* Get unclaimed royalty info for a storyline token.
* Get royalty info for a beneficiary on a given reserve token.
*
* @param tokenAddress - The storyline's ERC-20 token address
* @param beneficiary - The royalty beneficiary (usually the bond creator)
* @returns Unclaimed royalty amount
* @param reserveToken - The reserve token address (e.g. WETH on testnet, $PLOT on mainnet)
* @returns Balance (unclaimed) and claimed royalty amounts
*/
async getRoyaltyInfo(tokenAddress: Address, beneficiary: Address): Promise<RoyaltyInfo> {
const unclaimed = await this.publicClient.readContract({
async getRoyaltyInfo(beneficiary: Address, reserveToken: Address): Promise<RoyaltyInfo> {
const [balance, claimed] = await this.publicClient.readContract({
address: this.mcv2Bond,
abi: mcv2BondAbi,
functionName: "getRoyaltyInfo",
args: [tokenAddress, beneficiary],
});
args: [beneficiary, reserveToken],
}) as [bigint, bigint];

return { unclaimed: unclaimed as bigint };
return { balance, claimed };
}

/**
* Claim accumulated royalties for a storyline token from the MCV2_Bond
* Claim accumulated royalties for a reserve token from the MCV2_Bond
* bonding curve contract.
*
* @param tokenAddress - The storyline's ERC-20 token address
* @param reserveToken - The reserve token address (e.g. WETH on testnet, $PLOT on mainnet)
* @returns Transaction hash
*/
async claimRoyalties(tokenAddress: Address): Promise<Hex> {
async claimRoyalties(reserveToken: Address): Promise<Hex> {
const { request } = await this.publicClient.simulateContract({
account: this.walletClient.account!,
address: this.mcv2Bond,
abi: mcv2BondAbi,
functionName: "claimRoyalties",
args: [tokenAddress],
args: [reserveToken],
});

const txHash = await this.walletClient.writeContract(request);
Expand Down
1 change: 1 addition & 0 deletions src/components/PriceChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function PriceChart({ tokenAddress, totalSupplyRaw, currentPriceRaw }: Pr
functionName: "getReserveForToken",
args: [tokenAddress, amount],
})
.then((r) => (r as readonly [bigint, bigint])[0])
.catch(() => BigInt(0)),
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/TradingWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export function TradingWidget({ tokenAddress }: { tokenAddress: Address }) {
functionName: tab === "buy" ? "getReserveForToken" : "getRefundForTokens",
args: [tokenAddress, parsedAmount],
});
return result;
// ABI returns [amount, royalty] tuple — extract the amount
return (result as readonly [bigint, bigint])[0];
},
enabled: parsedAmount > BigInt(0),
refetchInterval: 15000,
Expand Down
Loading