Releases: storyprotocol/sdk
v1.3.1-beta
SDK Release Notes – v1.3.1-beta
Version 1.3.1-Beta introduces optimized workflows for registering IP Assets. This update also includes new methods for retrieving licensing configurations associated with a specific IP and adding one or more IPs to an existing IP group.
Features & Enhancements
- Adds the
batchRegisterIpAssetsWithOptimizedWorkflows
function to theIPAsset
module. #505 - Adds the
getLicensingConfig
function to theLicense
module. #500 - Adds the
addIpsToGroup
function to theGroup
module. #504
Bug Fixes
- Fix the issue in the
mintAndRegisterIp
function that arises when using multicall. #505
Migration Guide
Migrating from v1.2.x
- Please refer to the 1.3.0-rc.1 release notes.
v1.3.0 Release
SDK Release Notes – v1.3.0
Version 1.3.0 of the Story Protocol SDK has been released, featuring significant enhancements, key bug fixes, and improvements to developer experience and documentation.
Features & Enhancements
- Enhance
mintLicenseTokens
by enforcing license term attachment rules with exceptions for default terms and IP owners. #485 - Increase integration test coverage for Dispute, License, and Royalty modules to validate
batchClaimAllRevenue
behavior with additional test cases. #493 - Add minimum bond check in the Dispute module and make the bond parameter optional, defaulting to the required minimum value. #494
- Data field in the Cancel and Resolve Dispute methods is now optional. #490
getDerivedStoryClient
method from the BIP32 utility module, now returns the address in addition to the client. #493
Bug Fixes
- Fix
tagIfRelatedIpInfringed
to correctly handle multiple data entries whenuseMulticallWhenPossible
is false, preventing nonce collisions due to concurrent execution. The issue arose because the SDK only tested single-entry cases in this configuration.#484 - Update integration tests to comply with the Dispute Module’s new minimum bond requirement of 0.1 IP, as zero-value bonds are no longer supported. #487 #494
- Fix incorrect spender assignment in
registerDerivative
, changing fromroyaltyTokenDistributionWorkflows
toroyaltyModule
. #488 - Verify that
approve
transaction in the Dispute module is properly awaited before proceeding, preventing race conditions in subsequent function executions. Integration tests were also properly updated. #482 - It fixes a bugh when calling
predictMintingLicenseFee
to estimate license fees with default license terms. #485
Migration Guide
Migrating from v1.2.x
- Please refer to the 1.3.0-rc.1 release notes
Documentation
- Improved code comments across the Client and Dispute modules, along with enhancements to config file documentation for clarity and maintainability. #491
- Updated
README
by moving setup and testing instructions to the CONTRIBUTING.md file, and streamline content based on feedback for improved clarity. #492
New Contributors
- @holazz – #415
- @Dimitrolito – #369
@story-protocol/core-sdk@1.3.0-rc.3
Migration Guide
Migrating from 1.3.0-rc.2
to 1.3.0-rc.3
No changes.
Migrating from v1.2.x
Please refer to the 1.3.0-rc.1 release notes.
Key Changes
New Group Client Method: collectAndDistributeGroupRoyalties
This method collects royalties for the entire group and distribute the rewards to each member IP's royalty vault. See POC function.
Usage Example
const result = await storyClient.groupClient.collectAndDistributeGroupRoyalties({
groupIpId: groupIpId,
currencyTokens: [WIP_TOKEN_ADDRESS],
memberIpIds: ipIds,
txOptions: { waitForTransaction: true },
});
New Royalty Client Method: transferToVault
Transfers to vault an amount of revenue tokens claimable via a royalty policy.
Usage Example
const result = await storyClient.royalty.transferToVault({
royaltyPolicy: NativeRoyaltyPolicy.LAP,
ipId,
ancestorIpId,
token: WIP_TOKEN_ADDRESS,
txOptions: { waitForTransaction: true },
});
Bug Fixes
- Fixed an issue with
disputeAssertion
indispute
client where the approval call is not properly handled. #482.
@story-protocol/core-sdk@1.3.0-rc.2
Migration Guide
Migrating from 1.3.0-rc.1
to 1.3.0-rc.2
No changes.
Migrating from v1.2.x
Please refer to the 1.3.0-rc.1 release notes.
Key Changes
-
Improved Revenue Claiming
- Updated Methods:
claimAllRevenue
andbatchClaimAllRevenue
now useexecuteBatch
fromipAccount
to batch ERC20 transfers from a single IP account. (#454)
- Updated Methods:
-
IP → WIP Conversion Support in Disputes
- Added support for IP to WIP conversion in
raiseDispute
anddisputeAssertion
within the disputes client. (#456)
- Added support for IP to WIP conversion in
-
Fixed Contract Addresses
- Corrected the contract addresses of
IpRoyaltyVaultImpl
andSPGNFTImpl
on theaeneid
network. (#458)
- Corrected the contract addresses of
-
New ERC20 Transfer Method in ipAccount
- Added a new method,
transferErc20
, to theipAccount
client, enabling multiple ERC20 transfers within an IP account. (#457)
Example Usage
// Transfer one or more ERC20 tokens within an IP account await client.ipAccount.transferErc20({ ipId: ip.id, tokens: [ { address: tokenAddress, target: wallet.address, amount: 100, }, ], txOptions: { waitForTransaction: true }, });
- Added a new method,
@story-protocol/core-sdk@1.3.0-rc.1
Migration
Migrating from 1.3.0-beta.3
to 1.3.0-rc.1
- Request type definition for
generateIpMetadata
is updated to comply with the latest IPA Metadata Standard, as documented here. - The
type
property inIpRelationship
has been changed from astring
to anenum
, with all supported values now explicitly defined.
Migrating from 1.2.x
Please refer to the 1.3.0-beta.2 migration guide.
Key Changes
Optional License Configuration
The license config, initially required in v1.3.0-beta.1
when registering IP assets with PIL terms, is now optional. If not provided, the SDK will use a default license config.
Default License Config
{
"isSet": false,
"mintingFee": 0,
"licensingHook": "0x0000000000000000000000000000000000000000",
"hookData": "0x0000000000000000000000000000000000000000",
"commercialRevShare": 0,
"disabled": false,
"expectMinimumGroupRewardShare": 0,
"expectGroupRewardPool": "0x0000000000000000000000000000000000000000"
}
Optional Properties for Derivatives
The following properties for registering derivative IP assets, introduced in 1.3.0-beta.1
, are now optional:
maxMintingFee
: Defaults to 0 if not provided, indicating no max minting fee.maxRts
: Defaults to 100,000,000 if not provided.maxRevenueShare
: Defaults to 100 if not provided.- Note: This value is a percentage. Internally, it is converted to an absolute value based on a total of 100,000,000 royalty tokens. For example, 50 would be converted to 50,000,000.
Optional allowDuplicates
The allowDuplicates
property, introduced as a required field in 1.3.0-beta.1
to allow minting NFTs with duplicate metadata hashes, is now optional. If not provided, it defaults to true.
New Dispute Method: tagIfRelatedIpInfringed
The tagIfRelatedIpInfringed
method allows tagging derivative IP assets if the parent IP has been tagged with an infringement, or tagging group IP assets if a group member has been tagged.
- Multicall will be used automatically when multiple IP assets need to be tagged.
Usage Example
const results = await client.dispute.tagIfRelatedIpInfringed({
infringementTags: [
{
ipId: childIpId,
disputeId: disputeId,
},
{
ipId: childIpId2,
disputeId: disputeId,
},
],
txOptions: { waitForTransaction: true },
});
Disable Multicall
const result = await client.dispute.tagIfRelatedIpInfringed({
infringementTags: [
{
ipId: childIpId,
disputeId: disputeId,
},
],
options: { useMulticallWhenPossible: false },
});
Wrapped IP Client: New Methods
Two new methods have been added to the wip
client to facilitate WIP (Wrapper IP Tokens) transfers:
transfer
: Transfers a specified amount of WIP to a recipient.transferForm
: Transfers a specified amount of WIP from one account to another.
NFT Client: New Methods
getMintFeeToken
: Gets the mint fee token of an SPG NFT contract.getMintFee
: Gets the mint fee of an SPG NFT contract.
These methods are useful to determine the amount of WIP or any other ERC20 tokens required to mint an SPG NFT collection.
Auto ERC20 Approval for payRoyaltyOnBehalf
The payRoyaltyOnBehalf
method in the royalty
client now automatically approves ERC20 tokens for royalty payments if there is insufficient allowance. Previously, this functionality only applied to WIP tokens.
- Note: Multicall is not supported for auto-approving ERC20 tokens.
Usage Example
client.royalty.payRoyaltyOnBehalf({
receiverIpId,
payerIpId,
token: "0xF2104833d386a2734a4eB3B8ad6FC6812F29E38E", // mock ERC20 token
amount: 10,
txOptions: { waitForTransaction: true },
}),
Disable Auto ERC20 Approval
client.royalty.payRoyaltyOnBehalf({
// other params
erc20Options: { enableAutoApprove: false }
});
Auto IP → WIP Conversion Additions
Two more methods in the IP Asset Client are updated to support Auto IP Wrapping. For more details on Auto Wrapping IP, refer to v1.3.0-beta.2.
mintAndRegisterIp
: Automatically converts IP to WIP if the SPG NFT minting fee is required in WIP.registerDerivative
: Automatically converts IP to WIP if the derivative minting fee requires WIP.
Update to IPA Metadata Standard
The following updates have been made to comply with the latest IPA Metadata Standard, as documented here:
generateCreatorMetadata
no longer sets the following properties to empty default values if not provided:description
image
socialMedia
role
- The request type for
generateIpMetadata
has been updated to align with the latest IPA Metadata Standard, with inline documentation added to each property for better clarity. - The
type
property inIpRelationship
has been changed from a string to an enum, with all supported values now explicitly defined.
New Dispute Method: disputeAssertion
Counters a dispute that was raised by another party on an IP using counter evidence that is uploaded to IPFS.
This method can only be called by the IP's owner to counter a dispute by providing counter evidence. The counter evidence (e.g., documents, images) should be uploaded to IPFS, and its corresponding CID is converted internally to a hash for the request.
Getting Assertion ID
If you only have the dispute ID, you can retrieve the assertion ID by calling the newly added getDisputeIdFromAssertionId
method in the dispute client.
Usage Example
const ret = await client.dispute.disputeAssertion({
ipId, // the ipId of the disputed IP
assertionId, // the assertionId of the dispute
counterEvidenceCID, // CID of the counter evidence
});
New Royalty Method: batchClaimAllRevenue
The batchClaimAllRevenue
method allows batching multiple claimAllRevenue
requests into a single process.
This method can perform the following on-chain transactions:
- Claim all revenue from the child IPs of the provided ancestor IPs.
- If Multicall is enabled, this is executed as a single transaction.
- If Multicall is disabled, a separate transaction is executed for each
ancestorIp
.
- Transfer currency tokens from the IP Account to the claimer's wallet.
- This occurs only if the claimer is an IP Account and your wallet owns the IP.
- If the claimer is your own wallet or you do not own the IP Account, this step is skipped.
- If multiple currency tokens are claimed, each transfer is executed as a separate on-chain transaction.
- If there are multiple unique IP Account claimers in the provided
ancestorIps
, each claimer must transfer all their claimed currency tokens. - The total number of transactions for this step is:
unique IP Account claimers × number of claimed currency tokens per claimer
.
- Convert WIP to IP for any claimed WIP tokens transferred to your wallet.
- This step is executed only if WIP tokens are transferred.
- If no WIP tokens are received, no conversion occurs.
When Multicall is enabled, the total number of transactions executed is:
1 (claim all revenue)
+ (unique IP Account claimers × number of claimed currency tokens per claimer)
+ 1 (WIP → IP conversion, if applicable)
Usage Example
const result = await client.royalty.batchClaimAllRevenue({
ancestorIps: [
{
ipId: ipA,
claimer: ipA,
childIpIds: [],
royaltyPolicies: [],
currencyTokens: [WIP_TOKEN_ADDRESS], // even if no child ips, you need to include what tokens to claim.
},
{
ipId: ipB,
claimer: ipB,
childIpIds: [ipC, ipD],
royaltyPolicies: [royaltyPolicyLrpAddress[aeneid], royaltyPolicyLrpAddress[aeneid]],
currencyTokens: [WIP_TOKEN_ADDRESS, WIP_TOKEN_ADDRESS],
},
],
});
Disable IP Account Claims Transfer
Disable the SDK from trying to automatically transfer the claimed tokens from the IP Account back to your wallet.
await client.royalty.batchClaimAllRevenue({
// ...other params
claimOptions: { autoTransferAllClaimedTokensFromIp: false }
});
Disable IP → WIP Conversion
To prevent automatic conversion of WIP to IP, override the following option.
await client.royalty.batchClaimAllRevenue({
// ...other params
claimOptions: { autoUnwrapIpTokens: false }
});
New IPAccount Method: setIpMetadata
The setIpMetadata
method allows setting the metadataURI
and metadataHash
for an IP asset owned by the wallet.
This utility method calls the setMetadataURI
function on the CoreMetadataModule
contract through the IP Account of the IP asset owned by the client wallet.
Usage Example
const txHash = await client.ipAccount.setIpMetadata({
ipId,
metadataURI: "https://example.com",
metadataHash: "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997",
});
Other Changes
- Enhanced unit test coverage for the
wip
client. - Improve error messaging for
maxAllowedRewardShare
input validation. PIL_TYPE.COMMERCIAL_USE
has been updated to set bothderivativesAllowed
andderivativesAttribution
to false.- New constants, classes, and types have been exported:
WipClient
,ERC20Options
,WipOptions
,TransactionResponse
ClaimAllRevenueRequest
,ClaimAllRevenueResponse
,
BatchClaimAllRevenueRequest
, `BatchCl...
@story-protocol/core-sdk@1.3.0-beta.3
Migration
No changes required from 1.3.0-beta.2
Changes
- Support for Mainnet
StoryClient.newClient({
chainId: "mainnet", // or 1514
transport: http(RPC),
});
- Fixed an issue with ipAsset
batchRegister
not supportingipMetadata
- Fixed bug with
mintLicenseToken
not approving the correct spender for WIP usage - Wrapped IP token address is now exported.
WIP_TOKEN_ADDRESS
@story-protocol/core-sdk@1.3.0-beta.2
Migration
All previous SDK versions must be updated to 1.3.0-beta.2
to ensure full compatibility with POC v1.3 on aeneid
.
Migrating from 1.3.0-beta.1
- Update
chainId
fromhomer
toaeneid
when creating a new Story Client:
StoryClient.newClient({
chainId: "aeneid",
transport: http(RPC),
});
- If you are using
ipAsset.mintAndRegisterIpAndMakeDerivative
, note that the response fieldchildIpId
has been renamed toipId
.
Migrating from v1.2.x
Follow our migration guide.
Changes
Support for aeneid
Testnet
The homer
testnet has been renamed to aeneid
. You can find the latest RPC details here.
StoryClient.newClient({
chainId: "aeneid",
transport: http(RPC),
});
New Wrapped IP Client
The wip
client allows conversion between IP and WIP.
// IP -> WIP
const rsp = await client.wipClient.deposit({
amount,
txOptions: { waitForTransaction: true },
});
// WIP -> IP
const rsp = await client.wipClient.withdraw({
amount,
txOptions: { waitForTransaction: true },
});
Also check for WIP balance
await client.wipClient.balanceOf("0x0000000000000000000000000000000000000000");
New Royalty Method: claimAllRevenue
A new method, claimAllRevenue
, has been added to the Royalty module. It allows claiming all revenue from the child IPs of an ancestor IP.
If the wallet owns the IP and the claimer is the IP Account, all claimed tokens will be automatically transferred from the IP Account to the client’s wallet.
If any claimed tokens are WIP, they will be automatically converted back to IP unless disabled via options.
Disable IP Account Claims Transfer
Disable the SDK from trying to automatically transfer the claimed tokens from the IP Account back to your wallet.
await client.royalty.claimAllRevenue({
// ...other params
claimOptions: { autoTransferAllClaimedTokensFromIp:false }
});
Disable IP → WIP Conversion
To prevent automatic conversion of WIP to IP, override the following option.
await client.royalty.claimAllRevenue({
// ...other params
claimOptions: { autoUnwrapIpTokens: false }
});
Auto Wrapping IP
The SDK now supports automatic conversion of IP to WIP when a wallet lacks sufficient WIP to cover minting fees.
If the wallet does not have enough WIP
- The SDK will first convert IP → WIP, then approve the SPG contracts to use the WIP, and finally execute the SPG contract call.
- This process typically involves two or more transactions, but with Multicall, it is bundled into a single transaction for efficiency.
- Multicall is automatically enabled for all supported methods. Methods that do not currently support Multicall are listed under Supported Methods below.
If the wallet has enough WIP
- The SDK will use the available WIP directly.
- If the SPG contracts have not been approved to use the WIP, the SDK will include any necessary approval transactions automatically. Approvals are only needed once per SGP contract.
- Multicall is not yet supported for this flow, but future updates may enable it.
If the wallet lacks both WIP and IP
- An error will be thrown indicating insufficient funds.
Supported Methods
The following SDK methods support automatic IP → WIP conversion when minting fees in WIP is required. This behavior can be customized via wipOptions
:
license.mintLicenseTokens
- Pay license minting fee
ipAsset.mintAndRegisterIpAssetWithPilTerms
- Pay NFT minting fee
ipAsset.mintAndRegisterIpAndMakeDerivativeWithLicenseTokens
- Pay NFT and license minting fee
- Does not support Multicall
ipAsset.mintAndRegisterIpAndMakeDerivativeAndDistributeRoyaltyTokens
- Pay NFT and license minting fee
ipAsset.mintAndRegisterIpAndAttachPilTermsAndDistributeRoyaltyTokens
- Pay NFT minting fee
ipAsset.registerDerivativeIpAndAttachLicenseTermsAndDistributeRoyaltyTokens
- Pay license minting fee
- Does not support Multicall
ipAsset.registerDerivativeIp
- Pay license minting fee
- Does not support Multicall
ipAsset.mintAndRegisterIpAndMakeDerivative
- Pay NFT and license minting fee
ipAsset.payRoyaltyOnBehalf
- Auto convert IP -> WIP when paying royalty in WIP.
Disabling Auto Wrap IP
To disable automatic conversion of IP to WIP, set enableAutoWrapIp
to false
client.ipAsset.registerDerivativeIp({
wipOptions: { enableAutoWrapIp: false },
})
Disable Multicall
By default, the SDK batches transactions into a single Multicall when possible to reduces the number of contract calls (e.g., WIP deposit → WIP approve → SPG contract call). To disable this behavior:
client.ipAsset.registerDerivativeIp({
wipOptions: { useMulticallWhenPossible: false },
})
Disable Auto Approve
When WIP is required for IP registration or minting license tokens, the SDK automatically approves the SPG contracts to use the WIP. By default, the approval is set to max allowance when the current allowance is insufficient. To disable this behavior:
client.ipAsset.registerDerivativeIp({
wipOptions: { enableAutoApprove: false },
})
Other Changes
- Replaced permanent permissions with transient permissions. This this a required change for POC v1.3.
- Renamed
childIpId
toipId
in the response data formintAndRegisterIpAndMakeDerivative
, aligning it with other register functions likeregisterIpAndMakeDerivative
.