@campnetwork/origin 1.3.0-alpha.3 → 1.3.0-alpha.6

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.
@@ -294,11 +294,12 @@ declare function getDataWithIntent(this: Origin, tokenId: bigint, signer?: any,
294
294
 
295
295
  /**
296
296
  * Raises a dispute against an IP NFT.
297
- * Requires the caller to have the dispute bond amount in dispute tokens.
297
+ * Automatically handles token approval for ERC20 bonds or native token value.
298
+ * Includes the protocol dispute fee in the transaction.
298
299
  *
299
300
  * @param targetIpId The token ID of the IP NFT to dispute.
300
301
  * @param evidenceHash The hash of evidence supporting the dispute.
301
- * @param disputeTag A tag identifying the type of dispute.
302
+ * @param disputeTag A tag identifying the type of dispute (bytes32).
302
303
  * @returns A promise that resolves with the transaction result including the dispute ID.
303
304
  *
304
305
  * @example
@@ -306,7 +307,7 @@ declare function getDataWithIntent(this: Origin, tokenId: bigint, signer?: any,
306
307
  * const result = await origin.raiseDispute(
307
308
  * 1n,
308
309
  * "0x1234...", // evidence hash
309
- * "0x5678..." // dispute tag (e.g., "infringement", "fraud")
310
+ * "0x0100000000000000000000000000000000000000000000000000000000000000" // dispute tag (bytes32)
310
311
  * );
311
312
  * ```
312
313
  */
@@ -540,6 +541,31 @@ interface DisputeProgress {
540
541
  */
541
542
  declare function getDisputeProgress(this: Origin, disputeId: bigint): Promise<DisputeProgress>;
542
543
 
544
+ interface DisputeRequirements {
545
+ bondAmount: bigint;
546
+ protocolFee: bigint;
547
+ totalRequired: bigint;
548
+ tokenAddress: Address;
549
+ isNativeToken: boolean;
550
+ userBalance: bigint;
551
+ hasSufficientBalance: boolean;
552
+ }
553
+ /**
554
+ * Gets the requirements for raising a dispute, including balance check.
555
+ *
556
+ * @param userAddress The address to check balance for.
557
+ * @returns A promise that resolves with the dispute requirements.
558
+ *
559
+ * @example
560
+ * ```typescript
561
+ * const requirements = await origin.getDisputeRequirements(walletAddress);
562
+ * if (!requirements.hasSufficientBalance) {
563
+ * console.log(`Need ${requirements.totalRequired} but only have ${requirements.userBalance}`);
564
+ * }
565
+ * ```
566
+ */
567
+ declare function getDisputeRequirements(this: Origin, userAddress: Address): Promise<DisputeRequirements>;
568
+
543
569
  /**
544
570
  * Fractionalizes an IP NFT into fungible ERC20 tokens.
545
571
  * The NFT is transferred to the fractionalizer contract and a new ERC20 token is created.
@@ -908,6 +934,7 @@ declare class Origin {
908
934
  getDispute: typeof getDispute;
909
935
  canVoteOnDispute: typeof canVoteOnDispute;
910
936
  getDisputeProgress: typeof getDisputeProgress;
937
+ getDisputeRequirements: typeof getDisputeRequirements;
911
938
  fractionalize: typeof fractionalize;
912
939
  redeem: typeof redeem;
913
940
  getTokenForNFT: typeof getTokenForNFT;
@@ -924,6 +951,14 @@ declare class Origin {
924
951
  constructor(environment?: Environment | string, jwt?: string, viemClient?: WalletClient, baseParentId?: bigint, appId?: string);
925
952
  getJwt(): string | undefined;
926
953
  setViemClient(client: WalletClient): void;
954
+ /**
955
+ * Approves an ERC20 token for spending by a spender address if the current allowance is insufficient.
956
+ * Waits for the approval transaction to be confirmed before returning.
957
+ * @param tokenAddress The address of the ERC20 token.
958
+ * @param spender The address that will be approved to spend the tokens.
959
+ * @param amount The amount of tokens to approve.
960
+ */
961
+ approveERC20IfNeeded(tokenAddress: Address, spender: Address, amount: bigint): Promise<void>;
927
962
  /**
928
963
  * Uploads a JSON object to IPFS and returns the resulting CID.
929
964
  * @param data The JSON object to upload.
@@ -6789,11 +6789,12 @@ function getCurrentAccount() {
6789
6789
 
6790
6790
  /**
6791
6791
  * Raises a dispute against an IP NFT.
6792
- * Requires the caller to have the dispute bond amount in dispute tokens.
6792
+ * Automatically handles token approval for ERC20 bonds or native token value.
6793
+ * Includes the protocol dispute fee in the transaction.
6793
6794
  *
6794
6795
  * @param targetIpId The token ID of the IP NFT to dispute.
6795
6796
  * @param evidenceHash The hash of evidence supporting the dispute.
6796
- * @param disputeTag A tag identifying the type of dispute.
6797
+ * @param disputeTag A tag identifying the type of dispute (bytes32).
6797
6798
  * @returns A promise that resolves with the transaction result including the dispute ID.
6798
6799
  *
6799
6800
  * @example
@@ -6801,13 +6802,46 @@ function getCurrentAccount() {
6801
6802
  * const result = await origin.raiseDispute(
6802
6803
  * 1n,
6803
6804
  * "0x1234...", // evidence hash
6804
- * "0x5678..." // dispute tag (e.g., "infringement", "fraud")
6805
+ * "0x0100000000000000000000000000000000000000000000000000000000000000" // dispute tag (bytes32)
6805
6806
  * );
6806
6807
  * ```
6807
6808
  */
6808
6809
  function raiseDispute(targetIpId, evidenceHash, disputeTag) {
6809
6810
  return __awaiter(this, void 0, void 0, function* () {
6810
- return this.callContractMethod(this.environment.DISPUTE_CONTRACT_ADDRESS, this.environment.DISPUTE_ABI, "raiseDispute", [targetIpId, evidenceHash, disputeTag], { waitForReceipt: true });
6811
+ const publicClient = getPublicClient();
6812
+ const disputeContractAddress = this.environment
6813
+ .DISPUTE_CONTRACT_ADDRESS;
6814
+ const disputeAbi = this.environment.DISPUTE_ABI;
6815
+ // Get dispute bond amount, protocol fee, and token address from the contract
6816
+ const [disputeBond, protocolFee, disputeToken] = yield Promise.all([
6817
+ publicClient.readContract({
6818
+ address: disputeContractAddress,
6819
+ abi: disputeAbi,
6820
+ functionName: "disputeBond",
6821
+ }),
6822
+ publicClient.readContract({
6823
+ address: disputeContractAddress,
6824
+ abi: disputeAbi,
6825
+ functionName: "protocolDisputeFee",
6826
+ }),
6827
+ publicClient.readContract({
6828
+ address: disputeContractAddress,
6829
+ abi: disputeAbi,
6830
+ functionName: "disputeToken",
6831
+ }),
6832
+ ]);
6833
+ const isNativeToken = disputeToken === zeroAddress;
6834
+ const totalAmount = disputeBond + protocolFee;
6835
+ if (!isNativeToken) {
6836
+ // ERC20 token: approve the dispute contract to spend the total amount
6837
+ yield this.approveERC20IfNeeded(disputeToken, disputeContractAddress, totalAmount);
6838
+ }
6839
+ // Call the raiseDispute contract method
6840
+ // Pass the total (bond + protocol fee) as msg.value if using native token
6841
+ return this.callContractMethod(disputeContractAddress, disputeAbi, "raiseDispute", [targetIpId, evidenceHash, disputeTag], {
6842
+ waitForReceipt: true,
6843
+ value: isNativeToken ? totalAmount : undefined,
6844
+ });
6811
6845
  });
6812
6846
  }
6813
6847
 
@@ -6969,7 +7003,23 @@ function tagChildIp(childIpId, infringerDisputeId) {
6969
7003
  */
6970
7004
  function getDispute(disputeId) {
6971
7005
  return __awaiter(this, void 0, void 0, function* () {
6972
- return this.callContractMethod(this.environment.DISPUTE_CONTRACT_ADDRESS, this.environment.DISPUTE_ABI, "disputes", [disputeId]);
7006
+ const result = yield this.callContractMethod(this.environment.DISPUTE_CONTRACT_ADDRESS, this.environment.DISPUTE_ABI, "disputes", [disputeId]);
7007
+ // Contract returns a tuple, map it to the Dispute interface
7008
+ const [initiator, targetId, disputeTag, disputeEvidenceHash, counterEvidenceHash, disputeTimestamp, assertionTimestamp, yesVotes, noVotes, status, bondAmount, protocolFeeAmount,] = result;
7009
+ return {
7010
+ initiator,
7011
+ targetId,
7012
+ disputeTag,
7013
+ disputeEvidenceHash,
7014
+ counterEvidenceHash,
7015
+ disputeTimestamp,
7016
+ assertionTimestamp,
7017
+ yesVotes,
7018
+ noVotes,
7019
+ status: status,
7020
+ bondAmount,
7021
+ protocolFeeAmount,
7022
+ };
6973
7023
  });
6974
7024
  }
6975
7025
 
@@ -7251,6 +7301,71 @@ function getDisputeProgress(disputeId) {
7251
7301
  });
7252
7302
  }
7253
7303
 
7304
+ /**
7305
+ * Gets the requirements for raising a dispute, including balance check.
7306
+ *
7307
+ * @param userAddress The address to check balance for.
7308
+ * @returns A promise that resolves with the dispute requirements.
7309
+ *
7310
+ * @example
7311
+ * ```typescript
7312
+ * const requirements = await origin.getDisputeRequirements(walletAddress);
7313
+ * if (!requirements.hasSufficientBalance) {
7314
+ * console.log(`Need ${requirements.totalRequired} but only have ${requirements.userBalance}`);
7315
+ * }
7316
+ * ```
7317
+ */
7318
+ function getDisputeRequirements(userAddress) {
7319
+ return __awaiter(this, void 0, void 0, function* () {
7320
+ const publicClient = getPublicClient();
7321
+ const disputeContractAddress = this.environment
7322
+ .DISPUTE_CONTRACT_ADDRESS;
7323
+ const disputeAbi = this.environment.DISPUTE_ABI;
7324
+ // Get dispute parameters from the contract
7325
+ const [bondAmount, protocolFee, tokenAddress] = yield Promise.all([
7326
+ publicClient.readContract({
7327
+ address: disputeContractAddress,
7328
+ abi: disputeAbi,
7329
+ functionName: "disputeBond",
7330
+ }),
7331
+ publicClient.readContract({
7332
+ address: disputeContractAddress,
7333
+ abi: disputeAbi,
7334
+ functionName: "protocolDisputeFee",
7335
+ }),
7336
+ publicClient.readContract({
7337
+ address: disputeContractAddress,
7338
+ abi: disputeAbi,
7339
+ functionName: "disputeToken",
7340
+ }),
7341
+ ]);
7342
+ const isNativeToken = tokenAddress === zeroAddress;
7343
+ const totalRequired = bondAmount + protocolFee;
7344
+ // Get user's balance
7345
+ let userBalance;
7346
+ if (isNativeToken) {
7347
+ userBalance = yield publicClient.getBalance({ address: userAddress });
7348
+ }
7349
+ else {
7350
+ userBalance = (yield publicClient.readContract({
7351
+ address: tokenAddress,
7352
+ abi: erc20Abi,
7353
+ functionName: "balanceOf",
7354
+ args: [userAddress],
7355
+ }));
7356
+ }
7357
+ return {
7358
+ bondAmount,
7359
+ protocolFee,
7360
+ totalRequired,
7361
+ tokenAddress,
7362
+ isNativeToken,
7363
+ userBalance,
7364
+ hasSufficientBalance: userBalance >= totalRequired,
7365
+ };
7366
+ });
7367
+ }
7368
+
7254
7369
  /**
7255
7370
  * Fractionalizes an IP NFT into fungible ERC20 tokens.
7256
7371
  * The NFT is transferred to the fractionalizer contract and a new ERC20 token is created.
@@ -7622,10 +7737,11 @@ function getAppInfo(appId) {
7622
7737
  /**
7623
7738
  * Approves a spender to spend a specified amount of tokens on behalf of the owner.
7624
7739
  * If the current allowance is less than the specified amount, it will perform the approval.
7740
+ * Waits for the approval transaction to be confirmed before returning.
7625
7741
  * @param {ApproveParams} params - The parameters for the approval.
7626
7742
  */
7627
7743
  function approveIfNeeded(_a) {
7628
- return __awaiter(this, arguments, void 0, function* ({ walletClient, publicClient, tokenAddress, owner, spender, amount, }) {
7744
+ return __awaiter(this, arguments, void 0, function* ({ walletClient, publicClient, tokenAddress, owner, spender, amount, chain, }) {
7629
7745
  const allowance = yield publicClient.readContract({
7630
7746
  address: tokenAddress,
7631
7747
  abi: erc20Abi,
@@ -7633,14 +7749,21 @@ function approveIfNeeded(_a) {
7633
7749
  args: [owner, spender],
7634
7750
  });
7635
7751
  if (allowance < amount) {
7636
- yield walletClient.writeContract({
7752
+ const txHash = yield walletClient.writeContract({
7637
7753
  address: tokenAddress,
7638
7754
  account: owner,
7639
7755
  abi: erc20Abi,
7640
7756
  functionName: "approve",
7641
7757
  args: [spender, amount],
7642
- chain: testnet,
7758
+ chain,
7643
7759
  });
7760
+ // Wait for the approval transaction to be confirmed with extra confirmations
7761
+ yield publicClient.waitForTransactionReceipt({
7762
+ hash: txHash,
7763
+ confirmations: 2,
7764
+ });
7765
+ // Small delay to ensure RPC nodes have synced the new state
7766
+ yield new Promise((resolve) => setTimeout(resolve, 1000));
7644
7767
  }
7645
7768
  });
7646
7769
  }
@@ -7809,6 +7932,7 @@ function bulkBuyAccessSmart(tokenIds, options) {
7809
7932
  owner: buyer,
7810
7933
  spender: this.environment.BATCH_PURCHASE_CONTRACT_ADDRESS,
7811
7934
  amount: erc20.amount,
7935
+ chain: this.environment.CHAIN,
7812
7936
  });
7813
7937
  }
7814
7938
  // Execute the purchase
@@ -7884,6 +8008,7 @@ class Origin {
7884
8008
  this.getDispute = getDispute.bind(this);
7885
8009
  this.canVoteOnDispute = canVoteOnDispute.bind(this);
7886
8010
  this.getDisputeProgress = getDisputeProgress.bind(this);
8011
+ this.getDisputeRequirements = getDisputeRequirements.bind(this);
7887
8012
  // Fractionalizer module methods
7888
8013
  this.fractionalize = fractionalize.bind(this);
7889
8014
  this.redeem = redeem.bind(this);
@@ -7901,6 +8026,27 @@ class Origin {
7901
8026
  setViemClient(client) {
7902
8027
  this.viemClient = client;
7903
8028
  }
8029
+ /**
8030
+ * Approves an ERC20 token for spending by a spender address if the current allowance is insufficient.
8031
+ * Waits for the approval transaction to be confirmed before returning.
8032
+ * @param tokenAddress The address of the ERC20 token.
8033
+ * @param spender The address that will be approved to spend the tokens.
8034
+ * @param amount The amount of tokens to approve.
8035
+ */
8036
+ approveERC20IfNeeded(tokenAddress, spender, amount) {
8037
+ return __awaiter(this, void 0, void 0, function* () {
8038
+ const account = yield __classPrivateFieldGet(this, _Origin_instances, "m", _Origin_resolveWalletAddress).call(this);
8039
+ yield approveIfNeeded({
8040
+ walletClient: this.viemClient,
8041
+ publicClient: getPublicClient(),
8042
+ tokenAddress,
8043
+ owner: account,
8044
+ spender,
8045
+ amount,
8046
+ chain: this.environment.CHAIN,
8047
+ });
8048
+ });
8049
+ }
7904
8050
  /**
7905
8051
  * Uploads a JSON object to IPFS and returns the resulting CID.
7906
8052
  * @param data The JSON object to upload.
@@ -8257,6 +8403,7 @@ class Origin {
8257
8403
  owner: account,
8258
8404
  spender: this.environment.MARKETPLACE_CONTRACT_ADDRESS,
8259
8405
  amount: totalCost,
8406
+ chain: this.environment.CHAIN,
8260
8407
  });
8261
8408
  return this.buyAccess(account, tokenId, totalCost, duration, paymentToken, protocolFeeBps, appFeeBps);
8262
8409
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campnetwork/origin",
3
- "version": "1.3.0-alpha.3",
3
+ "version": "1.3.0-alpha.6",
4
4
  "main": "dist/core.cjs",
5
5
  "exports": {
6
6
  ".": {