UNPKG

@campnetwork/origin

Version:
2,327 lines (2,288 loc) 291 kB
'use client'; import React, { createContext, useState, useContext, useEffect, useLayoutEffect, useRef, useSyncExternalStore } from 'react'; import { custom, createWalletClient, createPublicClient, http, erc20Abi, getAbiItem, encodeFunctionData, zeroAddress, checksumAddress } from 'viem'; import { toAccount } from 'viem/accounts'; import { createSiweMessage } from 'viem/siwe'; import axios from 'axios'; import { WagmiContext, useAccount, useConnectorClient } from 'wagmi'; import ReactDOM, { createPortal } from 'react-dom'; import { useQuery } from '@tanstack/react-query'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; class APIError extends Error { constructor(message, statusCode) { super(message); this.name = "APIError"; this.statusCode = statusCode || 500; Error.captureStackTrace(this, this.constructor); } toJSON() { return { error: this.name, message: this.message, statusCode: this.statusCode || 500, }; } } const testnet = { id: 123420001114, name: "Basecamp", nativeCurrency: { decimals: 18, name: "Camp", symbol: "CAMP", }, rpcUrls: { default: { http: [ "https://rpc-campnetwork.xyz", "https://rpc.basecamp.t.raas.gelato.cloud", ], }, }, blockExplorers: { default: { name: "Explorer", url: "https://basecamp.cloud.blockscout.com/", }, }, }; // @ts-ignore let client = null; let publicClient = null; const getClient = (provider, name = "window.ethereum", address) => { var _a; if (!provider && !client) { console.warn("Provider is required to create a client."); return null; } if (!client || (client.transport.name !== name && provider) || (address !== ((_a = client.account) === null || _a === void 0 ? void 0 : _a.address) && provider)) { const obj = { chain: testnet, transport: custom(provider, { name: name, }), }; if (address) { obj.account = toAccount(address); } client = createWalletClient(obj); } return client; }; const getPublicClient = () => { if (!publicClient) { publicClient = createPublicClient({ chain: testnet, transport: http(), }); } return publicClient; }; var constants = { SIWE_MESSAGE_STATEMENT: "Connect with Camp Network", AUTH_HUB_BASE_API: "https://wv2h4to5qa.execute-api.us-east-2.amazonaws.com/dev", ORIGIN_DASHBOARD: "https://origin.campnetwork.xyz", SUPPORTED_IMAGE_FORMATS: [ "image/jpeg", "image/png", "image/gif", "image/webp", ], SUPPORTED_VIDEO_FORMATS: ["video/mp4", "video/webm"], SUPPORTED_AUDIO_FORMATS: ["audio/mpeg", "audio/wav", "audio/ogg"], SUPPORTED_TEXT_FORMATS: ["text/plain"], AVAILABLE_SOCIALS: ["twitter", "spotify", "tiktok"], ACKEE_INSTANCE: "https://ackee-production-01bd.up.railway.app", ACKEE_EVENTS: { USER_CONNECTED: "ed42542d-b676-4112-b6d9-6db98048b2e0", USER_DISCONNECTED: "20af31ac-e602-442e-9e0e-b589f4dd4016", TWITTER_LINKED: "7fbea086-90ef-4679-ba69-f47f9255b34c", DISCORD_LINKED: "d73f5ae3-a8e8-48f2-8532-85e0c7780d6a", SPOTIFY_LINKED: "fc1788b4-c984-42c8-96f4-c87f6bb0b8f7", TIKTOK_LINKED: "4a2ffdd3-f0e9-4784-8b49-ff76ec1c0a6a", TELEGRAM_LINKED: "9006bc5d-bcc9-4d01-a860-4f1a201e8e47", }, DATANFT_CONTRACT_ADDRESS: "0xb55066f2793773B3784f8c57c415a8b5932B33Cd", MARKETPLACE_CONTRACT_ADDRESS: "0x977fdEF62CE095Ae8750Fd3496730F24F60dea7a", }; let providers = []; const providerStore = { value: () => providers, subscribe: (callback) => { function onAnnouncement(event) { if (providers.some((p) => p.info.uuid === event.detail.info.uuid)) return; providers = [...providers, event.detail]; callback(providers); } if (typeof window === "undefined") return; window.addEventListener("eip6963:announceProvider", onAnnouncement); window.dispatchEvent(new Event("eip6963:requestProvider")); return () => window.removeEventListener("eip6963:announceProvider", onAnnouncement); }, }; /** * Formats an Ethereum address by truncating it to the first and last n characters. * @param {string} address - The Ethereum address to format. * @param {number} n - The number of characters to keep from the start and end of the address. * @return {string} - The formatted address. */ const formatAddress = (address, n = 8) => { return `${address.slice(0, n)}...${address.slice(-n)}`; }; /** * Capitalizes the first letter of a string. * @param {string} str - The string to capitalize. * @return {string} - The capitalized string. */ const capitalize = (str) => { return str.charAt(0).toUpperCase() + str.slice(1); }; /** * Formats a Camp amount to a human-readable string. * @param {number} amount - The Camp amount to format. * @returns {string} - The formatted Camp amount. */ const formatCampAmount = (amount) => { if (amount >= 1000) { const formatted = (amount / 1000).toFixed(1); return formatted.endsWith(".0") ? formatted.slice(0, -2) + "k" : formatted + "k"; } return amount.toString(); }; /** * Uploads a file to a specified URL with progress tracking. * Falls back to a simple fetch request if XMLHttpRequest is not available. * @param {File} file - The file to upload. * @param {string} url - The URL to upload the file to. * @param {UploadProgressCallback} onProgress - A callback function to track upload progress. * @returns {Promise<string>} - A promise that resolves with the response from the server. */ const uploadWithProgress = (file, url, onProgress) => { return new Promise((resolve, reject) => { axios .put(url, file, Object.assign({ headers: { "Content-Type": file.type, } }, (typeof window !== "undefined" && typeof onProgress === "function" ? { onUploadProgress: (progressEvent) => { if (progressEvent.total) { const percent = (progressEvent.loaded / progressEvent.total) * 100; onProgress(percent); } }, } : {}))) .then((res) => { resolve(res.data); }) .catch((error) => { var _a; const message = ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) || (error === null || error === void 0 ? void 0 : error.message) || "Upload failed"; reject(message); }); }); }; var abi$1 = [ { inputs: [ { internalType: "string", name: "_name", type: "string" }, { internalType: "string", name: "_symbol", type: "string" } ], stateMutability: "nonpayable", type: "constructor" }, { inputs: [ ], name: "DurationZero", type: "error" }, { inputs: [ { internalType: "address", name: "sender", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "address", name: "owner", type: "address" } ], name: "ERC721IncorrectOwner", type: "error" }, { inputs: [ { internalType: "address", name: "operator", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "ERC721InsufficientApproval", type: "error" }, { inputs: [ { internalType: "address", name: "approver", type: "address" } ], name: "ERC721InvalidApprover", type: "error" }, { inputs: [ { internalType: "address", name: "operator", type: "address" } ], name: "ERC721InvalidOperator", type: "error" }, { inputs: [ { internalType: "address", name: "owner", type: "address" } ], name: "ERC721InvalidOwner", type: "error" }, { inputs: [ { internalType: "address", name: "receiver", type: "address" } ], name: "ERC721InvalidReceiver", type: "error" }, { inputs: [ { internalType: "address", name: "sender", type: "address" } ], name: "ERC721InvalidSender", type: "error" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "ERC721NonexistentToken", type: "error" }, { inputs: [ ], name: "EnforcedPause", type: "error" }, { inputs: [ ], name: "ExpectedPause", type: "error" }, { inputs: [ ], name: "InvalidDeadline", type: "error" }, { inputs: [ { internalType: "uint16", name: "royaltyBps", type: "uint16" } ], name: "InvalidRoyalty", type: "error" }, { inputs: [ ], name: "InvalidSignature", type: "error" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "address", name: "caller", type: "address" } ], name: "NotTokenOwner", type: "error" }, { inputs: [ { internalType: "address", name: "owner", type: "address" } ], name: "OwnableInvalidOwner", type: "error" }, { inputs: [ { internalType: "address", name: "account", type: "address" } ], name: "OwnableUnauthorizedAccount", type: "error" }, { inputs: [ ], name: "SignatureAlreadyUsed", type: "error" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "TokenAlreadyExists", type: "error" }, { inputs: [ ], name: "Unauthorized", type: "error" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: true, internalType: "address", name: "buyer", type: "address" }, { indexed: false, internalType: "uint32", name: "periods", type: "uint32" }, { indexed: false, internalType: "uint256", name: "newExpiry", type: "uint256" }, { indexed: false, internalType: "uint256", name: "amountPaid", type: "uint256" } ], name: "AccessPurchased", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "owner", type: "address" }, { indexed: true, internalType: "address", name: "approved", type: "address" }, { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "Approval", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "owner", type: "address" }, { indexed: true, internalType: "address", name: "operator", type: "address" }, { indexed: false, internalType: "bool", name: "approved", type: "bool" } ], name: "ApprovalForAll", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: true, internalType: "address", name: "creator", type: "address" } ], name: "DataDeleted", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: true, internalType: "address", name: "creator", type: "address" }, { indexed: false, internalType: "bytes32", name: "contentHash", type: "bytes32" } ], name: "DataMinted", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "previousOwner", type: "address" }, { indexed: true, internalType: "address", name: "newOwner", type: "address" } ], name: "OwnershipTransferred", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "account", type: "address" } ], name: "Paused", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: false, internalType: "uint256", name: "royaltyAmount", type: "uint256" }, { indexed: false, internalType: "address", name: "creator", type: "address" }, { indexed: false, internalType: "uint256", name: "protocolAmount", type: "uint256" } ], name: "RoyaltyPaid", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: false, internalType: "uint128", name: "newPrice", type: "uint128" }, { indexed: false, internalType: "uint32", name: "newDuration", type: "uint32" }, { indexed: false, internalType: "uint16", name: "newRoyaltyBps", type: "uint16" }, { indexed: false, internalType: "address", name: "paymentToken", type: "address" } ], name: "TermsUpdated", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "from", type: "address" }, { indexed: true, internalType: "address", name: "to", type: "address" }, { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "Transfer", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "account", type: "address" } ], name: "Unpaused", type: "event" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "approve", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "owner", type: "address" } ], name: "balanceOf", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "", type: "uint256" } ], name: "contentHash", outputs: [ { internalType: "bytes32", name: "", type: "bytes32" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "", type: "uint256" } ], name: "dataStatus", outputs: [ { internalType: "enum IpNFT.DataStatus", name: "", type: "uint8" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "finalizeDelete", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "getApproved", outputs: [ { internalType: "address", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "getTerms", outputs: [ { components: [ { internalType: "uint128", name: "price", type: "uint128" }, { internalType: "uint32", name: "duration", type: "uint32" }, { internalType: "uint16", name: "royaltyBps", type: "uint16" }, { internalType: "address", name: "paymentToken", type: "address" } ], internalType: "struct IpNFT.LicenseTerms", name: "", type: "tuple" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "owner", type: "address" }, { internalType: "address", name: "operator", type: "address" } ], name: "isApprovedForAll", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "bytes32", name: "creatorContentHash", type: "bytes32" }, { internalType: "string", name: "uri", type: "string" }, { components: [ { internalType: "uint128", name: "price", type: "uint128" }, { internalType: "uint32", name: "duration", type: "uint32" }, { internalType: "uint16", name: "royaltyBps", type: "uint16" }, { internalType: "address", name: "paymentToken", type: "address" } ], internalType: "struct IpNFT.LicenseTerms", name: "licenseTerms", type: "tuple" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "bytes", name: "signature", type: "bytes" } ], name: "mintWithSignature", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ ], name: "name", outputs: [ { internalType: "string", name: "", type: "string" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "owner", outputs: [ { internalType: "address", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "ownerOf", outputs: [ { internalType: "address", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "pause", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ ], name: "paused", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "renounceOwnership", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "uint256", name: "salePrice", type: "uint256" } ], name: "royaltyInfo", outputs: [ { internalType: "address", name: "receiver", type: "address" }, { internalType: "uint256", name: "royaltyAmount", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "", type: "uint256" } ], name: "royaltyPercentages", outputs: [ { internalType: "uint16", name: "", type: "uint16" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "", type: "uint256" } ], name: "royaltyReceivers", outputs: [ { internalType: "address", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "from", type: "address" }, { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "safeTransferFrom", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "from", type: "address" }, { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "bytes", name: "data", type: "bytes" } ], name: "safeTransferFrom", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "operator", type: "address" }, { internalType: "bool", name: "approved", type: "bool" } ], name: "setApprovalForAll", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "bytes4", name: "interfaceId", type: "bytes4" } ], name: "supportsInterface", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "symbol", outputs: [ { internalType: "string", name: "", type: "string" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "", type: "uint256" } ], name: "terms", outputs: [ { internalType: "uint128", name: "price", type: "uint128" }, { internalType: "uint32", name: "duration", type: "uint32" }, { internalType: "uint16", name: "royaltyBps", type: "uint16" }, { internalType: "address", name: "paymentToken", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "_tokenId", type: "uint256" } ], name: "tokenURI", outputs: [ { internalType: "string", name: "", type: "string" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "from", type: "address" }, { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "transferFrom", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "newOwner", type: "address" } ], name: "transferOwnership", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ ], name: "unpause", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "address", name: "_royaltyReceiver", type: "address" }, { components: [ { internalType: "uint128", name: "price", type: "uint128" }, { internalType: "uint32", name: "duration", type: "uint32" }, { internalType: "uint16", name: "royaltyBps", type: "uint16" }, { internalType: "address", name: "paymentToken", type: "address" } ], internalType: "struct IpNFT.LicenseTerms", name: "newTerms", type: "tuple" } ], name: "updateTerms", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "bytes32", name: "", type: "bytes32" } ], name: "usedNonces", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" } ]; /** * Mints a Data NFT with a signature. * @param to The address to mint the NFT to. * @param tokenId The ID of the token to mint. * @param hash The hash of the data associated with the NFT. * @param uri The URI of the NFT metadata. * @param licenseTerms The terms of the license for the NFT. * @param deadline The deadline for the minting operation. * @param signature The signature for the minting operation. * @returns A promise that resolves when the minting is complete. */ function mintWithSignature(to, tokenId, hash, uri, licenseTerms, deadline, signature) { return __awaiter(this, void 0, void 0, function* () { return yield this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "mintWithSignature", [to, tokenId, hash, uri, licenseTerms, deadline, signature], { waitForReceipt: true }); }); } /** * Registers a Data NFT with the Origin service in order to obtain a signature for minting. * @param source The source of the Data NFT (e.g., "spotify", "twitter", "tiktok", or "file"). * @param deadline The deadline for the registration operation. * @param fileKey Optional file key for file uploads. * @return A promise that resolves with the registration data. */ function registerIpNFT(source, deadline, licenseTerms, fileKey) { return __awaiter(this, void 0, void 0, function* () { const body = { source, deadline: Number(deadline), licenseTerms: { price: licenseTerms.price.toString(), duration: licenseTerms.duration, royaltyBps: licenseTerms.royaltyBps, paymentToken: licenseTerms.paymentToken, }, }; if (fileKey !== undefined) { body.fileKey = fileKey; } const res = yield fetch(`${constants.AUTH_HUB_BASE_API}/auth/origin/register`, { method: "POST", headers: { Authorization: `Bearer ${this.getJwt()}`, }, body: JSON.stringify(body), }); if (!res.ok) { throw new Error(`Failed to get signature: ${res.statusText}`); } const data = yield res.json(); if (data.isError) { throw new Error(`Failed to get signature: ${data.message}`); } return data.data; }); } function updateTerms(tokenId, newTerms) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "updateTerms", [tokenId, newTerms], { waitForReceipt: true }); } function requestDelete(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "requestDelete", [tokenId]); } function getTerms(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "getTerms", [tokenId]); } function ownerOf(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "ownerOf", [tokenId]); } function balanceOf(owner) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "balanceOf", [owner]); } function contentHash(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "contentHash", [tokenId]); } function tokenURI(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "tokenURI", [tokenId]); } function dataStatus(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "dataStatus", [tokenId]); } function royaltyInfo(tokenId, salePrice) { return __awaiter(this, void 0, void 0, function* () { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "royaltyInfo", [tokenId, salePrice]); }); } function getApproved(tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "getApproved", [tokenId]); } function isApprovedForAll(owner, operator) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "isApprovedForAll", [owner, operator]); } function transferFrom(from, to, tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "transferFrom", [from, to, tokenId]); } function safeTransferFrom(from, to, tokenId, data) { const args = data ? [from, to, tokenId, data] : [from, to, tokenId]; return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "safeTransferFrom", args); } function approve(to, tokenId) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "approve", [to, tokenId]); } function setApprovalForAll(operator, approved) { return this.callContractMethod(constants.DATANFT_CONTRACT_ADDRESS, abi$1, "setApprovalForAll", [operator, approved]); } var abi = [ { inputs: [ { internalType: "address", name: "dataNFT_", type: "address" }, { internalType: "uint16", name: "protocolFeeBps_", type: "uint16" }, { internalType: "address", name: "treasury_", type: "address" } ], stateMutability: "nonpayable", type: "constructor" }, { inputs: [ ], name: "EnforcedPause", type: "error" }, { inputs: [ ], name: "ExpectedPause", type: "error" }, { inputs: [ { internalType: "uint256", name: "expected", type: "uint256" }, { internalType: "uint256", name: "actual", type: "uint256" } ], name: "InvalidPayment", type: "error" }, { inputs: [ { internalType: "uint32", name: "periods", type: "uint32" } ], name: "InvalidPeriods", type: "error" }, { inputs: [ { internalType: "uint16", name: "royaltyBps", type: "uint16" } ], name: "InvalidRoyalty", type: "error" }, { inputs: [ { internalType: "address", name: "owner", type: "address" } ], name: "OwnableInvalidOwner", type: "error" }, { inputs: [ { internalType: "address", name: "account", type: "address" } ], name: "OwnableUnauthorizedAccount", type: "error" }, { inputs: [ ], name: "TransferFailed", type: "error" }, { inputs: [ ], name: "Unauthorized", type: "error" }, { inputs: [ ], name: "ZeroAddress", type: "error" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: true, internalType: "address", name: "buyer", type: "address" }, { indexed: false, internalType: "uint32", name: "periods", type: "uint32" }, { indexed: false, internalType: "uint256", name: "newExpiry", type: "uint256" }, { indexed: false, internalType: "uint256", name: "amountPaid", type: "uint256" } ], name: "AccessPurchased", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: true, internalType: "address", name: "creator", type: "address" } ], name: "DataDeleted", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: true, internalType: "address", name: "creator", type: "address" }, { indexed: false, internalType: "bytes32", name: "contentHash", type: "bytes32" } ], name: "DataMinted", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "previousOwner", type: "address" }, { indexed: true, internalType: "address", name: "newOwner", type: "address" } ], name: "OwnershipTransferred", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "account", type: "address" } ], name: "Paused", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: false, internalType: "uint256", name: "royaltyAmount", type: "uint256" }, { indexed: false, internalType: "address", name: "creator", type: "address" }, { indexed: false, internalType: "uint256", name: "protocolAmount", type: "uint256" } ], name: "RoyaltyPaid", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "uint256", name: "tokenId", type: "uint256" }, { indexed: false, internalType: "uint128", name: "newPrice", type: "uint128" }, { indexed: false, internalType: "uint32", name: "newDuration", type: "uint32" }, { indexed: false, internalType: "uint16", name: "newRoyaltyBps", type: "uint16" }, { indexed: false, internalType: "address", name: "paymentToken", type: "address" } ], name: "TermsUpdated", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "account", type: "address" } ], name: "Unpaused", type: "event" }, { inputs: [ { internalType: "address", name: "feeManager", type: "address" } ], name: "addFeeManager", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "buyer", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" }, { internalType: "uint32", name: "periods", type: "uint32" } ], name: "buyAccess", outputs: [ ], stateMutability: "payable", type: "function" }, { inputs: [ ], name: "dataNFT", outputs: [ { internalType: "contract IpNFT", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "", type: "address" } ], name: "feeManagers", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "user", type: "address" }, { internalType: "uint256", name: "tokenId", type: "uint256" } ], name: "hasAccess", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "owner", outputs: [ { internalType: "address", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "pause", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ ], name: "paused", outputs: [ { internalType: "bool", name: "", type: "bool" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "protocolFeeBps", outputs: [ { internalType: "uint16", name: "", type: "uint16" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "feeManager", type: "address" } ], name: "removeFeeManager", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ ], name: "renounceOwnership", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "address", name: "", type: "address" } ], name: "subscriptionExpiry", outputs: [ { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "newOwner", type: "address" } ], name: "transferOwnership", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ ], name: "treasury", outputs: [ { internalType: "address", name: "", type: "address" } ], stateMutability: "view", type: "function" }, { inputs: [ ], name: "unpause", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint16", name: "newFeeBps", type: "uint16" } ], name: "updateProtocolFee", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "newTreasury", type: "address" } ], name: "updateTreasury", outputs: [ ], stateMutability: "nonpayable", type: "function" }, { stateMutability: "payable", type: "receive" } ]; function buyAccess(tokenId, periods, value // only for native token payments ) { return this.callContractMethod(constants.MARKETPLACE_CONTRACT_ADDRESS, abi, "buyAccess", [tokenId, periods], { waitForReceipt: true, value }); } function renewAccess(tokenId, buyer, periods, value) { return this.callContractMethod(constants.MARKETPLACE_CONTRACT_ADDRESS, abi, "renewAccess", [tokenId, buyer, periods], value !== undefined ? { value } : undefined); } function hasAccess(user, tokenId) { return this.callContractMethod(constants.MARKETPLACE_CONTRACT_ADDRESS, abi, "hasAccess", [user, tokenId]); } function subscriptionExpiry(tokenId, user) { return this.callContractMethod(constants.MARKETPLACE_CONTRACT_ADDRESS, abi, "subscriptionExpiry", [tokenId, user]); } /** * Approves a spender to spend a specified amount of tokens on behalf of the owner. * If the current allowance is less than the specified amount, it will perform the approval. * @param {ApproveParams} params - The parameters for the approval. */ function approveIfNeeded(_a) { return __awaiter(this, arguments, void 0, function* ({ walletClient, publicClient, tokenAddress, owner, spender, amount, }) { const allowance = yield publicClient.readContract({ address: tokenAddress, abi: erc20Abi, functionName: "allowance", args: [owner, spender], }); if (allowance < amount) { yield walletClient.writeContract({ address: tokenAddress, account: owner, abi: erc20Abi, functionName: "approve", args: [spender, amount], chain: testnet, }); } }); } var _Origin_instances, _Origin_generateURL, _Origin_setOriginStatus, _Origin_waitForTxReceipt, _Origin_ensureChainId; /** * The Origin class * Handles the upload of files to Origin, as well as querying the user's stats */ class Origin { constructor(jwt, viemClient) { _Origin_instances.add(this); _Origin_generateURL.set(this, (file) => __awaiter(this, void 0, void 0, function* () { const uploadRes = yield fetch(`${constants.AUTH_HUB_BASE_API}/auth/origin/upload-url`, { method: "POST", body: JSON.stringify({ name: file.name, type: file.type, }), headers: { Authorization: `Bearer ${this.jwt}`, }, }); const data = yield uploadRes.json(); return data.isError ? data.message : data.data; })); _Origin_setOriginStatus.set(this, (key, status) => __awaiter(this, void 0, void 0, function* () { const res = yield fetch(`${constants.AUTH_HUB_BASE_API}/auth/origin/update-status`, { method: "PATCH", body: JSON.stringify({ status, fileKey: key, }), headers: { Authorization: `Bearer ${this.jwt}`, "Content-Type": "application/json", }, }); if (!res.ok) { console.error("Failed to update origin status"); return; } })); this.uploadFile = (file, options) => __awaiter(this, void 0, void 0, function* () { const uploadInfo = yield __classPrivateFieldGet(this, _Origin_generateURL, "f").call(this, file); if (!uploadInfo) { console.error("Failed to generate upload URL"); return; } try { yield uploadWithProgress(file, uploadInfo.url, (options === null || options === void 0 ? void 0 : options.progressCallback) || (() => { })); } catch (error) { yield __classPrivateFieldGet(this, _Origin_setOriginStatus, "f").call(this, uploadInfo.key, "failed"); throw new Error("Failed to upload file: " + error); } yield __classPrivateFieldGet(this, _Origin_setOriginStatus, "f").call(this, uploadInfo.key, "success"); return uploadInfo; }); this.mintFile = (file, license, options) => __awaiter(this, void 0, void 0, function* () { if (!this.viemClient) { throw new Error("WalletClient not connected."); } const info = yield this.uploadFile(file, options); if (!info || !info.key) { throw new Error("Failed to upload file or get upload info."); } const deadline = BigInt(Math.floor(Date.now()) + 600); // 10 minutes from now const registration = yield this.registerIpNFT("file", deadline, license, info.key); const { tokenId, signerAddress, creatorContentHash, signature, uri } = registration; if (!tokenId || !signerAddress || !creatorContentHash || signature === undefined || !uri) { throw new Error("Failed to register IpNFT: Missing required fields in registration response."); } const [account] = yield this.viemClient.request({ method: "eth_requestAccounts", params: [], }); const mintResult = yield this.mintWithSignature(account, tokenId, creatorContentHash, uri, license, deadline, signature); if (mintResult.status !== "0x1") { throw new Error(`Minting failed with status: ${mintResult.status}`); } return tokenId.toString(); }); this.mintSocial = (source, license) => __awaiter(this, void 0, void 0, function* () { // try { const deadline = BigInt(Math.floor(Date.now()) + 600); // 10 minutes from now (temp) const registration = yield this.registerIpNFT(source, deadline, license); if (!registration) { // console.error("Failed to register IpNFT"); // return null; throw new Error("Failed to register Social IpNFT"); } return registration.tokenId.toString(); // } catch (error) { // console.error("Failed to mint social IpNFT:", error); // return null; // } }); this.getOriginUploads = () => __awaiter(this, void 0, void 0, function* () { const res = yield fetch(`${constants.AUTH_HUB_BASE_API}/auth/origin/files`, { method: "GET", headers: { Authorization: `Bearer ${this.jwt}`, }, }); if (!res.ok) { console.error("Failed to get origin uploads"); return null; } const data = yield res.json(); return data.data; }); this.jwt = jwt; this.viemClient = viemClient; // DataNFT methods this.mintWithSignature = mintWithSignature.bind(this); this.registerIpNFT = registerIpNFT.bind(this); this.updateTerms = updateTerms.bind(this); this.requestDelete = requestDelete.bind(this); this.getTerms = getTerms.bind(this); this.ownerOf = ownerOf.bind(this); this.balanceOf = balanceOf.bind(this); this.contentHash = contentHash.bind(this); this.tokenURI = tokenURI.bind(this); this.dataStatus = dataStatus.bind(this); this.royaltyInfo = royaltyInfo.bind(this); this.getApproved = getApproved.bind(this); this.isApprovedForAll = isApprovedForAll.bind(this); this.transferFrom = transferFrom.bind(this); this.safeTransferFrom = safeTransferFrom.bind(this); this.approve = approve.bind(this); this.setApprovalForAll = setApprovalForAll.bind(this); // Marketplace methods this.buyAccess = buyAccess.bind(this); this.renewAccess = renewAccess.bind(this); this.hasAccess = hasAccess.bind(this); this.subscriptionExpiry = subscriptionExpiry.bind(this); } getJwt() { return this.jwt; } setViemClient(client) { this.viemClient = client; } /** * Get the user's Origin stats (multiplier, consent, usage, etc.). * @returns {Promise<OriginUsageReturnType>} A promise that resolves with the user's Origin stats. */ getOriginUsage() { return __awaiter(this, void 0, void 0, function* () { const data = yield fetch(`${constants.AUTH_HUB_BASE_API}/auth/origin/usage`, { method: "GET", headers: { Authorization: `Bearer ${this.jwt}`, // "x-client-id": this.clientId, "Content-Type": "application/json", }, }).then((res) => res.json()); if (!data.isError && data.data.user) { return data; } else { throw new APIError(data.message || "Failed to fetch Origin usage"); } }); } /** * Set the user's consent for Origin usage. * @param {boolean} consent The user's consent. * @returns {Promise<void>} * @throws {Error|APIError} - Throws an error if the user is not authenticated. Also throws an error if the consent is not provided. */ setOriginConsent(consent) { return __awaiter(this, void 0, void 0, function* () { if (consent === undefined) { throw new APIError("Consent is required"); } const data = yield fetch(`${constants.AUTH_HUB_BASE_API}/auth/origin/status`, { method: "PATCH", headers: { Authorization: `Bearer ${this.jwt}`, // "x-client-id": this.clientId, "Content-Type": "application/json", }, body: JSON.stringify({ active: consent, }), }).then((res) => res.json()); if (!data.isError) { return; } else { throw new APIError(data.message || "Failed to