@campnetwork/origin 1.2.8 → 1.3.0-alpha.1

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.
@@ -5,41 +5,113 @@ import { UseQueryResult } from '@tanstack/react-query';
5
5
  interface Environment {
6
6
  NAME: string;
7
7
  AUTH_HUB_BASE_API: string;
8
- AUTH_ENDPOINT: string;
9
8
  ORIGIN_DASHBOARD: string;
10
9
  DATANFT_CONTRACT_ADDRESS: string;
11
10
  MARKETPLACE_CONTRACT_ADDRESS: string;
12
11
  BATCH_PURCHASE_CONTRACT_ADDRESS: string;
12
+ DISPUTE_CONTRACT_ADDRESS?: string;
13
+ FRACTIONALIZER_CONTRACT_ADDRESS?: string;
14
+ APP_REGISTRY_CONTRACT_ADDRESS?: string;
15
+ USDC_CONTRACT_ADDRESS: string;
13
16
  CHAIN: any;
14
17
  IPNFT_ABI?: any;
15
18
  MARKETPLACE_ABI?: any;
16
19
  TBA_ABI?: any;
17
20
  BATCH_PURCHASE_ABI?: any;
21
+ DISPUTE_ABI?: any;
22
+ FRACTIONALIZER_ABI?: any;
23
+ APP_REGISTRY_ABI?: any;
18
24
  }
19
25
 
26
+ /**
27
+ * Enum representing the type of license for an IP NFT.
28
+ * - DURATION_BASED: License expires after a set duration (subscription model).
29
+ * - SINGLE_PAYMENT: One-time payment for perpetual access.
30
+ * - X402: HTTP 402-based micropayment license (no on-chain payments).
31
+ */
32
+ declare enum LicenseType {
33
+ DURATION_BASED = 0,
34
+ SINGLE_PAYMENT = 1,
35
+ X402 = 2
36
+ }
20
37
  /**
21
38
  * Represents the terms of a license for a digital asset.
22
39
  * @property price - The price of the asset in wei.
23
- * @property duration - The duration of the license in seconds.
40
+ * @property duration - The duration of the license in seconds (0 for SINGLE_PAYMENT and X402).
24
41
  * @property royaltyBps - The royalty percentage in basis points (0-10000).
25
42
  * @property paymentToken - The address of the payment token (ERC20 / address(0) for native currency).
43
+ * @property licenseType - The type of license (DURATION_BASED, SINGLE_PAYMENT, or X402).
26
44
  */
27
45
  type LicenseTerms = {
28
46
  price: bigint;
29
47
  duration: number;
30
48
  royaltyBps: number;
31
49
  paymentToken: Address;
50
+ licenseType: LicenseType;
32
51
  };
33
52
  /**
34
53
  * Enum representing the status of data in the system.
35
- * * - ACTIVE: The data is currently active and available.
36
- * * - PENDING_DELETE: The data is scheduled for deletion but not yet removed.
37
- * * - DELETED: The data has been deleted and is no longer available.
54
+ * - ACTIVE: The data is currently active and available.
55
+ * - DELETED: The data has been deleted and is no longer available.
56
+ * - DISPUTED: The data has been disputed and marked as potentially infringing.
38
57
  */
39
58
  declare enum DataStatus {
40
59
  ACTIVE = 0,
41
- PENDING_DELETE = 1,
42
- DELETED = 2
60
+ DELETED = 1,
61
+ DISPUTED = 2
62
+ }
63
+ /**
64
+ * Enum representing the status of a dispute.
65
+ * - Uninitialized: Dispute does not exist.
66
+ * - Raised: Dispute has been raised but not yet asserted by IP owner.
67
+ * - Asserted: IP owner has responded to the dispute.
68
+ * - Resolved: Dispute has been resolved (either valid or invalid).
69
+ * - Cancelled: Dispute was cancelled by the initiator.
70
+ */
71
+ declare enum DisputeStatus {
72
+ Uninitialized = 0,
73
+ Raised = 1,
74
+ Asserted = 2,
75
+ Resolved = 3,
76
+ Cancelled = 4
77
+ }
78
+ /**
79
+ * Represents a dispute against an IP NFT.
80
+ */
81
+ interface Dispute {
82
+ initiator: Address;
83
+ targetId: bigint;
84
+ disputeTag: Hex;
85
+ disputeEvidenceHash: Hex;
86
+ counterEvidenceHash: Hex;
87
+ disputeTimestamp: bigint;
88
+ assertionTimestamp: bigint;
89
+ yesVotes: bigint;
90
+ noVotes: bigint;
91
+ status: DisputeStatus;
92
+ bondAmount: bigint;
93
+ protocolFeeAmount: bigint;
94
+ }
95
+ /**
96
+ * Represents app information from the AppRegistry.
97
+ */
98
+ interface AppInfo {
99
+ treasury: Address;
100
+ revenueShareBps: number;
101
+ isActive: boolean;
102
+ }
103
+ /**
104
+ * Comprehensive token information returned by getTokenInfoSmart.
105
+ */
106
+ interface TokenInfo {
107
+ tokenId: bigint;
108
+ owner: Address;
109
+ uri: string;
110
+ status: DataStatus;
111
+ terms: LicenseTerms;
112
+ hasAccess: boolean;
113
+ accessExpiry: bigint | null;
114
+ appId: string;
43
115
  }
44
116
  /**
45
117
  * Represents the source of an IpNFT.
@@ -58,9 +130,10 @@ type IpNFTSource = "spotify" | "twitter" | "tiktok" | "file";
58
130
  * @param licenseTerms The terms of the license for the NFT.
59
131
  * @param deadline The deadline for the minting operation.
60
132
  * @param signature The signature for the minting operation.
133
+ * @param appId Optional app ID for the minting operation.
61
134
  * @returns A promise that resolves when the minting is complete.
62
135
  */
63
- declare function mintWithSignature(this: Origin, to: Address, tokenId: bigint, parents: bigint[], isIp: boolean, hash: Hex, uri: string, licenseTerms: LicenseTerms, deadline: bigint, signature: Hex): Promise<any>;
136
+ declare function mintWithSignature(this: Origin, to: Address, tokenId: bigint, parents: bigint[], isIp: boolean, hash: Hex, uri: string, licenseTerms: LicenseTerms, deadline: bigint, signature: Hex, appId?: string): Promise<any>;
64
137
  /**
65
138
  * Registers a Data NFT with the Origin service in order to obtain a signature for minting.
66
139
  * @param source The source of the Data NFT (e.g., "spotify", "twitter", "tiktok", or "file").
@@ -71,7 +144,7 @@ declare function mintWithSignature(this: Origin, to: Address, tokenId: bigint, p
71
144
  * @param parents The IDs of the parent NFTs, if applicable.
72
145
  * @return A promise that resolves with the registration data.
73
146
  */
74
- declare function registerIpNFT(this: Origin, source: IpNFTSource, deadline: bigint, licenseTerms: LicenseTerms, metadata: Record<string, unknown>, fileKey?: string | string[], parents?: bigint[]): Promise<any>;
147
+ declare function registerIpNFT(this: Origin, source: IpNFTSource, deadline: bigint, licenseTerms: LicenseTerms, metadata: Record<string, unknown>, isIp: boolean, fileKey?: string | string[], parents?: bigint[], appId?: string): Promise<any>;
75
148
 
76
149
  /**
77
150
  * Updates the license terms of a specified IPNFT.
@@ -154,10 +227,12 @@ declare function setApprovalForAll(this: Origin, operator: Address, approved: bo
154
227
  * @param expectedPrice The expected price for the access.
155
228
  * @param expectedDuration The expected duration of the access in seconds.
156
229
  * @param expectedPaymentToken The address of the payment token (use zero address for native token).
230
+ * @param expectedProtocolFeeBps The expected protocol fee in basis points (0-10000). Defaults to 0.
231
+ * @param expectedAppFeeBps The expected app fee in basis points (0-10000). Defaults to 0.
157
232
  * @param value The amount of native token to send (only required if paying with native token).
158
233
  * @returns A promise that resolves when the transaction is confirmed.
159
234
  */
160
- declare function buyAccess(this: Origin, buyer: Address, tokenId: bigint, expectedPrice: bigint, expectedDuration: bigint, expectedPaymentToken: Address, value?: bigint): Promise<any>;
235
+ declare function buyAccess(this: Origin, buyer: Address, tokenId: bigint, expectedPrice: bigint, expectedDuration: bigint, expectedPaymentToken: Address, expectedProtocolFeeBps?: number, expectedAppFeeBps?: number, value?: bigint): Promise<any>;
161
236
 
162
237
  /**
163
238
  * Checks if a user has access to a specific token based on subscription expiry.
@@ -217,6 +292,448 @@ declare function settlePaymentIntent(this: Origin, paymentIntentResponse: X402Re
217
292
  */
218
293
  declare function getDataWithIntent(this: Origin, tokenId: bigint, signer?: any, decide?: (terms: any) => Promise<boolean>): Promise<any>;
219
294
 
295
+ /**
296
+ * Raises a dispute against an IP NFT.
297
+ * Requires the caller to have the dispute bond amount in dispute tokens.
298
+ *
299
+ * @param targetIpId The token ID of the IP NFT to dispute.
300
+ * @param evidenceHash The hash of evidence supporting the dispute.
301
+ * @param disputeTag A tag identifying the type of dispute.
302
+ * @returns A promise that resolves with the transaction result including the dispute ID.
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const result = await origin.raiseDispute(
307
+ * 1n,
308
+ * "0x1234...", // evidence hash
309
+ * "0x5678..." // dispute tag (e.g., "infringement", "fraud")
310
+ * );
311
+ * ```
312
+ */
313
+ declare function raiseDispute(this: Origin, targetIpId: bigint, evidenceHash: Hex, disputeTag: Hex): Promise<any>;
314
+
315
+ interface RaiseDisputeSmartResult {
316
+ transactionResult: any;
317
+ evidenceCid: string;
318
+ evidenceHash: Hex;
319
+ }
320
+ /**
321
+ * Raises a dispute with automatic evidence upload to IPFS.
322
+ * Uploads evidence JSON to IPFS, hashes the CID to bytes32 for on-chain storage,
323
+ * and calls raiseDispute.
324
+ *
325
+ * @param targetIpId The token ID of the IP NFT to dispute.
326
+ * @param evidence The evidence JSON object to upload to IPFS.
327
+ * @param disputeTag A tag identifying the type of dispute.
328
+ * @returns A promise that resolves with the transaction result, IPFS CID, and evidence hash.
329
+ *
330
+ * @example
331
+ * ```typescript
332
+ * const result = await origin.raiseDisputeSmart(
333
+ * 1n,
334
+ * { reason: "copyright", details: "Unauthorized use of copyrighted material" },
335
+ * "0x696e6672696e67656d656e74..." // dispute tag
336
+ * );
337
+ *
338
+ * // Store the CID for evidence retrieval
339
+ * console.log("Evidence CID:", result.evidenceCid);
340
+ *
341
+ * // Fetch evidence later via IPFS gateway
342
+ * // https://ipfs.io/ipfs/{result.evidenceCid}
343
+ *
344
+ * // Verify evidence hash matches on-chain: keccak256(toHex(evidenceCid)) === evidenceHash
345
+ * ```
346
+ */
347
+ declare function raiseDisputeSmart(this: Origin, targetIpId: bigint, evidence: Record<string, any>, disputeTag: Hex): Promise<RaiseDisputeSmartResult>;
348
+
349
+ /**
350
+ * Asserts a dispute as the IP owner with counter-evidence.
351
+ * Must be called by the owner of the disputed IP within the cooldown period.
352
+ *
353
+ * @param disputeId The ID of the dispute to assert.
354
+ * @param counterEvidenceHash The hash of evidence countering the dispute.
355
+ * @returns A promise that resolves with the transaction result.
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * await origin.disputeAssertion(1n, "0x1234..."); // counter-evidence hash
360
+ * ```
361
+ */
362
+ declare function disputeAssertion(this: Origin, disputeId: bigint, counterEvidenceHash: Hex): Promise<any>;
363
+
364
+ /**
365
+ * Votes on a dispute as a CAMP token staker.
366
+ * Only users who staked before the dispute was raised can vote.
367
+ * Requires the caller to have voting power >= staking threshold.
368
+ *
369
+ * @param disputeId The ID of the dispute to vote on.
370
+ * @param support True to vote in favor of the dispute, false to vote against.
371
+ * @returns A promise that resolves with the transaction result.
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * // Vote in favor of the dispute
376
+ * await origin.voteOnDispute(1n, true);
377
+ *
378
+ * // Vote against the dispute
379
+ * await origin.voteOnDispute(1n, false);
380
+ * ```
381
+ */
382
+ declare function voteOnDispute(this: Origin, disputeId: bigint, support: boolean): Promise<any>;
383
+
384
+ /**
385
+ * Resolves a dispute after the voting period has ended.
386
+ * Can be called by anyone - resolution is deterministic based on votes and quorum.
387
+ * If the dispute is valid, the IP is marked as disputed and bond is returned.
388
+ * If invalid, the bond is split between the IP owner and resolver (protocol fee to caller).
389
+ *
390
+ * @param disputeId The ID of the dispute to resolve.
391
+ * @returns A promise that resolves with the transaction result.
392
+ *
393
+ * @example
394
+ * ```typescript
395
+ * await origin.resolveDispute(1n);
396
+ * ```
397
+ */
398
+ declare function resolveDispute(this: Origin, disputeId: bigint): Promise<any>;
399
+
400
+ /**
401
+ * Cancels a dispute that is still in the raised state.
402
+ * Can only be called by the dispute initiator during the cooldown period.
403
+ * The bond is returned to the initiator.
404
+ *
405
+ * @param disputeId The ID of the dispute to cancel.
406
+ * @returns A promise that resolves with the transaction result.
407
+ *
408
+ * @example
409
+ * ```typescript
410
+ * await origin.cancelDispute(1n);
411
+ * ```
412
+ */
413
+ declare function cancelDispute(this: Origin, disputeId: bigint): Promise<any>;
414
+
415
+ /**
416
+ * Tags a child IP as disputed if its parent has been successfully disputed.
417
+ * This propagates the dispute status to derivative IPs.
418
+ *
419
+ * @param childIpId The token ID of the child IP to tag.
420
+ * @param infringerDisputeId The ID of the resolved dispute against the parent IP.
421
+ * @returns A promise that resolves with the transaction result.
422
+ *
423
+ * @example
424
+ * ```typescript
425
+ * // After parent IP (tokenId 1) has been disputed, tag child IP (tokenId 2)
426
+ * await origin.tagChildIp(2n, 1n); // childIpId, disputeId of parent
427
+ * ```
428
+ */
429
+ declare function tagChildIp(this: Origin, childIpId: bigint, infringerDisputeId: bigint): Promise<any>;
430
+
431
+ /**
432
+ * Gets the details of a dispute by its ID.
433
+ *
434
+ * @param disputeId The ID of the dispute to fetch.
435
+ * @returns A promise that resolves with the dispute details.
436
+ *
437
+ * @example
438
+ * ```typescript
439
+ * const dispute = await origin.getDispute(1n);
440
+ * console.log(`Status: ${dispute.status}`);
441
+ * console.log(`Yes votes: ${dispute.yesVotes}`);
442
+ * console.log(`No votes: ${dispute.noVotes}`);
443
+ * ```
444
+ */
445
+ declare function getDispute(this: Origin, disputeId: bigint): Promise<Dispute>;
446
+
447
+ /**
448
+ * Result of checking if a user can vote on a dispute.
449
+ */
450
+ interface VoteEligibility {
451
+ canVote: boolean;
452
+ /** Reason why user cannot vote (if canVote is false) */
453
+ reason?: string;
454
+ /** User's voting weight (staked CAMP balance) */
455
+ votingWeight: bigint;
456
+ /** Minimum required stake to vote */
457
+ stakingThreshold: bigint;
458
+ hasAlreadyVoted: boolean;
459
+ /** Timestamp when user staked (0 if never staked) */
460
+ userStakeTimestamp: bigint;
461
+ disputeTimestamp: bigint;
462
+ disputeStatus: DisputeStatus;
463
+ isVotingPeriodActive: boolean;
464
+ }
465
+ /**
466
+ * Checks if a user meets the requirements to vote on a dispute.
467
+ * Returns detailed information about eligibility and reason if ineligible.
468
+ *
469
+ * @param disputeId The ID of the dispute to check.
470
+ * @param voter Optional address to check. If not provided, uses connected wallet.
471
+ * @returns A promise that resolves with the vote eligibility details.
472
+ *
473
+ * @example
474
+ * ```typescript
475
+ * const eligibility = await origin.canVoteOnDispute(1n);
476
+ *
477
+ * if (eligibility.canVote) {
478
+ * console.log(`You can vote with weight: ${eligibility.votingWeight}`);
479
+ * await origin.voteOnDispute(1n, true);
480
+ * } else {
481
+ * console.log(`Cannot vote: ${eligibility.reason}`);
482
+ * }
483
+ * ```
484
+ */
485
+ declare function canVoteOnDispute(this: Origin, disputeId: bigint, voter?: Address): Promise<VoteEligibility>;
486
+
487
+ /**
488
+ * Progress and voting statistics for a dispute.
489
+ */
490
+ interface DisputeProgress {
491
+ disputeId: bigint;
492
+ status: DisputeStatus;
493
+ /** Total YES votes (weighted by stake) */
494
+ yesVotes: bigint;
495
+ /** Total NO votes (weighted by stake) */
496
+ noVotes: bigint;
497
+ totalVotes: bigint;
498
+ /** YES votes as percentage (0-100) */
499
+ yesPercentage: number;
500
+ /** NO votes as percentage (0-100) */
501
+ noPercentage: number;
502
+ /** Required quorum for valid resolution */
503
+ quorum: bigint;
504
+ /** Current progress toward quorum (0-100+) */
505
+ quorumPercentage: number;
506
+ quorumMet: boolean;
507
+ /** Projected outcome if resolved now */
508
+ projectedOutcome: "dispute_succeeds" | "dispute_fails" | "no_quorum";
509
+ timeline: {
510
+ raisedAt: Date;
511
+ /** When the cooldown period ends (owner can no longer assert) */
512
+ cooldownEndsAt: Date;
513
+ votingEndsAt: Date;
514
+ canResolveNow: boolean;
515
+ /** Time remaining until resolution (in seconds, 0 if can resolve) */
516
+ timeUntilResolution: number;
517
+ };
518
+ }
519
+ /**
520
+ * Gets detailed progress and voting statistics for a dispute.
521
+ * Includes vote counts, percentages, quorum progress, and timeline.
522
+ *
523
+ * @param disputeId The ID of the dispute to check.
524
+ * @returns A promise that resolves with the dispute progress details.
525
+ *
526
+ * @example
527
+ * ```typescript
528
+ * const progress = await origin.getDisputeProgress(1n);
529
+ *
530
+ * console.log(`Yes: ${progress.yesPercentage}% | No: ${progress.noPercentage}%`);
531
+ * console.log(`Quorum: ${progress.quorumPercentage}% (${progress.quorumMet ? 'met' : 'not met'})`);
532
+ * console.log(`Projected outcome: ${progress.projectedOutcome}`);
533
+ *
534
+ * if (progress.timeline.canResolveNow) {
535
+ * await origin.resolveDispute(1n);
536
+ * } else {
537
+ * console.log(`Can resolve in ${progress.timeline.timeUntilResolution} seconds`);
538
+ * }
539
+ * ```
540
+ */
541
+ declare function getDisputeProgress(this: Origin, disputeId: bigint): Promise<DisputeProgress>;
542
+
543
+ /**
544
+ * Fractionalizes an IP NFT into fungible ERC20 tokens.
545
+ * The NFT is transferred to the fractionalizer contract and a new ERC20 token is created.
546
+ * The caller receives the full supply of fractional tokens.
547
+ *
548
+ * @param tokenId The token ID of the IP NFT to fractionalize.
549
+ * @returns A promise that resolves with the transaction result.
550
+ *
551
+ * @example
552
+ * ```typescript
553
+ * // First approve the fractionalizer contract to transfer your NFT
554
+ * await origin.approve(fractionalizerAddress, tokenId);
555
+ *
556
+ * // Then fractionalize
557
+ * const result = await origin.fractionalize(1n);
558
+ * ```
559
+ */
560
+ declare function fractionalize(this: Origin, tokenId: bigint): Promise<any>;
561
+
562
+ /**
563
+ * Redeems an IP NFT by burning all of its fractional tokens.
564
+ * The caller must hold the entire supply of the NFT's fractional token.
565
+ * After redemption, the NFT is transferred back to the caller.
566
+ *
567
+ * @param tokenId The token ID of the IP NFT to redeem.
568
+ * @returns A promise that resolves with the transaction result.
569
+ *
570
+ * @example
571
+ * ```typescript
572
+ * // Requires holding 100% of the fractional token supply
573
+ * await origin.redeem(1n);
574
+ * ```
575
+ */
576
+ declare function redeem(this: Origin, tokenId: bigint): Promise<any>;
577
+
578
+ /**
579
+ * Gets the fractional ERC20 token address for a specific IP NFT.
580
+ * Returns zero address if the NFT has not been fractionalized.
581
+ *
582
+ * @param tokenId The token ID of the IP NFT.
583
+ * @returns A promise that resolves with the fractional token address.
584
+ *
585
+ * @example
586
+ * ```typescript
587
+ * const fractionalToken = await origin.getTokenForNFT(1n);
588
+ * if (fractionalToken !== zeroAddress) {
589
+ * console.log(`Fractional token: ${fractionalToken}`);
590
+ * } else {
591
+ * console.log("NFT has not been fractionalized");
592
+ * }
593
+ * ```
594
+ */
595
+ declare function getTokenForNFT(this: Origin, tokenId: bigint): Promise<Address>;
596
+
597
+ /**
598
+ * Fractionalizes an IP NFT with automatic approval.
599
+ * This method first approves the fractionalizer contract to transfer your NFT,
600
+ * then calls fractionalize. This is the recommended method for most use cases.
601
+ *
602
+ * @param tokenId The token ID of the IP NFT to fractionalize.
603
+ * @returns A promise that resolves with the transaction result.
604
+ *
605
+ * @example
606
+ * ```typescript
607
+ * // Single call handles approval and fractionalization
608
+ * const result = await origin.fractionalizeWithApproval(1n);
609
+ * ```
610
+ */
611
+ declare function fractionalizeWithApproval(this: Origin, tokenId: bigint): Promise<any>;
612
+
613
+ /**
614
+ * Redeems fractional tokens for the underlying NFT, but only if the caller owns 100% of the supply.
615
+ * This method checks the caller's balance before attempting to redeem, providing a clear error
616
+ * if they don't hold the full supply.
617
+ *
618
+ * @param tokenId The token ID of the original NFT to redeem.
619
+ * @returns A promise that resolves with the transaction result.
620
+ * @throws Error if the caller doesn't own 100% of the fractional tokens.
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * try {
625
+ * const result = await origin.redeemIfComplete(1n);
626
+ * console.log("NFT redeemed successfully!");
627
+ * } catch (error) {
628
+ * console.log("You don't own all fractional tokens yet");
629
+ * }
630
+ * ```
631
+ */
632
+ declare function redeemIfComplete(this: Origin, tokenId: bigint): Promise<any>;
633
+
634
+ /**
635
+ * Ownership information for fractional tokens.
636
+ */
637
+ interface FractionOwnership {
638
+ tokenId: bigint;
639
+ /** The ERC20 token address (zero if not fractionalized) */
640
+ erc20Address: Address;
641
+ isFractionalized: boolean;
642
+ /** User's balance of fractional tokens */
643
+ balance: bigint;
644
+ /** Total supply of fractional tokens */
645
+ totalSupply: bigint;
646
+ /** User's ownership percentage (0-100) */
647
+ ownershipPercentage: number;
648
+ /** Whether user owns 100% and can redeem */
649
+ canRedeem: boolean;
650
+ decimals: number;
651
+ }
652
+ /**
653
+ * Gets a user's ownership percentage of a fractionalized NFT.
654
+ * Returns detailed information about the user's fractional token holdings.
655
+ *
656
+ * @param tokenId The token ID of the original NFT.
657
+ * @param owner Optional address to check. If not provided, uses connected wallet.
658
+ * @returns A promise that resolves with the ownership details.
659
+ *
660
+ * @example
661
+ * ```typescript
662
+ * const ownership = await origin.getFractionOwnership(1n);
663
+ *
664
+ * if (!ownership.isFractionalized) {
665
+ * console.log("This NFT has not been fractionalized");
666
+ * } else {
667
+ * console.log(`You own ${ownership.ownershipPercentage}% of this NFT`);
668
+ * console.log(`Balance: ${ownership.balance} / ${ownership.totalSupply}`);
669
+ *
670
+ * if (ownership.canRedeem) {
671
+ * console.log("You can redeem the original NFT!");
672
+ * await origin.redeem(1n);
673
+ * }
674
+ * }
675
+ * ```
676
+ */
677
+ declare function getFractionOwnership(this: Origin, tokenId: bigint, owner?: Address): Promise<FractionOwnership>;
678
+
679
+ /**
680
+ * Result of checking if a user can fractionalize an NFT.
681
+ */
682
+ interface FractionalizeEligibility {
683
+ canFractionalize: boolean;
684
+ /** Reason why user cannot fractionalize (if canFractionalize is false) */
685
+ reason?: string;
686
+ isOwner: boolean;
687
+ currentOwner: Address;
688
+ isAlreadyFractionalized: boolean;
689
+ /** ERC20 address if already fractionalized */
690
+ existingErc20Address?: Address;
691
+ dataStatus: DataStatus;
692
+ isApproved: boolean;
693
+ needsApproval: boolean;
694
+ }
695
+ /**
696
+ * Checks if a user can fractionalize an NFT and why not if they can't.
697
+ * Returns detailed information about eligibility requirements.
698
+ *
699
+ * @param tokenId The token ID of the NFT to check.
700
+ * @param owner Optional address to check. If not provided, uses connected wallet.
701
+ * @returns A promise that resolves with the fractionalize eligibility details.
702
+ *
703
+ * @example
704
+ * ```typescript
705
+ * const eligibility = await origin.canFractionalize(1n);
706
+ *
707
+ * if (eligibility.canFractionalize) {
708
+ * if (eligibility.needsApproval) {
709
+ * // Use fractionalizeWithApproval for convenience
710
+ * await origin.fractionalizeWithApproval(1n);
711
+ * } else {
712
+ * await origin.fractionalize(1n);
713
+ * }
714
+ * } else {
715
+ * console.log(`Cannot fractionalize: ${eligibility.reason}`);
716
+ * }
717
+ * ```
718
+ */
719
+ declare function canFractionalize(this: Origin, tokenId: bigint, owner?: Address): Promise<FractionalizeEligibility>;
720
+
721
+ /**
722
+ * Gets information about a registered app from the AppRegistry.
723
+ *
724
+ * @param appId The app ID to look up.
725
+ * @returns A promise that resolves with the app information.
726
+ *
727
+ * @example
728
+ * ```typescript
729
+ * const appInfo = await origin.getAppInfo("my-app-id");
730
+ * console.log(`Treasury: ${appInfo.treasury}`);
731
+ * console.log(`Revenue Share: ${appInfo.revenueShareBps / 100}%`);
732
+ * console.log(`Active: ${appInfo.isActive}`);
733
+ * ```
734
+ */
735
+ declare function getAppInfo(this: Origin, appId: string): Promise<AppInfo>;
736
+
220
737
  /**
221
738
  * Parameters for a single purchase in a bulk buy operation.
222
739
  */
@@ -225,6 +742,8 @@ interface BuyParams {
225
742
  expectedPrice: bigint;
226
743
  expectedDuration: number;
227
744
  expectedPaymentToken: Address;
745
+ expectedProtocolFeeBps: number;
746
+ expectedAppFeeBps: number;
228
747
  }
229
748
  /**
230
749
  * Preview of bulk purchase costs.
@@ -379,13 +898,39 @@ declare class Origin {
379
898
  previewBulkCost: typeof previewBulkCost;
380
899
  buildPurchaseParams: typeof buildPurchaseParams;
381
900
  checkActiveStatus: typeof checkActiveStatus;
901
+ raiseDispute: typeof raiseDispute;
902
+ raiseDisputeSmart: typeof raiseDisputeSmart;
903
+ disputeAssertion: typeof disputeAssertion;
904
+ voteOnDispute: typeof voteOnDispute;
905
+ resolveDispute: typeof resolveDispute;
906
+ cancelDispute: typeof cancelDispute;
907
+ tagChildIp: typeof tagChildIp;
908
+ getDispute: typeof getDispute;
909
+ canVoteOnDispute: typeof canVoteOnDispute;
910
+ getDisputeProgress: typeof getDisputeProgress;
911
+ fractionalize: typeof fractionalize;
912
+ redeem: typeof redeem;
913
+ getTokenForNFT: typeof getTokenForNFT;
914
+ fractionalizeWithApproval: typeof fractionalizeWithApproval;
915
+ redeemIfComplete: typeof redeemIfComplete;
916
+ getFractionOwnership: typeof getFractionOwnership;
917
+ canFractionalize: typeof canFractionalize;
918
+ getAppInfo: typeof getAppInfo;
382
919
  private jwt?;
383
920
  environment: Environment;
384
921
  private viemClient?;
385
922
  baseParentId?: bigint;
386
- constructor(environment?: Environment | string, jwt?: string, viemClient?: WalletClient, baseParentId?: bigint);
923
+ appId?: string;
924
+ constructor(environment?: Environment | string, jwt?: string, viemClient?: WalletClient, baseParentId?: bigint, appId?: string);
387
925
  getJwt(): string | undefined;
388
926
  setViemClient(client: WalletClient): void;
927
+ /**
928
+ * Uploads a JSON object to IPFS and returns the resulting CID.
929
+ * @param data The JSON object to upload.
930
+ * @returns The CID of the uploaded JSON.
931
+ * @throws {APIError} If the upload fails.
932
+ */
933
+ uploadJSONToIPFS(data: Record<string, any>): Promise<string>;
389
934
  /**
390
935
  * Mints a file-based IpNFT.
391
936
  * @param file The file to mint.
@@ -419,12 +964,42 @@ declare class Origin {
419
964
  * @throws {Error} - Throws an error if the wallet client is not connected and the method is not a view function.
420
965
  */
421
966
  callContractMethod(contractAddress: string, abi: Abi, methodName: string, params: any[], options?: CallOptions): Promise<any>;
967
+ /**
968
+ * Gets comprehensive token information in a single call.
969
+ * Combines owner, status, terms, URI, and access information.
970
+ *
971
+ * @param tokenId The token ID to get information for.
972
+ * @param owner Optional address to check access for. If not provided, uses connected wallet.
973
+ * @returns A promise that resolves with comprehensive token information.
974
+ *
975
+ * @example
976
+ * ```typescript
977
+ * const info = await origin.getTokenInfoSmart(1n);
978
+ * console.log(`Owner: ${info.owner}`);
979
+ * console.log(`Price: ${info.terms.price}`);
980
+ * console.log(`Has access: ${info.hasAccess}`);
981
+ * ```
982
+ */
983
+ getTokenInfoSmart(tokenId: bigint, owner?: Address): Promise<TokenInfo>;
422
984
  /**
423
985
  * Buy access to an asset by first checking its price via getTerms, then calling buyAccess.
424
- * @param {bigint} tokenId The token ID of the asset.
425
- * @returns {Promise<any>} The result of the buyAccess call.
986
+ * Automatically fetches protocol and app fees from the contracts.
987
+ * If the user already has access, returns null without making a transaction.
988
+ *
989
+ * @param tokenId The token ID of the asset.
990
+ * @returns The result of the buyAccess call, or null if user already has access.
991
+ *
992
+ * @example
993
+ * ```typescript
994
+ * const result = await origin.buyAccessSmart(1n);
995
+ * if (result === null) {
996
+ * console.log("You already have access to this asset");
997
+ * } else {
998
+ * console.log("Access purchased:", result.txHash);
999
+ * }
1000
+ * ```
426
1001
  */
427
- buyAccessSmart(tokenId: bigint): Promise<any>;
1002
+ buyAccessSmart(tokenId: bigint): Promise<any | null>;
428
1003
  /**
429
1004
  * Fetch the underlying data associated with a specific token ID.
430
1005
  * @param {bigint} tokenId - The token ID to fetch data for.
@@ -499,6 +1074,7 @@ declare class Auth {
499
1074
  #private;
500
1075
  redirectUri: Record<string, string>;
501
1076
  clientId: string;
1077
+ appId: string;
502
1078
  isAuthenticated: boolean;
503
1079
  jwt: string | null;
504
1080
  walletAddress: string | null;
@@ -516,8 +1092,9 @@ declare class Auth {
516
1092
  * @param {StorageAdapter} [options.storage] Custom storage adapter. Defaults to localStorage in browser, memory storage in Node.js.
517
1093
  * @throws {APIError} - Throws an error if the clientId is not provided.
518
1094
  */
519
- constructor({ clientId, redirectUri, environment, baseParentId, storage, }: {
1095
+ constructor({ clientId, appId, redirectUri, environment, baseParentId, storage, }: {
520
1096
  clientId: string;
1097
+ appId: string;
521
1098
  redirectUri: string | Record<string, string>;
522
1099
  environment?: "DEVELOPMENT" | "PRODUCTION";
523
1100
  baseParentId?: bigint;
@@ -725,8 +1302,9 @@ declare const CampContext: React.Context<CampContextType>;
725
1302
  * @param {string} props.environment The environment to use ("DEVELOPMENT" or "PRODUCTION")
726
1303
  * @returns {JSX.Element} The CampProvider component
727
1304
  */
728
- declare const CampProvider: ({ clientId, redirectUri, children, environment, baseParentId, }: {
1305
+ declare const CampProvider: ({ clientId, appId, redirectUri, children, environment, baseParentId, }: {
729
1306
  clientId: string;
1307
+ appId: string;
730
1308
  redirectUri?: string;
731
1309
  children: React.ReactNode;
732
1310
  environment?: "DEVELOPMENT" | "PRODUCTION";