Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
19 changes: 15 additions & 4 deletions packages/core-sdk/src/resources/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ export class GroupClient {
spgNftContract: validateAddress(spgNftContract),
recipient: validateAddress(recipient || this.wallet.account!.address),
maxAllowedRewardShare: BigInt(
getRevenueShare(request.maxAllowedRewardShare, RevShareType.MAX_ALLOWED_REWARD_SHARE),
getRevenueShare(
request.maxAllowedRewardShare ?? 100,
RevShareType.MAX_ALLOWED_REWARD_SHARE,
),
),
licensesData: this.getLicenseData(request.licenseData),
ipMetadata: getIpMetadataForWorkflow(request.ipMetadata),
Expand Down Expand Up @@ -275,7 +278,10 @@ export class GroupClient {
ipMetadata: getIpMetadataForWorkflow(request.ipMetadata),
tokenId: BigInt(request.tokenId),
maxAllowedRewardShare: BigInt(
getRevenueShare(request.maxAllowedRewardShare, RevShareType.MAX_ALLOWED_REWARD_SHARE),
getRevenueShare(
request.maxAllowedRewardShare ?? 100,
RevShareType.MAX_ALLOWED_REWARD_SHARE,
),
),
sigAddToGroup: {
signer: validateAddress(this.wallet.account!.address),
Expand Down Expand Up @@ -350,7 +356,12 @@ export class GroupClient {
groupPool: validateAddress(request.groupPool),
ipIds: request.ipIds,
licenseData: this.getLicenseData(request.licenseData)[0],
maxAllowedRewardShare: BigInt(getRevenueShare(request.maxAllowedRewardShare)),
maxAllowedRewardShare: BigInt(
getRevenueShare(
request.maxAllowedRewardShare ?? 100,
RevShareType.MAX_ALLOWED_REWARD_SHARE,
),
),
};
for (let i = 0; i < request.ipIds.length; i++) {
const isRegistered = await this.ipAssetRegistryClient.isRegistered({
Expand Down Expand Up @@ -491,7 +502,7 @@ export class GroupClient {
ipIds: validateAddresses(ipIds),
maxAllowedRewardShare: BigInt(
getRevenueShare(
maxAllowedRewardSharePercentage === undefined ? 100 : maxAllowedRewardSharePercentage,
maxAllowedRewardSharePercentage ?? 100,
RevShareType.MAX_ALLOWED_REWARD_SHARE_PERCENTAGE,
),
),
Expand Down
57 changes: 16 additions & 41 deletions packages/core-sdk/src/resources/ipAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
TotalLicenseTokenLimitHookClient,
WrappedIpClient,
} from "../abi/generated";
import { MAX_ROYALTY_TOKEN } from "../constants/common";
import { LicenseTermsIdInput, RevShareType } from "../types/common";
import { ChainIds } from "../types/config";
import { TransactionResponse } from "../types/options";
Expand Down Expand Up @@ -433,12 +432,9 @@ export class IPAssetClient {
arg.licenseTermsIds.map((id) => BigInt(id)),
arg.licenseTemplate || this.licenseTemplateAddress,
zeroAddress,
BigInt(arg.maxMintingFee || 0),
Number(arg.maxRts === undefined ? MAX_ROYALTY_TOKEN : arg.maxRts),
getRevenueShare(
arg.maxRevenueShare === undefined ? 100 : arg.maxRevenueShare,
RevShareType.MAX_REVENUE_SHARE,
),
BigInt(arg.maxMintingFee ?? 0),
validateMaxRts(arg.maxRts),
getRevenueShare(arg.maxRevenueShare ?? 100, RevShareType.MAX_REVENUE_SHARE),
],
});
const { result: state } = await ipAccount.state();
Expand Down Expand Up @@ -492,9 +488,8 @@ export class IPAssetClient {
childIpId: validateAddress(request.childIpId),
licenseTokenIds: request.licenseTokenIds.map((id) => BigInt(id)),
royaltyContext: zeroAddress,
maxRts: Number(request.maxRts),
maxRts: validateMaxRts(request.maxRts),
};
validateMaxRts(req.maxRts);
const isChildIpIdRegistered = await this.isRegistered(request.childIpId);
if (!isChildIpIdRegistered) {
throw new Error(`The child IP with id ${request.childIpId} is not registered.`);
Expand Down Expand Up @@ -1049,11 +1044,9 @@ export class IPAssetClient {
ipMetadata: getIpMetadataForWorkflow(request.ipMetadata),
licenseTokenIds: licenseTokenIds,
royaltyContext: zeroAddress,
maxRts: Number(request.maxRts),
maxRts: validateMaxRts(request.maxRts),
allowDuplicates: request.allowDuplicates || true,
};
validateMaxRts(object.maxRts);

const encodedTxData =
this.derivativeWorkflowsClient.mintAndRegisterIpAndMakeDerivativeWithLicenseTokensEncode(
object,
Expand Down Expand Up @@ -1130,9 +1123,8 @@ export class IPAssetClient {
deadline: calculatedDeadline,
signature,
},
maxRts: Number(request.maxRts),
maxRts: validateMaxRts(request.maxRts),
};
validateMaxRts(object.maxRts);
if (request.txOptions?.encodedTxDataOnly) {
return {
encodedTxData:
Expand Down Expand Up @@ -1694,7 +1686,7 @@ export class IPAssetClient {
}
}
/**
* Register a derivative IP asset, supporting both minted and mint-on-demand NFTs, with optional `derivData`, `royaltyShares` and `licenseTokenIds`, `maxRts`.
* Register a derivative IP asset, supporting both minted and mint-on-demand NFTs, with optional `derivData`, `royaltyShares` and `licenseTokenIds`.
*
* This method automatically selects and calls the appropriate workflow from 6 available methods based on your input parameters.
* Here are three common usage patterns:
Expand All @@ -1707,7 +1699,6 @@ export class IPAssetClient {
* parentIpIds: ["0x..."],
* licenseTermsIds: [1n],
* maxMintingFee: 10000n,
* maxRts: 100,
* maxRevenueShare: 100
* },
* royaltyShares: [
Expand All @@ -1724,18 +1715,16 @@ export class IPAssetClient {
* parentIpIds: ["0x..."],
* licenseTermsIds: [1n],
* maxMintingFee: 10000n,
* maxRts: 100,
* maxRevenueShare: 100
* }
* });
* ```
*
* **3. Mint NFT with License Token IDs and maxRts:**
* **3. Mint NFT with License Token IDs:**
* ```typescript
* const result = await client.ipAsset.registerDerivativeIpAsset({
* nft: { type: "mint", spgNftContract: "0x...", recipient: "0x...", allowDuplicates: false },
* licenseTokenIds: [1, 2, 3],
* maxRts: 100
* });
* ```
*
Expand All @@ -1752,37 +1741,25 @@ export class IPAssetClient {
* - It checks allowances for all required spenders and automatically approves them if their current allowance is lower than needed.
* - These automatic processes can be configured through the `wipOptions` parameter to control behavior like multicall usage and approval settings.
*
* @throws {Error} If `licenseTokenIds` and `maxRts` are not provided together.
* @throws {Error} If `derivData` is not provided when `royaltyShares` are provided.
* @throws {Error} If neither `derivData` nor (`licenseTokenIds` and `maxRts`) are provided.
* @throws {Error} If neither `derivData` nor `licenseTokenIds` are provided.
* @throws {Error} If the NFT type is invalid.
*/
public async registerDerivativeIpAsset<
T extends RegisterDerivativeIpAssetRequest<MintedNFT | MintNFT>,
>(request: T): Promise<RegisterDerivativeIpAssetResponse<T>> {
try {
const { nft, licenseTokenIds, maxRts, royaltyShares, derivData } = request;
if (
(licenseTokenIds && licenseTokenIds.length > 0 && maxRts === undefined) ||
(maxRts !== undefined && (!licenseTokenIds || licenseTokenIds.length === 0))
) {
throw new Error("licenseTokenIds and maxRts must be provided together.");
}

const { nft, licenseTokenIds, royaltyShares, derivData } = request;
if (royaltyShares && !derivData) {
throw new Error("derivData must be provided when royaltyShares are provided.");
}

// Validate that at least one valid combination is provided
const hasDerivData = !!derivData;
const hasLicenseTokens = !!(
licenseTokenIds &&
licenseTokenIds.length > 0 &&
maxRts !== undefined
);
const hasLicenseTokens = !!(licenseTokenIds && licenseTokenIds.length > 0);

if (!hasDerivData && !hasLicenseTokens) {
throw new Error("Either derivData or (licenseTokenIds and maxRts) must be provided.");
throw new Error("Either derivData or licenseTokenIds must be provided.");
}

if (nft.type === "minted") {
Expand All @@ -1802,7 +1779,7 @@ export class IPAssetClient {
}

/**
* Handles derivative registration for already minted NFTs with optional `derivData`, `royaltyShares` and `licenseTokenIds`, `maxRts`.
* Handles derivative registration for already minted NFTs with optional `derivData`, `royaltyShares` and `licenseTokenIds`.
*
* Supports the following workflows:
* - {@link registerDerivativeIpAndAttachLicenseTermsAndDistributeRoyaltyTokens}
Expand Down Expand Up @@ -1849,12 +1826,12 @@ export class IPAssetClient {
return this.registerIpAndMakeDerivativeWithLicenseTokens({
...baseParams,
licenseTokenIds: licenseTokenIds!,
maxRts: maxRts!,
maxRts,
});
}

/**
* Handles derivative registration for minted NFTs with optional `derivData`, `royaltyShares` and `licenseTokenIds`, `maxRts`.
* Handles derivative registration for minted NFTs with optional `derivData`, `royaltyShares` and `licenseTokenIds`.
*
* Supports the following workflows:
* - {@link mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens}
Expand Down Expand Up @@ -1901,7 +1878,7 @@ export class IPAssetClient {
return this.mintAndRegisterIpAndMakeDerivativeWithLicenseTokens({
...baseParams,
licenseTokenIds: licenseTokenIds!,
maxRts: maxRts!,
maxRts,
});
}

Expand All @@ -1916,7 +1893,6 @@ export class IPAssetClient {
* ```typescript
* const result = await client.ipAsset.linkDerivative({
* licenseTokenIds: [1, 2, 3],
* maxRts: 100,
* childIpId: "0x...",
* });
* ```
Expand All @@ -1926,7 +1902,6 @@ export class IPAssetClient {
* const result = await client.ipAsset.linkDerivative({
* parentIpIds: ["0x..."],
* licenseTermsIds: [1],
* maxRts: 100,
* childIpId: "0x...",
* });
* ```
Expand Down
7 changes: 5 additions & 2 deletions packages/core-sdk/src/resources/license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,11 @@ export class LicenseClient {
amount: BigInt(request.amount === undefined ? 1 : request.amount),
receiver,
royaltyContext: zeroAddress,
maxMintingFee: BigInt(request.maxMintingFee),
maxRevenueShare: getRevenueShare(request.maxRevenueShare, RevShareType.MAX_REVENUE_SHARE),
maxMintingFee: BigInt(request.maxMintingFee ?? 0),
maxRevenueShare: getRevenueShare(
request.maxRevenueShare ?? 100,
RevShareType.MAX_REVENUE_SHARE,
),
} as const;
if (req.maxMintingFee < 0) {
throw new Error(`The maxMintingFee must be greater than 0.`);
Expand Down
17 changes: 13 additions & 4 deletions packages/core-sdk/src/types/resources/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ export type MintAndRegisterIpAndAttachLicenseAndAddToGroupRequest = {
/**
* The maximum reward share percentage that can be allocated to each member IP.
* Must be between 0 and 100 (where 100% represents 100_000_000).
*
* @default 100
*/
maxAllowedRewardShare: RevShareInput;
maxAllowedRewardShare?: RevShareInput;
/** The data of the license and its configuration to be attached to the new group IP. */
licenseData: LicenseDataInput[];
/** The address of the recipient of the minted NFT. If not provided, the function will use the user's own wallet address. */
Expand Down Expand Up @@ -85,8 +87,13 @@ export type RegisterIpAndAttachLicenseAndAddToGroupRequest = {
deadline?: DeadlineInput;
/** The data of the license and its configuration to be attached to the new group IP. */
licenseData: LicenseDataInput[];
/** The maximum reward share percentage that can be allocated to each member IP. */
maxAllowedRewardShare: RevShareInput;
/**
* The maximum reward share percentage that can be allocated to each member IP.
* Must be between 0 and 100 (where 100% represents 100_000_000).
*
* @default 100
*/
maxAllowedRewardShare?: RevShareInput;
} & IpMetadataAndTxOptions;

export type RegisterIpAndAttachLicenseAndAddToGroupResponse = {
Expand Down Expand Up @@ -118,8 +125,10 @@ export type RegisterGroupAndAttachLicenseAndAddIpsRequest = {
/**
* The maximum reward share percentage that can be allocated to each member IP.
* Must be between 0 and 100 (where 100% represents 100_000_000).
*
* @default 100
*/
maxAllowedRewardShare: RevShareInput;
maxAllowedRewardShare?: RevShareInput;
txOptions?: TxOptions;
};

Expand Down
30 changes: 19 additions & 11 deletions packages/core-sdk/src/types/resources/ipAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,11 @@ export type RegisterDerivativeWithLicenseTokensRequest = {
childIpId: Address;
/** The IDs of the license tokens. */
licenseTokenIds: LicenseTermsIdInput[];
/** The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000). */
maxRts: MaxRtsInput;
/**
* The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000).
* @default 100_000_000
*/
maxRts?: MaxRtsInput;
txOptions?: TxOptions;
};

Expand Down Expand Up @@ -213,8 +216,11 @@ export type MintAndRegisterIpAndMakeDerivativeWithLicenseTokensRequest = {
licenseTokenIds: LicenseTermsIdInput[];
/** The address of the recipient of the minted NFT. If not provided, the client's own wallet address will be used. */
recipient?: Address;
/** The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000). */
maxRts: MaxRtsInput;
/**
* The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000).
* @default 100_000_000
*/
maxRts?: MaxRtsInput;
/**
* Set to true to allow minting an NFT with a duplicate metadata hash.
* @default true
Expand All @@ -228,8 +234,11 @@ export type RegisterIpAndMakeDerivativeWithLicenseTokensRequest = {
tokenId: TokenIdInput;
/** The IDs of the license tokens to be burned for linking the IP to parent IPs. */
licenseTokenIds: LicenseTermsIdInput[];
/** The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000). */
maxRts: MaxRtsInput;
/**
* The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000).
* @default 100_000_000
*/
maxRts?: MaxRtsInput;
/**
* The deadline for the signature in seconds.
* @default 1000
Expand All @@ -256,7 +265,8 @@ export type BatchMintAndRegisterIpAssetWithPilTermsResponse = {

export type BatchRegisterDerivativeRequest = {
args: RegisterDerivativeRequest[];
/** The deadline for the signature in seconds.
/**
* The deadline for the signature in seconds.
* @default 1000
*/
deadline?: DeadlineInput;
Expand Down Expand Up @@ -773,12 +783,10 @@ export type RegisterDerivativeIpAssetRequest<T extends MintedNFT | MintNFT> = Wi
derivData?: DerivativeDataInput;
/**
* The maximum number of royalty tokens that can be distributed to the external royalty policies (max: 100,000,000).
* Must be provided together with `licenseTokenIds`.
* @default 100_000_000
*/
maxRts?: MaxRtsInput;
/** The IDs of the license tokens to be burned for linking the IP to parent IPs.
* Must be provided together with `maxRts`.
*/
/** The IDs of the license tokens to be burned for linking the IP to parent IPs. */
licenseTokenIds?: LicenseTermsIdInput[];
/**
* The deadline for the signature in seconds.
Expand Down
16 changes: 12 additions & 4 deletions packages/core-sdk/src/types/resources/license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,18 @@ export type MintLicenseTokensRequest = {
* Defaults to {@link https://docs.story.foundation/docs/programmable-ip-license | PIL} address if not provided.
*/
licenseTemplate?: Address;
/** The maximum minting fee that the caller is willing to pay. if set to 0 then no limit. */
maxMintingFee: FeeInput;
/** The maximum revenue share percentage allowed for minting the License Tokens. Must be between 0 and 100,000,000 (where 100,000,000 represents 100%). */
maxRevenueShare: RevShareInput;
/**
* The maximum minting fee that the caller is willing to pay.if set to 0 then no limit.
*
* @default 0
*/
maxMintingFee?: FeeInput;
/**
* The maximum revenue share percentage allowed for minting the License Tokens. Must be between 0 and 100,000,000 (where 100,000,000 represents 100%).
*
* @default 100
*/
maxRevenueShare?: RevShareInput;
/**
* The amount of license tokens to mint.
* @default 1
Expand Down
Loading