Skip to content

Commit

Permalink
Add ipAsset module methods including registerDerivative and registerD…
Browse files Browse the repository at this point in the history
…erivativeWithLicenseTokens
  • Loading branch information
bonnie57 committed Apr 12, 2024
1 parent 7a10cb3 commit a013af7
Show file tree
Hide file tree
Showing 8 changed files with 472 additions and 325 deletions.
9 changes: 8 additions & 1 deletion packages/core-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ export { DisputeClient } from "./resources/dispute";
export type { StoryConfig } from "./types/config";
export type { Hex, TypedData } from "./types/common";

export type { RegisterIpResponse, RegisterRequest } from "./types/resources/ipAsset";
export type {
RegisterIpResponse,
RegisterRequest,
RegisterDerivativeResponse,
RegisterDerivativeRequest,
RegisterDerivativeWithLicenseTokensRequest,
RegisterDerivativeWithLicenseTokensResponse,
} from "./types/resources/ipAsset";

export type {
MintLicenseTokensResponse,
Expand Down
124 changes: 106 additions & 18 deletions packages/core-sdk/src/resources/ipAsset.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import { Hex, PublicClient, WalletClient, getAddress } from "viem";
import { Hex, PublicClient, WalletClient, getAddress, zeroAddress } from "viem";

import { chain, parseToBigInt, waitTxAndFilterLog } from "../utils/utils";
import { getIPAssetRegistryConfig } from "../abi/config";
import { chain, parseToBigInt, waitTx, waitTxAndFilterLog } from "../utils/utils";
import {
getIPAssetRegistryConfig,
getLicenseTemplateConfig,
getLicensingModuleConfig,
} from "../abi/config";
import { SupportedChainIds } from "../types/config";
import { handleError } from "../utils/errors";
import { RegisterIpResponse, RegisterRequest } from "../types/resources/ipAsset";
import {
RegisterDerivativeRequest,
RegisterDerivativeResponse,
RegisterDerivativeWithLicenseTokensRequest,
RegisterDerivativeWithLicenseTokensResponse,
RegisterIpResponse,
RegisterRequest,
} from "../types/resources/ipAsset";

export class IPAssetClient {
private readonly wallet: WalletClient;
private readonly rpcClient: PublicClient;
private readonly chainId: SupportedChainIds;
public ipAssetRegistryConfig;
public licenseModuleConfig;
public licenseTemplateConfig;

constructor(rpcClient: PublicClient, wallet: WalletClient, chainId: SupportedChainIds) {
this.wallet = wallet;
this.rpcClient = rpcClient;
this.chainId = chainId;
this.ipAssetRegistryConfig = getIPAssetRegistryConfig(chainId);
this.licenseModuleConfig = getLicensingModuleConfig(chainId);
this.licenseTemplateConfig = getLicenseTemplateConfig(chainId);
}
private async isNFTRegistered(tokenAddress: Hex, tokenId: bigint): Promise<Hex> {
const ipId = await this.rpcClient.readContract({
...this.ipAssetRegistryConfig,
functionName: "ipId",
args: [parseToBigInt(chain[this.chainId]), tokenAddress, tokenId],
});
const isRegistered = await this.rpcClient.readContract({
...this.ipAssetRegistryConfig,
functionName: "isRegistered",
args: [ipId],
});
return isRegistered ? ipId : "0x";
}

/**
* Registers an NFT as IP, creating a corresponding IP record.
* @param request The request object that contains all data needed to register IP.
Expand Down Expand Up @@ -68,4 +69,91 @@ export class IPAssetClient {
handleError(error, "Failed to register IP");
}
}

/**
* Registers a derivative directly with parent IP's license terms, without needing license tokens,
* and attaches the license terms of the parent IPs to the derivative IP.
* The license terms must be attached to the parent IP before calling this function.
* All IPs attached default license terms by default.
* The derivative IP owner must be the caller or an authorized operator.
* @param request The request object that contains all data needed to register derivative IP.
* @param request.childIpId The derivative IP ID.
* @param request.parentIpIds The parent IP IDs.
* @param request.licenseTermsIds The IDs of the license terms that the parent IP supports.
* @param request.txOptions [Optional] The transaction options.
* @returns A Promise that resolves to an object containing the transaction hash.
*/
public async registerDerivative(
request: RegisterDerivativeRequest,
): Promise<RegisterDerivativeResponse> {
try {
const { request: call } = await this.rpcClient.simulateContract({
...this.licenseModuleConfig,
functionName: "registerDerivative",
args: [
request.childIpId,
request.parentIpIds,
request.licenseTermsIds.map((id) => BigInt(id)),
request.licenseTemplate || this.licenseTemplateConfig.address,
zeroAddress,
],
account: this.wallet.account,
});
const txHash = await this.wallet.writeContract(call);
if (request.txOptions?.waitForTransaction) {
await waitTx(this.rpcClient, txHash);
return { txHash };
} else {
return { txHash };
}
} catch (error) {
handleError(error, "Failed to register derivative");
}
}

/**
* Registers a derivative with license tokens.
* the derivative IP is registered with license tokens minted from the parent IP's license terms.
* the license terms of the parent IPs issued with license tokens are attached to the derivative IP.
* the caller must be the derivative IP owner or an authorized operator.
* @param request The request object that contains all data needed to register derivative license tokens.
* @param request.childIpId The derivative IP ID.
* @param request.licenseTokenIds The IDs of the license tokens.
* @param request.txOptions [Optional] The transaction options.
* @returns A Promise that resolves to an object containing the transaction hash.
*/
public async registerDerivativeWithLicenseTokens(
request: RegisterDerivativeWithLicenseTokensRequest,
): Promise<RegisterDerivativeWithLicenseTokensResponse> {
try {
const { request: call } = await this.rpcClient.simulateContract({
...this.licenseModuleConfig,
functionName: "registerDerivativeWithLicenseTokens",
args: [request.childIpId, request.licenseTokenIds.map((id) => BigInt(id)), zeroAddress],
account: this.wallet.account,
});
const txHash = await this.wallet.writeContract(call);
if (request.txOptions?.waitForTransaction) {
await waitTx(this.rpcClient, txHash);
return { txHash: txHash };
} else {
return { txHash: txHash };
}
} catch (error) {
handleError(error, "Failed to register derivative with license tokens");
}
}
private async isNFTRegistered(tokenAddress: Hex, tokenId: bigint): Promise<Hex> {
const ipId = await this.rpcClient.readContract({
...this.ipAssetRegistryConfig,
functionName: "ipId",
args: [parseToBigInt(chain[this.chainId]), tokenAddress, tokenId],
});
const isRegistered = await this.rpcClient.readContract({
...this.ipAssetRegistryConfig,
functionName: "isRegistered",
args: [ipId],
});
return isRegistered ? ipId : "0x";
}
}
17 changes: 8 additions & 9 deletions packages/core-sdk/src/resources/license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class LicenseClient {
};
const licenseTermsId = await this.getLicenseTermsId(licenseTerms);
if (licenseTermsId !== 0) {
return { licenseId: licenseTermsId.toString() };
return { licenseTermsId: licenseTermsId.toString() };
}
const { request: call } = await this.rpcClient.simulateContract({
...this.licenseTemplateConfig,
Expand All @@ -103,7 +103,7 @@ export class LicenseClient {
...this.licenseTemplateConfig,
eventName: "LicenseTermsRegistered",
});
return { txHash: txHash, licenseId: targetLogs[0].args.licenseTermsId.toString() };
return { txHash: txHash, licenseTermsId: targetLogs[0].args.licenseTermsId.toString() };
} else {
return { txHash: txHash };
}
Expand Down Expand Up @@ -146,7 +146,7 @@ export class LicenseClient {
};
const licenseTermsId = await this.getLicenseTermsId(licenseTerms);
if (licenseTermsId !== 0) {
return { licenseId: licenseTermsId.toString() };
return { licenseTermsId: licenseTermsId.toString() };
}

const { request: call } = await this.rpcClient.simulateContract({
Expand All @@ -162,7 +162,7 @@ export class LicenseClient {
...this.licenseTemplateConfig,
eventName: "LicenseTermsRegistered",
});
return { txHash: txHash, licenseId: targetLogs[0].args.licenseTermsId.toString() };
return { txHash: txHash, licenseTermsId: targetLogs[0].args.licenseTermsId.toString() };
} else {
return { txHash: txHash };
}
Expand Down Expand Up @@ -205,7 +205,7 @@ export class LicenseClient {
};
const licenseTermsId = await this.getLicenseTermsId(licenseTerms);
if (licenseTermsId !== 0) {
return { licenseId: licenseTermsId.toString() };
return { licenseTermsId: licenseTermsId.toString() };
}
const { request: call } = await this.rpcClient.simulateContract({
...this.licenseTemplateConfig,
Expand All @@ -220,7 +220,7 @@ export class LicenseClient {
...this.licenseTemplateConfig,
eventName: "LicenseTermsRegistered",
});
return { txHash: txHash, licenseId: targetLogs[0].args.licenseTermsId.toString() };
return { txHash: txHash, licenseTermsId: targetLogs[0].args.licenseTermsId.toString() };
} else {
return { txHash: txHash };
}
Expand All @@ -230,10 +230,9 @@ export class LicenseClient {
}

/**
* Attaches license terms to an IP, and the function must be called by the IP owner or an authorized operator.
* Attaches license terms to an IP.
* @param request The request object that contains all data needed to attach license terms.
@param request.ipId The IP ID.
@param request.tokenAddress The address of the NFT.
@param request.ipId The address of the IP to which the license terms are attached.
@param request.licenseTemplate The address of the license template.
@param request.licenseTermsId The ID of the license terms.
* @param request.txOptions [Optional] The transaction options.
Expand Down
23 changes: 23 additions & 0 deletions packages/core-sdk/src/types/resources/ipAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,26 @@ export type RegisterRequest = {
tokenId: string;
txOptions?: TxOptions;
};

export type RegisterDerivativeWithLicenseTokensRequest = {
childIpId: Hex;
licenseTokenIds: string[];
txOptions?: TxOptions;
};

export type RegisterDerivativeWithLicenseTokensResponse = {
txHash: string;
};

export type RegisterDerivativeRequest = {
childIpId: Hex;
parentIpIds: Hex[];
licenseTermsIds: string[];
licenseTemplate?: Hex;
txOptions?: TxOptions;
};

export type RegisterDerivativeResponse = {
txHash?: string;
childIpId?: Hex;
};
4 changes: 2 additions & 2 deletions packages/core-sdk/src/types/resources/license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export type LicenseTerms = {
export type LicenseTermsIdResponse = number;

export type RegisterLicenseTermsResponse = {
licenseId?: string;
licenseTermsId?: string;
txHash?: string;
};

Expand All @@ -56,8 +56,8 @@ export type RegisterCommercialRemixPILRequest = {

export type AttachLicenseTermsRequest = {
ipId: Hex;
licenseTemplate?: Hex;
licenseTermsId: string;
licenseTemplate?: Hex;
txOptions?: TxOptions;
};

Expand Down
Loading

0 comments on commit a013af7

Please sign in to comment.