@campnetwork/origin 1.2.8 → 1.3.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,7 @@ The Origin SDK currently exposes the following modules:
18
18
  - `Auth` - For authenticating users with the Origin SDK (browser and Node.js)
19
19
  - Signer adapters and utilities for Node.js support (ethers, viem, custom signers)
20
20
  - Camp Network chain configurations (`campMainnet`, `campTestnet`)
21
- - Origin utilities (`createLicenseTerms`, `LicenseTerms`, `DataStatus`)
21
+ - Origin utilities (`createLicenseTerms`, `LicenseTerms`, `LicenseType`, `DataStatus`, `DisputeStatus`, `Dispute`, `AppInfo`, `TokenInfo`)
22
22
  - `"@campnetwork/origin/react"` - Exposes the CampProvider and CampContext, as well as React components and hooks for authentication and fetching user data via Origin
23
23
 
24
24
  ## Features
@@ -29,6 +29,11 @@ The Origin SDK currently exposes the following modules:
29
29
  - **React Components** - Pre-built UI components and hooks
30
30
  - **TypeScript Support** - Full type definitions included
31
31
  - **Flexible Storage** - Custom storage adapters for session persistence
32
+ - **Multiple License Types** - Duration-based, single payment, and X402 micropayment licenses
33
+ - **Dispute Resolution** - Raise and resolve IP disputes with CAMP token voting
34
+ - **NFT Fractionalization** - Fractionalize IP NFTs into tradable ERC20 tokens
35
+ - **App Revenue Sharing** - Built-in app fee support via AppRegistry
36
+ - **Bulk Operations** - Purchase multiple IP NFTs in a single transaction
32
37
 
33
38
  # Installation
34
39
 
@@ -451,6 +456,9 @@ import {
451
456
  // Auth class
452
457
  Auth,
453
458
 
459
+ // Origin class
460
+ Origin,
461
+
454
462
  // Signer adapters
455
463
  ViemSignerAdapter,
456
464
  EthersSignerAdapter,
@@ -467,6 +475,27 @@ import {
467
475
  // Chain configs
468
476
  campMainnet,
469
477
  campTestnet,
478
+
479
+ // License utilities
480
+ createLicenseTerms,
481
+ LicenseTerms,
482
+ LicenseType,
483
+
484
+ // Status enums
485
+ DataStatus,
486
+ DisputeStatus,
487
+
488
+ // Types
489
+ Dispute,
490
+ AppInfo,
491
+ TokenInfo,
492
+ BuyParams,
493
+ TolerantResult,
494
+ BulkCostPreview,
495
+ VoteEligibility,
496
+ DisputeProgress,
497
+ FractionOwnership,
498
+ FractionalizeEligibility,
470
499
  } from "@campnetwork/origin";
471
500
  ```
472
501
 
@@ -922,6 +951,18 @@ The `Origin` class provides blockchain and API methods for interacting with Orig
922
951
 
923
952
  ### Types
924
953
 
954
+ #### `LicenseType`
955
+
956
+ Enum representing the type of license for an IP NFT:
957
+
958
+ ```typescript
959
+ enum LicenseType {
960
+ DURATION_BASED = 0, // License expires after a set duration (subscription model)
961
+ SINGLE_PAYMENT = 1, // One-time payment for perpetual access
962
+ X402 = 2, // HTTP 402-based micropayment license
963
+ }
964
+ ```
965
+
925
966
  #### `LicenseTerms`
926
967
 
927
968
  The license terms object used in minting and updating methods:
@@ -929,48 +970,136 @@ The license terms object used in minting and updating methods:
929
970
  ```typescript
930
971
  type LicenseTerms = {
931
972
  price: bigint; // Price in wei
932
- duration: number; // Duration in seconds
973
+ duration: number; // Duration in seconds (0 for SINGLE_PAYMENT and X402)
933
974
  royaltyBps: number; // Royalty in basis points (1-10000)
934
975
  paymentToken: Address; // Payment token address (address(0) for native currency)
976
+ licenseType: LicenseType; // Type of license
935
977
  };
936
978
  ```
937
979
 
980
+ #### `DataStatus`
981
+
982
+ Enum representing the status of data in the system:
983
+
984
+ ```typescript
985
+ enum DataStatus {
986
+ ACTIVE = 0, // Data is currently active and available
987
+ DELETED = 1, // Data has been deleted
988
+ DISPUTED = 2, // Data has been disputed and marked as potentially infringing
989
+ }
990
+ ```
991
+
992
+ #### `DisputeStatus`
993
+
994
+ Enum representing the status of a dispute:
995
+
996
+ ```typescript
997
+ enum DisputeStatus {
998
+ Uninitialized = 0, // Dispute does not exist
999
+ Raised = 1, // Dispute has been raised
1000
+ Asserted = 2, // IP owner has responded
1001
+ Resolved = 3, // Dispute has been resolved
1002
+ Cancelled = 4, // Dispute was cancelled
1003
+ }
1004
+ ```
1005
+
1006
+ #### `Dispute`
1007
+
1008
+ Interface representing a dispute against an IP NFT:
1009
+
1010
+ ```typescript
1011
+ interface Dispute {
1012
+ initiator: Address;
1013
+ targetId: bigint;
1014
+ disputeTag: Hex;
1015
+ disputeEvidenceHash: Hex;
1016
+ counterEvidenceHash: Hex;
1017
+ disputeTimestamp: bigint;
1018
+ assertionTimestamp: bigint;
1019
+ yesVotes: bigint;
1020
+ noVotes: bigint;
1021
+ status: DisputeStatus;
1022
+ bondAmount: bigint;
1023
+ protocolFeeAmount: bigint;
1024
+ }
1025
+ ```
1026
+
1027
+ #### `AppInfo`
1028
+
1029
+ Interface representing app information from the AppRegistry:
1030
+
1031
+ ```typescript
1032
+ interface AppInfo {
1033
+ treasury: Address;
1034
+ revenueShareBps: number;
1035
+ isActive: boolean;
1036
+ }
1037
+ ```
1038
+
1039
+ #### `TokenInfo`
1040
+
1041
+ Comprehensive token information returned by `getTokenInfoSmart`:
1042
+
1043
+ ```typescript
1044
+ interface TokenInfo {
1045
+ tokenId: bigint;
1046
+ owner: Address;
1047
+ uri: string;
1048
+ status: DataStatus;
1049
+ terms: LicenseTerms;
1050
+ hasAccess: boolean;
1051
+ accessExpiry: bigint | null;
1052
+ appId: string;
1053
+ }
1054
+ ```
1055
+
938
1056
  ### Minting Constraints
939
1057
 
940
1058
  When minting or updating an IpNFT, the following constraints apply to the `LicenseTerms`:
941
1059
 
942
1060
  - The price must be at least `1000000000000000` wei (0.001 $CAMP).
943
1061
  - The royaltyBps must be between `1` and `10000` (0.01% to 100%).
944
- - The duration must be between `86400` seconds and `2628000` seconds (1 day to 30 days).
1062
+ - For `DURATION_BASED` licenses, the duration must be between `86400` seconds and `2628000` seconds (1 day to 30 days).
1063
+ - For `SINGLE_PAYMENT` and `X402` licenses, duration must be `0`.
945
1064
 
946
- ### `createLicenseTerms(price, duration, royaltyBps, paymentToken)`
1065
+ ### `createLicenseTerms(price, duration, royaltyBps, paymentToken, licenseType?)`
947
1066
 
948
1067
  A utility function to create properly validated license terms for minting and updating IpNFTs.
949
1068
 
950
1069
  - `price`: Price in wei (bigint)
951
- - `duration`: Duration in seconds (number)
1070
+ - `duration`: Duration in seconds (number) - use 0 for SINGLE_PAYMENT and X402
952
1071
  - `royaltyBps`: Royalty in basis points (number)
953
1072
  - `paymentToken`: Payment token address (Address) - use `zeroAddress` from viem for native currency
1073
+ - `licenseType`: Type of license (LicenseType) - defaults to `DURATION_BASED`
954
1074
  - **Returns:** A validated `LicenseTerms` object
955
1075
  - **Throws:** Error if any parameter violates the constraints
956
1076
 
957
1077
  **Example:**
958
1078
 
959
1079
  ```typescript
960
- import { createLicenseTerms } from "@campnetwork/origin";
1080
+ import { createLicenseTerms, LicenseType } from "@campnetwork/origin";
961
1081
  import { zeroAddress } from "viem";
962
1082
 
963
- // Create license terms with validation
964
- const license = createLicenseTerms(
1083
+ // Create duration-based license (subscription)
1084
+ const subscriptionLicense = createLicenseTerms(
965
1085
  BigInt("1000000000000000"), // 0.001 CAMP in wei
966
1086
  86400, // 1 day in seconds
967
1087
  1000, // 10% royalty (1000 basis points)
968
1088
  zeroAddress // Native currency (CAMP)
969
1089
  );
970
1090
 
1091
+ // Create single payment license (perpetual access)
1092
+ const perpetualLicense = createLicenseTerms(
1093
+ BigInt("10000000000000000"), // 0.01 CAMP
1094
+ 0, // Duration must be 0 for single payment
1095
+ 500, // 5% royalty
1096
+ zeroAddress,
1097
+ LicenseType.SINGLE_PAYMENT
1098
+ );
1099
+
971
1100
  // Use with minting functions
972
- await auth.origin.mintFile(file, metadata, license);
973
- await auth.origin.mintSocial("twitter", metadata, license);
1101
+ await auth.origin.mintFile(file, metadata, subscriptionLicense);
1102
+ await auth.origin.mintSocial("twitter", metadata, perpetualLicense);
974
1103
  ```
975
1104
 
976
1105
  ### File Upload & Minting
@@ -1007,37 +1136,277 @@ Most methods mirror smart contract functions and require appropriate permissions
1007
1136
 
1008
1137
  #### Core IpNFT Methods
1009
1138
 
1010
- - `mintWithSignature(account, tokenId, parents, creatorContentHash, uri, license, deadline, signature)`
1011
- - `registerIpNFT(source, deadline, license, metadata, fileKey?, parents?)`
1012
- - `updateTerms(tokenId, license)`
1013
- - `finalizeDelete(tokenId)`
1014
- - `getOrCreateRoyaltyVault(tokenId)`
1015
- - `getTerms(tokenId)`
1016
- - `ownerOf(tokenId)`
1017
- - `balanceOf(owner)`
1018
- - `tokenURI(tokenId)`
1019
- - `dataStatus(tokenId)`
1020
- - `isApprovedForAll(owner, operator)`
1021
- - `transferFrom(from, to, tokenId)`
1022
- - `safeTransferFrom(from, to, tokenId)`
1023
- - `approve(to, tokenId)`
1024
- - `setApprovalForAll(operator, approved)`
1139
+ - `mintWithSignature(to, tokenId, parents, isIp, hash, uri, license, deadline, signature, appId?)` — Mint with a backend signature. `appId` defaults to SDK's clientId.
1140
+ - `registerIpNFT(source, deadline, license, metadata, fileKey?, parents?)` — Register IP with backend
1141
+ - `updateTerms(tokenId, license)` — Update license terms
1142
+ - `finalizeDelete(tokenId)` — Finalize deletion of an IP NFT
1143
+ - `getOrCreateRoyaltyVault(tokenId)` — Get or create Token Bound Account for royalties
1144
+ - `getTerms(tokenId)` — Get license terms for a token
1145
+ - `ownerOf(tokenId)` — Get owner address
1146
+ - `balanceOf(owner)` — Get token count for an owner
1147
+ - `tokenURI(tokenId)` — Get metadata URI
1148
+ - `dataStatus(tokenId)` — Get data status (ACTIVE, DELETED, or DISPUTED)
1149
+ - `isApprovedForAll(owner, operator)` — Check operator approval
1150
+ - `transferFrom(from, to, tokenId)` — Transfer token
1151
+ - `safeTransferFrom(from, to, tokenId)` — Safe transfer token
1152
+ - `approve(to, tokenId)` — Approve address for token
1153
+ - `setApprovalForAll(operator, approved)` — Set operator approval
1025
1154
 
1026
1155
  #### Marketplace Methods
1027
1156
 
1028
- - `buyAccess(buyer, tokenId, expectedPrice, expectedDuration, expectedPaymentToken, value?)`
1029
- - `hasAccess(tokenId, user)`
1030
- - `subscriptionExpiry(tokenId, user)`
1157
+ - `buyAccess(buyer, tokenId, expectedPrice, expectedDuration, expectedPaymentToken, expectedProtocolFeeBps?, expectedAppFeeBps?, value?)` — Purchase access to an IP NFT
1158
+ - `hasAccess(address, tokenId)` — Check if address has access
1159
+ - `subscriptionExpiry(tokenId, address)` — Get subscription expiry timestamp
1160
+
1161
+ #### Smart Helper Methods (Recommended)
1031
1162
 
1032
- #### Utility & Royalty Methods
1163
+ These methods handle complexity automatically and are recommended for most use cases:
1164
+
1165
+ - `getTokenInfoSmart(tokenId, owner?)` — Get comprehensive token info in a single call (owner, terms, status, access info, etc.)
1166
+ - `buyAccessSmart(tokenId)` — Buys access with automatic fee fetching. Returns `null` if user already has access.
1167
+ - `settlePaymentIntent(x402Response, signer?)` — Settle an X402 payment intent response
1168
+
1169
+ **Example:**
1170
+
1171
+ ```typescript
1172
+ // Get all token info at once
1173
+ const info = await auth.origin.getTokenInfoSmart(1n);
1174
+ console.log(`Owner: ${info.owner}`);
1175
+ console.log(`Price: ${info.terms.price}`);
1176
+ console.log(`Has access: ${info.hasAccess}`);
1177
+ console.log(`License type: ${info.terms.licenseType}`);
1178
+
1179
+ // Smart purchase - checks access first, fetches fees automatically
1180
+ const result = await auth.origin.buyAccessSmart(1n);
1181
+ if (result === null) {
1182
+ console.log("Already have access!");
1183
+ } else {
1184
+ console.log("Purchased:", result.txHash);
1185
+ }
1186
+ ```
1187
+
1188
+ #### Bulk Purchase Methods
1189
+
1190
+ For purchasing multiple IP NFTs in a single transaction:
1191
+
1192
+ - `bulkBuyAccess(buyer, purchases, value?)` — Atomic bulk purchase (all succeed or all fail)
1193
+ - `bulkBuyAccessTolerant(buyer, purchases, value?)` — Tolerant bulk purchase (partial success allowed)
1194
+ - `bulkBuyAccessSmart(tokenIds, options?)` — Smart bulk purchase with automatic parameter building
1195
+ - `previewBulkCost(tokenIds)` — Preview total cost for multiple tokens
1196
+ - `buildPurchaseParams(tokenIds)` — Build purchase parameters from token IDs
1197
+ - `checkActiveStatus(tokenIds)` — Check active status of multiple tokens
1198
+
1199
+ **Example:**
1200
+
1201
+ ```typescript
1202
+ // Smart bulk purchase - handles everything automatically
1203
+ const result = await auth.origin.bulkBuyAccessSmart([1n, 2n, 3n], {
1204
+ tolerant: true, // Continue even if some fail
1205
+ });
1206
+
1207
+ // Preview costs before purchasing
1208
+ const preview = await auth.origin.previewBulkCost([1n, 2n, 3n]);
1209
+ console.log(`Total cost: ${preview.totalNativeCost} wei`);
1210
+ ```
1033
1211
 
1034
- - `getRoyalties(token?, owner?)` — Get royalty vault and balance
1035
- - `claimRoyalties(token?, owner?)` — Claim royalties
1212
+ #### Dispute Module Methods
1213
+
1214
+ Methods for the IP dispute resolution system:
1215
+
1216
+ - `raiseDispute(targetIpId, evidenceHash, disputeTag)` — Raise a dispute against an IP NFT
1217
+ - `disputeAssertion(disputeId, counterEvidenceHash)` — IP owner responds to dispute
1218
+ - `voteOnDispute(disputeId, support)` — CAMP stakers vote on dispute
1219
+ - `resolveDispute(disputeId)` — Finalize dispute after voting period
1220
+ - `cancelDispute(disputeId)` — Cancel a dispute (initiator only)
1221
+ - `tagChildIp(childIpId, infringerDisputeId)` — Tag derivative IPs of disputed content
1222
+ - `getDispute(disputeId)` — Get dispute details
1223
+ - `canVoteOnDispute(disputeId, voter?)` — Check if user can vote and why (recommended before voting)
1224
+ - `getDisputeProgress(disputeId)` — Get voting stats, quorum progress, timeline, and projected outcome
1225
+
1226
+ **VoteEligibility Interface:**
1227
+
1228
+ ```typescript
1229
+ interface VoteEligibility {
1230
+ canVote: boolean; // Whether the user can vote
1231
+ reason?: string; // Why they can't vote (if canVote is false)
1232
+ votingWeight: bigint; // User's staked CAMP balance
1233
+ stakingThreshold: bigint; // Minimum required stake
1234
+ hasAlreadyVoted: boolean; // Whether user already voted
1235
+ userStakeTimestamp: bigint; // When user staked (0 if never)
1236
+ disputeTimestamp: bigint; // When dispute was raised
1237
+ disputeStatus: DisputeStatus; // Current status
1238
+ isVotingPeriodActive: boolean; // Whether voting is open
1239
+ }
1240
+ ```
1241
+
1242
+ **DisputeProgress Interface:**
1243
+
1244
+ ```typescript
1245
+ interface DisputeProgress {
1246
+ disputeId: bigint;
1247
+ status: DisputeStatus;
1248
+ yesVotes: bigint; // Total YES votes (weighted)
1249
+ noVotes: bigint; // Total NO votes (weighted)
1250
+ totalVotes: bigint;
1251
+ yesPercentage: number; // 0-100
1252
+ noPercentage: number; // 0-100
1253
+ quorum: bigint; // Required for valid resolution
1254
+ quorumPercentage: number; // Progress toward quorum
1255
+ quorumMet: boolean;
1256
+ projectedOutcome: "dispute_succeeds" | "dispute_fails" | "no_quorum";
1257
+ timeline: {
1258
+ raisedAt: Date;
1259
+ cooldownEndsAt: Date; // Owner can assert until this time
1260
+ votingEndsAt: Date;
1261
+ canResolveNow: boolean;
1262
+ timeUntilResolution: number; // Seconds remaining
1263
+ };
1264
+ }
1265
+ ```
1266
+
1267
+ **Example:**
1268
+
1269
+ ```typescript
1270
+ import { keccak256, toBytes } from "viem";
1271
+
1272
+ // Raise a dispute
1273
+ const evidenceHash = keccak256(toBytes("ipfs://QmEvidence..."));
1274
+ const disputeTag = keccak256(toBytes("copyright_infringement"));
1275
+
1276
+ const result = await auth.origin.raiseDispute(
1277
+ 1n, // Token ID to dispute
1278
+ evidenceHash,
1279
+ disputeTag
1280
+ );
1281
+
1282
+ // Check if you can vote before voting
1283
+ const eligibility = await auth.origin.canVoteOnDispute(disputeId);
1284
+
1285
+ if (eligibility.canVote) {
1286
+ console.log(`Voting with weight: ${eligibility.votingWeight}`);
1287
+ await auth.origin.voteOnDispute(disputeId, true); // Vote YES
1288
+ } else {
1289
+ console.log(`Cannot vote: ${eligibility.reason}`);
1290
+ // Possible reasons:
1291
+ // - "Dispute is not in a voteable status"
1292
+ // - "Voting period has ended"
1293
+ // - "You have already voted on this dispute"
1294
+ // - "You have never staked CAMP tokens"
1295
+ // - "You staked after this dispute was raised"
1296
+ // - "Insufficient stake: you have X but need at least Y"
1297
+ }
1298
+
1299
+ // Get detailed dispute progress
1300
+ const progress = await auth.origin.getDisputeProgress(disputeId);
1301
+ console.log(`Yes: ${progress.yesPercentage}% | No: ${progress.noPercentage}%`);
1302
+ console.log(`Quorum: ${progress.quorumPercentage}% (${progress.quorumMet ? "met" : "not met"})`);
1303
+ console.log(`Projected outcome: ${progress.projectedOutcome}`);
1304
+
1305
+ if (progress.timeline.canResolveNow) {
1306
+ await auth.origin.resolveDispute(disputeId);
1307
+ } else {
1308
+ console.log(`Can resolve in ${progress.timeline.timeUntilResolution} seconds`);
1309
+ }
1310
+ ```
1311
+
1312
+ #### Fractionalizer Module Methods
1313
+
1314
+ Methods for fractionalizing IP NFTs into ERC20 tokens:
1315
+
1316
+ - `fractionalize(tokenId)` — Fractionalize an NFT into ERC20 tokens
1317
+ - `fractionalizeWithApproval(tokenId)` — Fractionalize with automatic approval (recommended)
1318
+ - `redeem(tokenId)` — Redeem fractional tokens for the underlying NFT
1319
+ - `redeemIfComplete(tokenId)` — Redeem only if holding 100% of tokens (recommended)
1320
+ - `getTokenForNFT(tokenId)` — Get the ERC20 token address for a fractionalized NFT
1321
+ - `getFractionOwnership(tokenId, owner?)` — Get user's ownership percentage of fractional tokens
1322
+ - `canFractionalize(tokenId, owner?)` — Check if user can fractionalize an NFT
1323
+
1324
+ **FractionOwnership Interface:**
1325
+
1326
+ ```typescript
1327
+ interface FractionOwnership {
1328
+ tokenId: bigint;
1329
+ erc20Address: Address; // Zero if not fractionalized
1330
+ isFractionalized: boolean;
1331
+ balance: bigint; // User's fractional token balance
1332
+ totalSupply: bigint; // Total supply of fractional tokens
1333
+ ownershipPercentage: number; // 0-100
1334
+ canRedeem: boolean; // True if owns 100%
1335
+ decimals: number;
1336
+ }
1337
+ ```
1338
+
1339
+ **FractionalizeEligibility Interface:**
1340
+
1341
+ ```typescript
1342
+ interface FractionalizeEligibility {
1343
+ canFractionalize: boolean;
1344
+ reason?: string; // Why not (if false)
1345
+ isOwner: boolean;
1346
+ currentOwner: Address;
1347
+ isAlreadyFractionalized: boolean;
1348
+ existingErc20Address?: Address;
1349
+ dataStatus: DataStatus;
1350
+ isApproved: boolean; // Fractionalizer approved to transfer
1351
+ needsApproval: boolean;
1352
+ }
1353
+ ```
1354
+
1355
+ **Example:**
1356
+
1357
+ ```typescript
1358
+ // Check if you can fractionalize
1359
+ const eligibility = await auth.origin.canFractionalize(1n);
1360
+
1361
+ if (eligibility.canFractionalize) {
1362
+ // Fractionalize with automatic approval
1363
+ await auth.origin.fractionalizeWithApproval(1n);
1364
+ } else {
1365
+ console.log(`Cannot fractionalize: ${eligibility.reason}`);
1366
+ // Possible reasons:
1367
+ // - "You don't own this NFT"
1368
+ // - "This NFT is already fractionalized"
1369
+ // - "This NFT has been deleted"
1370
+ // - "This NFT is disputed"
1371
+ }
1372
+
1373
+ // Check your ownership of fractional tokens
1374
+ const ownership = await auth.origin.getFractionOwnership(1n);
1375
+
1376
+ if (!ownership.isFractionalized) {
1377
+ console.log("This NFT has not been fractionalized");
1378
+ } else {
1379
+ console.log(`You own ${ownership.ownershipPercentage}% of this NFT`);
1380
+ console.log(`Balance: ${ownership.balance} / ${ownership.totalSupply}`);
1381
+
1382
+ if (ownership.canRedeem) {
1383
+ console.log("You can redeem the original NFT!");
1384
+ await auth.origin.redeemIfComplete(1n);
1385
+ }
1386
+ }
1387
+ ```
1388
+
1389
+ #### AppRegistry Module Methods
1390
+
1391
+ Methods for querying app information:
1392
+
1393
+ - `getAppInfo(appId)` — Get app information from the registry
1394
+
1395
+ **Example:**
1396
+
1397
+ ```typescript
1398
+ const appInfo = await auth.origin.getAppInfo("my-app-id");
1399
+ console.log(`Treasury: ${appInfo.treasury}`);
1400
+ console.log(`Revenue Share: ${appInfo.revenueShareBps / 100}%`);
1401
+ console.log(`Active: ${appInfo.isActive}`);
1402
+ ```
1036
1403
 
1037
- #### Smart Access & Data
1404
+ #### Royalty & Data Methods
1038
1405
 
1039
- - `buyAccessSmart(tokenId)` — Buys access, handles payment approval and license details - **Recommended in place of buyAccess**
1040
- - `getData(tokenId)` — Fetches the underlying IP for a given IPNFT if the user has purchased access to it
1406
+ - `getTokenBoundAccount(tokenId)` — Get the Token Bound Account address for a token
1407
+ - `getRoyalties(tokenId, token?)` — Get royalty balance for a token
1408
+ - `claimRoyalties(tokenId, recipient?, token?)` — Claim royalties from a token's TBA
1409
+ - `getData(tokenId)` — Fetch the underlying IP data (requires access)
1041
1410
 
1042
1411
  ### Utility Methods
1043
1412