How to Tip an IP
Learn how to tip an IP Asset using the SDK and Smart Contracts.
Using the SDK
See the Completed Code
To see a completed, working example of setting up a simple derivative chain and then tipping the child IP Asset, please see the commercial tutorial.
In this tutorial, you will learn how to send money ("tip") an IP Asset using the TypeScript SDK.
The Explanation
In this scenario, let's say there is a parent IP Asset that represents Mickey Mouse. Someone else draws a hat on that Mickey Mouse and registers it as a derivative (or "child") IP Asset. The License Terms specify that the child must share 50% of all commercial revenue (commercialRevShare = 50
) with the parent. Someone else (a 3rd party user) comes along and wants to send the derivative 2 SUSD for being really cool.
For the purposes of this example, we will assume the child is already registered as a derivative IP Asset. If you want help learning this, check out Register a Derivative.
- Parent IP ID:
0x42595dA29B541770D9F9f298a014bF912655E183
- Child IP ID:
0xeaa4Eed346373805B377F5a4fe1daeFeFB3D182a
0. Before you Start
There are a few steps you have to complete before you can start the tutorial.
- Add your Story Network Testnet wallet's private key to
.env
file:
WALLET_PRIVATE_KEY=<YOUR_WALLET_PRIVATE_KEY>
- Add your preferred RPC URL to your
.env
file. You can just use the public default one we provide:
RPC_PROVIDER_URL=https://odyssey.storyrpc.io
- Install the dependencies:
npm install @story-protocol/core-sdk viem
1. Set up your Story Config
- Associated docs: TypeScript SDK Setup
import { StoryClient, StoryConfig } from '@story-protocol/core-sdk'
import { http } from 'viem'
import { privateKeyToAccount, Address, Account } from 'viem/accounts'
const privateKey: Address = `0x${process.env.WALLET_PRIVATE_KEY}`
const account: Account = privateKeyToAccount(privateKey)
const config: StoryConfig = {
account: account,
transport: http(process.env.RPC_PROVIDER_URL),
chainId: 'odyssey',
}
const client = StoryClient.newClient(config)
2. Tipping the Derivative IP Asset
Now we will use the payRoyaltyOnBehalf
function to pay the derivative asset. In this case:
receiverIpId
is theipId
of the derivative assetpayerIpId
iszeroAddress
because the payer is a 3rd party (someone that thinks Mickey Mouse with a hat on him is cool), and not necessarily another IP Assettoken
is the address of SUSD, which is currently the only whitelisted revenue tokenamount
is 2, since the person tipping wants to send 2 SUSD
import { PayRoyaltyOnBehalfResponse } from '@story-protocol/core-sdk'
const response: PayRoyaltyOnBehalfResponse = await client.royalty.payRoyaltyOnBehalf({
receiverIpId: '0xeaa4Eed346373805B377F5a4fe1daeFeFB3D182a',
payerIpId: zeroAddress,
token: '0x91f6F05B08c16769d3c85867548615d270C42fC7',
amount: 2,
txOptions: { waitForTransaction: true },
})
console.log(`Paid royalty at transaction hash ${response.txHash}`)
3. Parent Claiming Due Revenue
At this point we have already finished the tutorial: we learned how to tip an IP Asset. But what if the parent wants to claim their due revenue? In this example, the parent should be able to claim 1 SUSD since the child earned 2 SUSD and the commercialRevShare = 50
in the license terms.
We will use the transferToVaultAndSnapshotAndClaimByTokenBatch
to claim the due revenue tokens.
ancestorIpId
is theipId
of the parent ("ancestor") assetclaimer
is the address that holds the royalty tokens associated with the parent's IP Royalty Vault. By default, they are in the IP Account, which is just theipId
of the parent assetchildIpId
is obviously theipId
of the child assetroyaltyPolicy
is the address of the royalty policy. As explained in 💸 Royalty Module, this is eitherRoyaltyPolicyLAP
orRoyaltyPolicyLRP
, depending on the license terms. In this case, let's assume the license terms specify aRoyaltyPolicyLAP
. Simply go to Deployed Smart Contracts and find the correct address.currencyToken
is the address of SUSD, which is currently the only whitelisted revenue tokenamount
is 1, since the parent should have 1 SUSD available to claim
import { TransferToVaultAndSnapshotAndClaimByTokenBatchResponse } from '@story-protocol/core-sdk'
const response: TransferToVaultAndSnapshotAndClaimByTokenBatchResponse = await client.royalty.transferToVaultAndSnapshotAndClaimByTokenBatch({
ancestorIpId: '0x42595dA29B541770D9F9f298a014bF912655E183',
claimer: '0x42595dA29B541770D9F9f298a014bF912655E183',
royaltyClaimDetails: [{
childIpId: '0xeaa4Eed346373805B377F5a4fe1daeFeFB3D182a',
royaltyPolicy: '0x793Df8d32c12B0bE9985FFF6afB8893d347B6686',
currencyToken: '0x91f6F05B08c16769d3c85867548615d270C42fC7',
amount: 1
}],
txOptions: { waitForTransaction: true },
})
console.log(`Claimed revenue: ${response.amountsClaimed} at snapshotId ${response.snapshotId}`)
4. Done!
See the Completed Code
To see a completed, working example of setting up a simple derivative chain and then tipping the child IP Asset, please see the commercial tutorial.
Using a Smart Contract
Not Completed
A full written tutorial is coming soon. For now, you can see a code example at the bottom of this file in our boilerplate.
Updated 4 days ago