@cultura/sdk
Version:
SDK for interacting with Cultura, a Layer 2 Ethereum blockchain acting as the global registry for human creativity and IP. It ensures transparent licensing, revenue sharing, and secure provenance.
10,590 lines • 280 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
CulturaSDK: () => CulturaSDK,
ENVIRONMENTS: () => ENVIRONMENTS,
QueryClient: () => QueryClient,
createChainConfig: () => createChainConfig,
culturaChain: () => culturaChain,
getChainDisplayName: () => getChainDisplayName,
getNetworkName: () => getNetworkName,
utils: () => utils_exports
});
module.exports = __toCommonJS(index_exports);
// src/client.ts
var import_viem13 = require("viem");
// src/deployments/localhost.json
var localhost_default = {
schemaRegistry: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
mockERC20: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
CASProxy: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
CulturaDigitalAsset: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
CulturaRoyaltyModule: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
VerifierModule: "0x0165878A594ca255338adfa4d48449f69242Eb8F",
POP: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
LicensingAttestationMock: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788"
};
// src/deployments/conduit_devnet.json
var conduit_devnet_default = {
schemaRegistry: "0x099b90bD793aFccF3Cb272B452564a45d3B38cBe",
mockERC20: "0x94B1215cf3a7A80Ff006Fe6a088bF0aef4e8723E",
CASProxy: "0x730804d0bd3A29B77c5D07Ffcf1A4C9F965FCd28",
CulturaDigitalAsset: "0xc03B38Da60410119A8bE0b3c8a167dAe6d062F7C",
CulturaRoyaltyModule: "0xe281ed653157ebab1facb9616eF078d27F3E88af",
VerifierModule: "0x3d884E909979e220046A054ca3637b12C85307e0",
POP: "0x4aB6a0466044323d7f6b8845ac53992a355C4Ba7",
LicensingAttestationMock: "0x4D338CcAFe5A43F4B724CD7D874060Fb9222b152"
};
// src/deployments/conduit_testnet.json
var conduit_testnet_default = {
schemaRegistry: "0xc50362623DF286f1947688a6fa02086dE90FC7dF",
mockERC20: "0xb90e5a2fBe67c4C16517b909aa246bE6C889e21F",
CASProxy: "0xCDDda673Aa3138087F3a310B5Ba502e0E0B0343f",
CulturaDigitalAsset: "0xa7f1df597e238B2e0865a512e4109Bc1225B735E",
CulturaRoyaltyModule: "0x767F996Cb2E99B53B45EC4f2fb1A61cd02A7B966",
VerifierModule: "0x1E51dc3A8359C1EA0F4d419C0f05aCC64611Eb8a",
POP: "0x1A62ac7CA19B83D8C987DC27169c1F15186Ad1fA",
LicensingAttestationMock: "0xF2A6A0876a9093258f2b39B94D9c9752099e4413"
};
// src/config.ts
var ENVIRONMENTS = {
local: {
rpcUrl: "http://127.0.0.1:8545",
chainId: 31337,
// Default Hardhat chain ID
contracts: {
attestationService: localhost_default.CASProxy,
schemaRegistry: localhost_default.schemaRegistry,
culturaDigitalAsset: localhost_default.CulturaDigitalAsset,
bondToken: localhost_default.mockERC20,
royaltyModule: localhost_default.CulturaRoyaltyModule,
mockLicensingProtocol: localhost_default.LicensingAttestationMock,
verifierModule: localhost_default.VerifierModule,
POP: localhost_default.POP
}
},
devnet: {
rpcUrl: "https://rpc-yelling-tomato-whale-2ib9sndb39.t.conduit.xyz",
chainId: 26156,
// Devnet chain ID
contracts: {
attestationService: conduit_devnet_default.CASProxy,
schemaRegistry: conduit_devnet_default.schemaRegistry,
culturaDigitalAsset: conduit_devnet_default.CulturaDigitalAsset,
bondToken: conduit_devnet_default.mockERC20,
royaltyModule: conduit_devnet_default.CulturaRoyaltyModule,
mockLicensingProtocol: conduit_devnet_default.LicensingAttestationMock,
verifierModule: conduit_devnet_default.VerifierModule,
POP: conduit_devnet_default.POP
}
},
testnet: {
rpcUrl: "https://sepolia.cultura.xyz",
chainId: 61892,
// Testnet chain ID
contracts: {
attestationService: conduit_testnet_default.CASProxy,
schemaRegistry: conduit_testnet_default.schemaRegistry,
culturaDigitalAsset: conduit_testnet_default.CulturaDigitalAsset,
bondToken: conduit_testnet_default.mockERC20,
royaltyModule: conduit_testnet_default.CulturaRoyaltyModule,
mockLicensingProtocol: conduit_testnet_default.LicensingAttestationMock,
verifierModule: conduit_testnet_default.VerifierModule,
POP: conduit_testnet_default.POP
}
}
};
var createChainConfig = (env) => {
return {
id: ENVIRONMENTS[env].chainId,
name: getChainDisplayName(env),
network: getNetworkName(env),
nativeCurrency: {
decimals: 18,
name: "Ether",
symbol: "ETH"
},
rpcUrls: {
default: {
http: [ENVIRONMENTS[env].rpcUrl]
},
public: {
http: [ENVIRONMENTS[env].rpcUrl]
}
}
};
};
var culturaChain = createChainConfig("testnet");
function getChainDisplayName(env) {
switch (env) {
case "local":
return "Local Hardhat";
case "devnet":
return "Cultura Devnet";
case "testnet":
return "Cultura Testnet";
default:
return "Cultura Devnet";
}
}
function getNetworkName(env) {
switch (env) {
case "local":
return "local";
case "devnet":
return "cultura-devnet";
case "testnet":
return "cultura-testnet";
default:
return "cultura-devnet";
}
}
// src/resources/attestationService.ts
var import_viem2 = require("viem");
// src/abi/generated.ts
var CASAbi = [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
}
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [],
"name": "AssetHasToBeVerifiedRights",
"type": "error"
},
{
"inputs": [],
"name": "AttestationDoesNotExist",
"type": "error"
},
{
"inputs": [],
"name": "ClassDoesNotExist",
"type": "error"
},
{
"inputs": [],
"name": "DigitalAssetCollectionCantBe0Address",
"type": "error"
},
{
"inputs": [],
"name": "ECDSAInvalidSignature",
"type": "error"
},
{
"inputs": [],
"name": "ECDSAInvalidSignature",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "length",
"type": "uint256"
}
],
"name": "ECDSAInvalidSignatureLength",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "ECDSAInvalidSignatureS",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "ERC1967InvalidImplementation",
"type": "error"
},
{
"inputs": [],
"name": "ERC1967NonPayable",
"type": "error"
},
{
"inputs": [],
"name": "FailedCall",
"type": "error"
},
{
"inputs": [],
"name": "InvalidExpirationTime",
"type": "error"
},
{
"inputs": [],
"name": "InvalidInitialization",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSchema",
"type": "error"
},
{
"inputs": [],
"name": "Irrevocable",
"type": "error"
},
{
"inputs": [],
"name": "NotFound",
"type": "error"
},
{
"inputs": [],
"name": "NotInitializing",
"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": "UUPSUnauthorizedCallContext",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "slot",
"type": "bytes32"
}
],
"name": "UUPSUnsupportedProxiableUUID",
"type": "error"
},
{
"inputs": [],
"name": "ValueSentLessThanClassFee",
"type": "error"
},
{
"inputs": [],
"name": "VerifierNotWhitelisted",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "attester",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "schemaUID",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "assetClass",
"type": "uint256"
}
],
"name": "Attested",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "challenger",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bondedAmount",
"type": "uint256"
}
],
"name": "Challenged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "rightsBoundAccount",
"type": "address"
},
{
"internalType": "address",
"name": "attester",
"type": "address"
},
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct CulturaRightsBoundAccountInfo",
"name": "rightsBoundAccount",
"type": "tuple"
}
],
"name": "CulturaRightsBoundAccountDeployed",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"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": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "attester",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "schemaUID",
"type": "bytes32"
}
],
"name": "Revoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "revoker",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "data",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint64",
"name": "timestamp",
"type": "uint64"
}
],
"name": "RevokedOffchain",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "data",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "uint64",
"name": "timestamp",
"type": "uint64"
}
],
"name": "Timestamped",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Upgraded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "attester",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
}
],
"name": "Verified",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "verifier",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "isWhitelisted",
"type": "bool"
}
],
"name": "VerifierWLStateChanged",
"type": "event"
},
{
"inputs": [],
"name": "UPGRADE_INTERFACE_VERSION",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "verifier",
"type": "address"
}
],
"name": "addWLVerifier",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "assetClasses",
"outputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "uint256",
"name": "fee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requiredTokens",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requiredWLVerifiers",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requiredCommunityUsers",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "schema",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint64",
"name": "expirationTime",
"type": "uint64"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "bytes32",
"name": "refUID",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"internalType": "struct AttestationRequestData",
"name": "data",
"type": "tuple"
}
],
"internalType": "struct AttestationRequest",
"name": "request",
"type": "tuple"
},
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "assetClass",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "attest",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "attestation",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint64",
"name": "expirationTime",
"type": "uint64"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "bytes32",
"name": "refUID",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"internalType": "struct ChallengeRequestData",
"name": "data",
"type": "tuple"
}
],
"internalType": "struct ChallengeRequest",
"name": "request",
"type": "tuple"
},
{
"internalType": "uint256",
"name": "challengeAmount",
"type": "uint256"
}
],
"name": "challengeAttestation",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "culturaTreasuryAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "levelValue",
"type": "uint256"
}
],
"name": "deactivateLevel",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "address",
"name": "signer",
"type": "address"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"internalType": "struct SignatureUtils.SignatureParams",
"name": "delegatedSignature",
"type": "tuple"
},
{
"components": [
{
"internalType": "bytes32",
"name": "schema",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint64",
"name": "expirationTime",
"type": "uint64"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "bytes32",
"name": "refUID",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"internalType": "struct AttestationRequestData",
"name": "data",
"type": "tuple"
}
],
"internalType": "struct AttestationRequest",
"name": "request",
"type": "tuple"
},
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "assetClass",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "attester",
"type": "address"
}
],
"name": "delegatedAttest",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "digitalAssetClasses",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "digitalAssetLevels",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{
"internalType": "bytes1",
"name": "fields",
"type": "bytes1"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256[]",
"name": "extensions",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
}
],
"name": "getAttestation",
"outputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "schema",
"type": "bytes32"
},
{
"internalType": "uint64",
"name": "time",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "expirationTime",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "revocationTime",
"type": "uint64"
},
{
"internalType": "bytes32",
"name": "refUID",
"type": "bytes32"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "address",
"name": "attester",
"type": "address"
},
{
"internalType": "uint256",
"name": "verifierCount",
"type": "uint256"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "bondedAmount",
"type": "uint256"
},
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "communityUserCount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "WLVerifierCount",
"type": "uint256"
}
],
"internalType": "struct Attestation",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "getNonce",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getSchemaRegistry",
"outputs": [
{
"internalType": "contract ISchemaRegistry",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "initialOwner",
"type": "address"
},
{
"internalType": "contract ISchemaRegistry",
"name": "initialSchemaRegistry",
"type": "address"
},
{
"internalType": "address",
"name": "bondToken",
"type": "address"
},
{
"internalType": "address",
"name": "_culturaTreasury",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
}
],
"name": "isAttestationValid",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isWLVerifier",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "levels",
"outputs": [
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "uint256",
"name": "minTokensLocked",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minVerifiers",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minCouncilVerifiers",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "proxiableUUID",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "verifier",
"type": "address"
}
],
"name": "removeWLVerifier",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint8",
"name": "levelValue",
"type": "uint8"
},
{
"components": [
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "uint256",
"name": "minTokensLocked",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minVerifiers",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minCouncilVerifiers",
"type": "uint256"
}
],
"internalType": "struct VerifiedLevel",
"name": "level",
"type": "tuple"
}
],
"name": "setLevel",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ISchemaRegistry",
"name": "newSchemaRegistry",
"type": "address"
}
],
"name": "setSchemaRegistry",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_verifierModuleAddress",
"type": "address"
}
],
"name": "setVerifierModule",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "schema",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint64",
"name": "expirationTime",
"type": "uint64"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "bytes32",
"name": "refUID",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"internalType": "struct AttestationRequestData",
"name": "data",
"type": "tuple"
}
],
"internalType": "struct AttestationRequest",
"name": "request",
"type": "tuple"
},
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "assetClass",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "payer",
"type": "address"
}
],
"name": "sponsoredAttest",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "address",
"name": "signer",
"type": "address"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"internalType": "struct SignatureUtils.SignatureParams",
"name": "delegatedSignature",
"type": "tuple"
},
{
"components": [
{
"internalType": "bytes32",
"name": "schema",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint64",
"name": "expirationTime",
"type": "uint64"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "bytes32",
"name": "refUID",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"internalType": "struct AttestationRequestData",
"name": "data",
"type": "tuple"
}
],
"internalType": "struct AttestationRequest",
"name": "request",
"type": "tuple"
},
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "assetClass",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "attester",
"type": "address"
},
{
"internalType": "address",
"name": "payer",
"type": "address"
}
],
"name": "sponsoredDelegatedAttest",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "levelValue",
"type": "uint256"
},
{
"components": [
{
"internalType": "bool",
"name": "active",
"type": "bool"
},
{
"internalType": "uint256",
"name": "minTokensLocked",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minVerifiers",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minCouncilVerifiers",
"type": "uint256"
}
],
"internalType": "struct VerifiedLevel",
"name": "level",
"type": "tuple"
}
],
"name": "updateLevel",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newImplementation",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "upgradeToAndCall",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "verifierModuleAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "bondedAmount",
"type": "uint256"
}
],
"name": "verifyAttestation",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "withdrawBondToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
];
var SchemaRegistryAbi = [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyExists",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "registerer",
"type": "address"
},
{
"components": [
{
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "string",
"name": "schema",
"type": "string"
}
],
"indexed": false,
"internalType": "struct SchemaRecord",
"name": "schema",
"type": "tuple"
}
],
"name": "Registered",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
}
],
"name": "getSchema",
"outputs": [
{
"components": [
{
"internalType": "bytes32",
"name": "uid",
"type": "bytes32"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
},
{
"internalType": "string",
"name": "schema",
"type": "string"
}
],
"internalType": "struct SchemaRecord",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "schema",
"type": "string"
},
{
"internalType": "bool",
"name": "revocable",
"type": "bool"
}
],
"name": "register",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
];
var SignatureUtilsAbi = [
{
"inputs": [],
"name": "_DELEGATEDSELFATTEST_TYPEHASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
}
];
var CulturaRightAbi = [
{
"inputs": [
{
"internalType": "address",
"name": "defaultAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "minter",
"type": "address"
},
{
"internalType": "address",
"name": "culturaTreasuryAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "culturaTreasurySplit",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AccessControlBadConfirmation",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bytes32",
"name": "neededRole",
"type": "bytes32"
}
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "ERC721EnumerableForbiddenBatchMint",
"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": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "ERC721OutOfBoundsIndex",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "parentOwner",
"type": "address"
}
],
"name": "ParentOwnerMustBeRightsBoundAccount",
"type": "error"
},
{
"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": false,
"internalType": "uint256",
"name": "_fromTokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_toTokenId",
"type": "uint256"
}
],
"name": "BatchMetadataUpdate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "minter",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": false,
"internalType": "string",
"name": "digitalAssetName",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "digitalAssetDescription",
"type": "string"
},
{
"components": [
{
"internalType": "address",
"name": "rightsBoundAccount",
"type": "address"
},
{
"internalType": "uint256",
"name": "royaltySplit",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct ILicensed_ERC.ParentInfo[]",
"name": "parentInfo",
"type": "tuple[]"
},
{
"indexed": false,
"internalType": "string",
"name": "termsURI",
"type": "string"
},
{
"indexed": false,
"internalType": "bool",
"name": "isLicensed",
"type": "bool"
}
],
"name": "LicenseTokenMinted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "_tokenId",
"type": "uint256"
}
],
"name": "MetadataUpdate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"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"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MINTER_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"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": [],
"name": "culturaTreasury",
"outputs": [
{
"internalType": "address",
"name": "treasury",
"type": "address"
},
{
"internalType": "uint256",
"name": "treasurySplit",
"type": "uint256"
}
],
"stateMutability": "view",
"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": "getLicenseInfo",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "digitalAssetName",
"type": "string"
},
{
"internalType": "string",
"name": "digitalAssetDescription",
"type": "string"
},
{
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"components": [
{
"internalType": "address",
"name": "rightsBoundAccount",
"type": "address"
},
{
"internalType": "uint256",
"name": "royaltySplit",
"type": "uint256"
}
],
"internalType": "struct ILicensed_ERC.ParentInfo[]",
"name": "parentInfo",
"type": "tuple[]"
},
{
"internalType": "string",
"name": "termsURI",
"type": "string"
},
{
"internalType": "bool",
"name": "isLicensed",
"type": "bool"
}
],
"internalType": "struct ILicensed_ERC.LicenseInfo",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
}
],
"name": "getRoleAdmin",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "hasRole",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"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": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "string",
"name": "digitalAssetName",
"type": "string"
},
{
"internalType": "string",
"name": "digitalAssetDescription",
"type": "string"
},
{
"components": [
{
"internalType": "address",
"name": "rightsBoundAccount",
"type": "address"
},
{
"internalType": "uint256",
"name": "royaltySplit",
"type": "uint256"
}
],
"internalType": "struct ILicensed_ERC.ParentInfo[]",
"name": "parentInfo",
"type": "tuple[]"
},
{
"internalType": "string",
"name": "termsURI",
"type": "string"
},
{
"internalType": "string",
"name": "culturaDigitalAssetTokenURI",
"type": "string"
}
],
"name": "safeMint",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"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": "index",
"type": "uint256"
}
],
"name": "tokenByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenOfOwnerByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"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"
}
];
var CulturaRightsBoundAccountAbi = [
{
"inputs": [
{
"internalType": "address",
"name": "_rightsContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "_rightsId",
"type": "uint256"
},
{
"internalType": "address",
"name": "_tokenAddress",
"type": "address"
},
{
"internalType": "address",
"name": "_culturaTreasury",
"type": "address"
},
{
"internalType": "address",
"name": "_verifierModule",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "childAccount",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ChildTransferFailed",
"type": "error"
},
{
"inputs": [],
"name": "ECDSAInvalidSignature",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "length",
"type": "uint256"
}
],
"name": "ECDSAInvalidSignatureLength",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "ECDSAInvalidSignatureS",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientParentSplitTotal",
"type": "error"
},
{
"inputs": [],
"name": "InvalidParentSplitTotal",
"type": "error"
},
{
"inputs": [],
"name": "InvalidShortString",
"type": "error"
},
{
"inputs": [
{
"internalType": "string",
"name": "reason",
"type": "string"
}
],
"name": "InvalidSignature",
"type": "error"
},
{
"inputs": [],
"name": "NoParentsFound",
"type": "error"
},
{
"inputs": [],
"name": "NoPaymentInfoForPeriod",
"type": "error"
},
{
"inputs": [],
"name": "NotRightsHolder",
"type": "error"
},
{
"inputs": [],
"name": "NothingToClaim",
"type": "error"
},
{
"inputs": [],
"name": "OnlyVerifierModuleCanCall",
"type": "error"
},
{
"inputs": [],
"name": "PaymentInfoAlreadySet",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"inputs": [
{
"internalType": "string",
"name": "str",
"type": "string"
}
],
"name": "StringTooLong",
"type": "error"
},
{
"inputs": [],
"name": "VerifierModuleNotEnabled",
"type": "error"
},
{
"inputs": [],
"name": "VerifiersShouldClaimThroughModule",
"type": "error"
},
{
"inputs": [
{
"internalType": "string",
"name": "paramName",
"type": "string"
}
],
"name": "ZeroAddressNotAllowed",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "period",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "beneficiary",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "Claimed",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "period",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address[]",
"name": "beneficiaries",
"type": "address[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256",
"name": "totalAmount",
"type": "uint256"
}
],
"name": "PaymentInfoSet",
"type": "event"
},
{
"inputs": [],
"name": "CULTURA_PERCENTAGE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PARENTS_PERCENTAGE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PAYMENT_INFO_TYPEHASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PERCENTAGE_BASE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VERIFIER_PERCENTAGE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "period",
"type": "uint256"
}
],
"name": "claim",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "period",
"type": "uint256"
}
],
"name": "claimForVerifierModule",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "childBoundAccount",
"type": "address"
},
{
"internalType": "uint256",
"name": "period",
"type": "uint256"
}
],
"name": "claimFromChild",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "culturaTreasury",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentPeriod",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{
"internalType": "bytes1",
"name": "fields",
"type": "bytes1"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256[]",
"name": "extensions",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "period",
"type": "uint256"
},
{
"internalType": "address",
"name": "beneficiary",
"type": "address"
}
],
"name": "getPaymentAmount",
"outputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "paymentInfos",
"outputs": [
{
"internalType": "uint256",
"name": "totalAmount",
"type": "uint256"
},
{
"internalType": "bool",
"name": "exists",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "totalAmount",
"type": "uint256"
}
],
"name": "previewSplits",
"outputs": [
{
"internalType": "address[]",
"name": "parentAddresses",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "parentAmounts",
"type": "uint256[]"
},
{
"internalType": "uint256",
"name": "culturaAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "verifierAmount",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "rightsContract",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "rightsId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "totalAmount",
"type": "uint256"
},
{
"internalType": "address",
"name": "sponsor",
"type": "address"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "address",
"name": "signer",
"type": "address"
}
],
"internalType": "struct ICulturaRightsBoundAccount.PaymentInput",
"name": "input",
"type": "tuple"
}
],
"name": "setPaymentInfo",
"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": "tokenAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "period",
"type": "uint256"
}
],
"name": "transferToParent",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "useVerifierModule",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "verifierModule",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
];
var BondTokenAbi = [
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientAllowance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientBalance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "approver",
"type": "address"
}
],
"name": "ERC20InvalidApprover",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "ERC20InvalidReceiver",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "ERC20InvalidSender",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "ERC20InvalidSpender",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
];
var CRSAbi = [
{
"inputs": [
{
"internalType": "address",
"name": "_culturaDigitalAssetAddress",
"type": "address"
},
{
"internalType": "address",
"name": "_culturaPaymentTokenAddress",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AmountPaidExceedsDue",
"type": "error"
},
{
"inputs": [],
"name": "ECDSAInvalidSignature",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "length",
"type": "uint256"
}
],
"name": "ECDSAInvalidSignatureLength",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "ECDSAInvalidSignatureS",
"type": "error"
},
{
"inputs": [
{
"internalType": "enum ICRS.OffChainPaymentStatus",
"name": "currentStatus",
"type": "uint8"
},
{
"internalType": "enum ICRS.OffChainPaymentStatus",
"name": "requiredStatus",
"type": "uint8"
}
],
"name": "IncorrectOffChainPaymentStatus",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "required",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "allowed",
"type": "uint256"
}
],
"name": "InsufficientAllowanceForFees",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "required",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "available",
"type": "uint256"
}
],
"name": "InsufficientBalanceForFees",
"type": "error"
},
{
"inputs": [],
"name": "InvalidAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidCulturaBoundAccount",
"type": "error"
},
{
"inputs": [],
"name": "InvalidDateRange",
"type": "error"
},
{
"inputs": [],
"name": "InvalidFeeCalculation",
"type": "error"
},
{
"inputs": [],
"name": "InvalidParentBoundAccount",
"type": "error"
},
{
"inputs": [],
"name": "InvalidPeriodIndex",
"type": "error"
},
{
"inputs": [],
"name": "InvalidShortString",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSignature",
"type": "error"
},
{
"inputs": [],
"name": "NoParentDigitalAssetToPay",
"type": "error"
},
{
"inputs": [],
"name": "NoRoyaltyDue",
"type": "error"
},
{
"inputs": [],
"name": "NotCreatorOfVR",
"type": "error"
},
{
"inputs": [],
"name": "NotOwnerOfParentVR",
"type": "error"
},
{
"inputs": [],
"name": "NotParentBoundAccountOwner",
"type": "error"
},
{
"inputs": [],
"name": "NotVROwner",
"type": "error"
},
{
"inputs": [],
"name": "OffChainPaymentAlreadyExists",
"type": "error"
},
{
"inputs": [],
"name": "ParentAlreadyResponded",
"type": "error"
},
{
"inputs": [],
"name": "ParentNotFound",
"type": "error"
},
{
"inputs": [],
"name": "RoyaltyInfoAlreadyExists",
"type": "error"
},
{
"inputs": [],
"name": "RoyaltyInfoIndexOutOfBounds",
"type": "error"
},
{
"inputs": [],
"name": "RoyaltyPeriodNotFound",
"type": "error"
},
{
"inputs": [
{
"internalType": "string",
"name": "str",
"type": "string"
}
],
"name": "StringTooLong",
"type": "error"
},
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "acceptor",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "acceptedAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "OffChainPaymentAccepted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "parentBoundAccount",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "acceptedAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "OffChainPaymentAcceptedByParent",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "denier",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "OffChainPaymentDenied",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "parentBoundAccount",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "OffChainPaymentDeniedByParent",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "reporter",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "reportedAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "string",
"name": "metadata",
"type": "string"
}
],
"name": "OffChainPaymentReported",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "startDate",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "endDate",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amountDue",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
}
],
"name": "RoyaltyDueRegistered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "payer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "periodStart",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "periodEnd",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amountPaid",
"type": "uint256"
}
],
"name": "RoyaltyPaid",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "parentBoundAccount",
"type": "address"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "address",
"name": "signer",
"type": "address"
},
{
"internalType": "address",
"name": "sponsor",
"type": "address"
}
],
"name": "acceptOffChainPaymentByParent",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "culturaDigitalAssetAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "culturaPaymentTokenAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountPaid",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "culturaBoundAccount",
"type": "address"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "delegatedSignature",
"type": "bytes"
}
],
"name": "delegatedPayRoyalty",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountDue",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "startDate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "endDate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "royaltyInfoIndex",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "delegatedRegisterRoyaltyDue",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "string",
"name": "metadata",
"type": "string"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "delegatedReportOffChainPayment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "parentBoundAccount",
"type": "address"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "address",
"name": "signer",
"type": "address"
}
],
"name": "denyOffChainPaymentByParent",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{
"internalType": "bytes1",
"name": "fields",
"type": "bytes1"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256[]",
"name": "extensions",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getFullRoyaltyInfo",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "periodStart",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodEnd",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountDue",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountPaid",
"type": "uint256"
}
],
"internalType": "struct ICRS.RoyaltyInfoView[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "parentBoundAccount",
"type": "address"
}
],
"name": "getParentAcceptanceInfo",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "allocatedAmount",
"type": "uint256"
},
{
"internalType": "enum ICRS.OffChainPaymentStatus",
"name": "status",
"type": "uint8"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"internalType": "struct ICRS.ParentAcceptanceInfo",
"name": "acceptanceInfo",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getRoyaltyInfoCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
}
],
"name": "getRoyaltyInfoPeriod",
"outputs": [
{
"internalType": "uint256",
"name": "periodStart",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodEnd",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountDue",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountPaid",
"type": "uint256"
},
{
"internalType": "uint256[]",
"name": "parentPendingClaims",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
}
],
"name": "offChainPayments",
"outputs": [
{
"internalType": "uint256",
"name": "reportedAmount",
"type": "uint256"
},
{
"internalType": "string",
"name": "metadata",
"type": "string"
},
{
"internalType": "address",
"name": "reporter",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountPaid",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "address",
"name": "culturaBoundAccount",
"type": "address"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
}
],
"name": "payRoyalty",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountDue",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "startDate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "endDate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "royaltyInfoIndex",
"type": "uint256"
}
],
"name": "registerRoyaltyDue",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "periodIndex",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "string",
"name": "metadata",
"type": "string"
}
],
"name": "reportOffChainPayment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
];
var VerifierModuleAbi = [
{
"inputs": [
{
"internalType": "address",
"name": "_paymentToken",
"type": "address"
},
{
"internalType": "address",
"name": "_casAddress",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "NoRewardsToClaim",
"type": "error"
},
{
"inputs": [],
"name": "NoRewardsToDistribute",
"type": "error"
},
{
"inputs": [],
"name": "NoVerifiersRegisteredForVR",
"type": "error"
},
{
"inputs": [],
"name": "NotAnVerifierForVR",
"type": "error"
},
{
"inputs": [],
"name": "OnlyCASCanRegisterVerifiers",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"inputs": [],
"name": "TokenTransferFailed",
"type": "error"
},
{
"inputs": [
{
"internalType": "string",
"name": "paramName",
"type": "string"
}
],
"name": "ZeroAddress",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "vrId",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "verifier",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RewardsClaimed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "vrId",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "boundAccount",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "period",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RewardsDistributed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "vrId",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "RewardsReceived",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "vrId",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "verifier",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bondedAmount",
"type": "uint256"
}
],
"name": "VerifierRegistered",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifier",
"type": "address"
}
],
"name": "calculateClaimableRewards",
"outputs": [
{
"internalType": "uint256",
"name": "claimableAmount",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "casAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
}
],
"name": "claimRewards",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "claimedRewards",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "address",
"name": "boundAccount",
"type": "address"
},
{
"internalType": "uint256",
"name": "period",
"type": "uint256"
}
],
"name": "distributeRewards",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
}
],
"name": "getTotalBondedAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifier",
"type": "address"
}
],
"name": "getVerifierBond",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "paymentToken",
"outputs": [
{
"internalType": "contract IERC20",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "receiveFees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "digitalAssetAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "digitalAssetId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifier",
"type": "address"
},
{
"internalType": "uint256",
"name": "bondedAmount",
"type": "uint256"
}
],
"name": "registerVerifierBond",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "totalBondedAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "verifierBonds",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "vrRewards",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
];
var MockLicensingAttestationAbi = [
{
"inputs": [
{
"internalType": "address",
"name": "_collectionAddress",
"type": "address"
},
{
"internalType": "address",
"name": "_paymentTokenAddress",
"type": "address"
},
{
"internalType": "address",
"name": "_licensingAttestationFunctions",
"type": "address"
},
{
"internalType": "address",
"name": "_cas",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "cas",
"outputs": [
{
"internalType": "contract ICAS",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "collectionAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "licensedCollectionAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "fakeLicenseIp",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "licensedTokens",
"outputs": [
{
"internalType": "address",
"name": "collectionAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "licensingAttestationFunctions",
"outputs": [
{
"internalType": "contract ILicensingAttestationMock",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "paymentTokenAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "bondedAmount",
"type": "uint256"
}
],
"name": "verifyLicensedAsset",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
];
var POPAbi = [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
}
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [],
"name": "AttestationDoesNotExist",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "ERC1967InvalidImplementation",
"type": "error"
},
{
"inputs": [],
"name": "ERC1967NonPayable",
"type": "error"
},
{
"inputs": [],
"name": "ExceedsMaxVotePerUser",
"type": "error"
},
{
"inputs": [],
"name": "FailedCall",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientVotedAmount",
"type": "error"
},
{
"inputs": [],
"name": "InvalidAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidInitialization",
"type": "error"
},
{
"inputs": [],
"name": "NoTokensToWithdraw",
"type": "error"
},
{
"inputs": [],
"name": "NotInitializing",
"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": "TokensStillLocked",
"type": "error"
},
{
"inputs": [],
"name": "TransferFailed",
"type": "error"
},
{
"inputs": [],
"name": "UUPSUnauthorizedCallContext",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "slot",
"type": "bytes32"
}
],
"name": "UUPSUnsupportedProxiableUUID",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"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": true,
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TokensVoted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TokensWithdrawn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32[3]",
"name": "topAttestations",
"type": "bytes32[3]"
},
{
"indexed": false,
"internalType": "uint256[3]",
"name": "topScores",
"type": "uint256[3]"
}
],
"name": "TopAttestationsUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Upgraded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "unlockTime",
"type": "uint256"
}
],
"name": "WithdrawalRequested",
"type": "event"
},
{
"inputs": [],
"name": "UPGRADE_INTERFACE_VERSION",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "WITHDRAW_TIMELOCK",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "casAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
}
],
"name": "getPopularityScore",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "count",
"type": "uint256"
}
],
"name": "getTopAttestations",
"outputs": [
{
"internalType": "bytes32[]",
"name": "",
"type": "bytes32[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getTopAttestationsWithScores",
"outputs": [
{
"internalType": "bytes32[3]",
"name": "attestations",
"type": "bytes32[3]"
},
{
"internalType": "uint256[3]",
"name": "scores",
"type": "uint256[3]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
}
],
"name": "getTotalVotedAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "getUnlockTime",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "getUserVotedAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "initialOwner",
"type": "address"
},
{
"internalType": "address",
"name": "voteToken",
"type": "address"
},
{
"internalType": "address",
"name": "_casAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "_maxVotePerUser",
"type": "uint256"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "maxVotePerUser",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "popularityScore",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "proxiableUUID",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "requestVoteWithdrawal",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_casAddress",
"type": "address"
}
],
"name": "setCASAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_maxVotePerUser",
"type": "uint256"
}
],
"name": "setMaxVotePerUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "totalVotedAmount",
"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": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "unlockTime",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newImplementation",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "upgradeToAndCall",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "userVotedAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "voteOnAttestation",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "withdrawVoteToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "attestationUID",
"type": "bytes32"
}
],
"name": "withdrawVotes",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
];
// src/resources/attestationService.ts
var import_viem3 = require("viem");
// src/utils/index.ts
var utils_exports = {};
__export(utils_exports, {
CHAIN_IDS: () => CHAIN_IDS,
CHAIN_NAMES: () => CHAIN_NAMES,
getChainId: () => getChainId,
getChainName: () => getChainName,
getDigitalAssetUID: () => getDigitalAssetUID,
getVerifiedRightsId: () => getVerifiedRightsId,
uploadFileToIpfs: () => uploadFileToIpfs,
uploadMetadataToIpfs: () => uploadMetadataToIpfs
});
// src/utils/ipfs.ts
var IPFS_PROJECT_ID = "fa82b4891e1949f1bada6fc0631fe474";
var IPFS_SECRET = "yNgMagDB1d4paoR5SWUe2jfvqgMr2P07qVfGDk2f1TNx4RF2GDjrMg";
var IPFS_GATEWAY = "https://spaceport-dev.infura-ipfs.io";
var IPFS_API = "https://spaceport-dev.infura-ipfs.io:5001";
function toBase64(val) {
if (typeof Buffer !== "undefined" && typeof Buffer.from === "function") {
return Buffer.from(val).toString("base64");
} else if (typeof btoa === "function") {
return btoa(val);
} else {
throw new Error("Base64 encoding not supported in this environment.");
}
}
async function uploadFileToIpfs(file) {
const body = new FormData();
body.set("file", file);
const stringToEncode = `${IPFS_PROJECT_ID}:${IPFS_SECRET}`;
const base64Credentials = toBase64(stringToEncode);
const authorization = `Basic ${base64Credentials}`;
const response = await fetch(`${IPFS_API}/api/v0/add`, {
method: "POST",
body,
headers: { authorization }
});
const ipfs = await response.json();
return `${IPFS_GATEWAY}/ipfs/${ipfs.Hash}`;
}
async function uploadMetadataToIpfs(metadata) {
const body = new FormData();
const blob = new Blob([JSON.stringify(metadata)], { type: "application/json" });
body.set("file", blob);
const stringToEncode = `${IPFS_PROJECT_ID}:${IPFS_SECRET}`;
const base64Credentials = toBase64(stringToEncode);
const authorization = `Basic ${base64Credentials}`;
const response = await fetch(`${IPFS_API}/api/v0/add`, {
method: "POST",
body,
headers: { authorization }
});
const ipfs = await response.json();
return `${IPFS_GATEWAY}/ipfs/${ipfs.Hash}`;
}
// src/utils/chain.ts
var CHAIN_IDS = {
local: ENVIRONMENTS.local.chainId,
devnet: ENVIRONMENTS.devnet.chainId,
testnet: ENVIRONMENTS.testnet.chainId
};
var CHAIN_NAMES = Object.entries(CHAIN_IDS).reduce(
(acc, [name, id]) => ({
...acc,
[id]: name
}),
{}
);
function getChainId(chainName) {
if (typeof chainName === "number") {
if (!CHAIN_NAMES[chainName]) {
throw new Error(
`Unsupported chain ID: ${chainName}. Supported chains: ${Object.values(CHAIN_IDS).join(", ")}`
);
}
return chainName;
}
const chainId = CHAIN_IDS[chainName];
if (!chainId) {
throw new Error(
`Unsupported chain name: ${chainName}. Supported chains: ${Object.keys(CHAIN_IDS).join(", ")}`
);
}
return chainId;
}
function getChainName(chainId) {
const chainName = CHAIN_NAMES[chainId];
if (!chainName) {
throw new Error(
`Unsupported chain ID: ${chainId}. Supported chains: ${Object.values(CHAIN_IDS).join(", ")}`
);
}
return chainName;
}
// src/utils/uid.ts
var import_viem = require("viem");
function getDigitalAssetUID(digitalAssetAddress, digitalAssetId) {
return (0, import_viem.keccak256)(
(0, import_viem.encodeAbiParameters)((0, import_viem.parseAbiParameters)("address, uint256"), [
digitalAssetAddress,
digitalAssetId
])
);
}
function getVerifiedRightsId(digitalAssetAddress, digitalAssetId) {
return getDigitalAssetUID(digitalAssetAddress, digitalAssetId);
}
// src/resources/attestationService.ts
var AttestationServiceClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
/**
* Create an attestation for a digital asset
*
* @param attestationRequest - Object containing attestation details
* @param digitalAssetAddress - Address of the digital asset token contract
* @param digitalAssetId - Token ID of the digital asset being attested
* @param assetClass - Asset class ID for the attestation (affects fees and requirements)
* @param bondAmount - Amount of tokens to bond for the attestation
*
* @returns An object containing the unique identifier (UID) of the created attestation and the address of the deployed Rights Bound Account.
*
* @example
* ```typescript
* const attestationRequest = {
* schema: schemaHash,
* data: {
* recipient: userAddress,
* expirationTime: BigInt(Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60),
* revocable: true,
* refUID: "0x0000000000000000000000000000000000000000000000000000000000000000",
* data: "0x"
* }
* }
*
* const attestationData = await sdk.attestationService.attest(
* attestationRequest,
* tokenAddress,
* tokenId,
* assetClass,
* bondAmount
* );
* ```
*/
async attest(attestationRequest, digitalAssetAddress, digitalAssetId, assetClass, bondAmount) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (!(0, import_viem2.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
if (digitalAssetAddress === import_viem2.zeroAddress) {
throw new Error("Digital asset address cannot be zero address");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "attest",
args: [attestationRequest, digitalAssetAddress, digitalAssetId, assetClass, bondAmount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return this.getAttestationDataFromReceipt(receipt);
}
/**
* Create a sponsored attestation for a digital asset paid by a third party
*
* @param attestationRequest - Object containing attestation details
* @param digitalAssetAddress - Address of the digital asset token contract
* @param digitalAssetId - Token ID of the digital asset being attested
* @param assetClass - Asset class ID for the attestation (affects fees and requirements)
* @param bondAmount - Amount of tokens to bond for the attestation
* @param payer - Address of the sponsor/payer
*
* @returns An object containing the unique identifier (UID) of the created attestation and the address of the deployed Rights Bound Account.
*
* @example
* ```typescript
* const attestationRequest = {
* schema: schemaHash,
* data: {
* recipient: userAddress,
* expirationTime: BigInt(Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60),
* revocable: true,
* refUID: "0x0000000000000000000000000000000000000000000000000000000000000000",
* data: "0x"
* }
* }
*
* const attestationData = await sdk.attestationService.sponsoredAttest(
* attestationRequest,
* tokenAddress,
* tokenId,
* assetClass,
* bondAmount,
* payer
* );
* ```
*/
async sponsoredAttest(attestationRequest, digitalAssetAddress, digitalAssetId, assetClass, bondAmount, payer) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (!(0, import_viem2.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
if (digitalAssetAddress === import_viem2.zeroAddress) {
throw new Error("Digital asset address cannot be zero address");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "sponsoredAttest",
args: [
attestationRequest,
digitalAssetAddress,
digitalAssetId,
assetClass,
bondAmount,
payer
],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return this.getAttestationDataFromReceipt(receipt);
}
/**
* Create a delegated attestation
*
* This method allows a user to create an attestation on behalf of another account,
* using a signature from that account for authorization.
*
* @param signatureParams - Parameters for the signature verification
* @param attestationRequest - Object containing attestation details
* @param digitalAssetAddress - Address of the digital asset token contract
* @param digitalAssetId - Token ID of the digital asset being attested
* @param assetClass - Asset class ID for the attestation (affects fees and requirements)
* @param bondAmount - Amount of tokens to bond for the attestation
* @param delegatedAddress - Address that will perform the attestation on behalf of the signer
* @returns An object containing the unique identifier (UID) of the created attestation and the address of the deployed Rights Bound Account.
*/
async delegatedAttest(signatureParams, attestationRequest, digitalAssetAddress, digitalAssetId, assetClass, bondAmount, delegatedAddress) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (!(0, import_viem2.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
if (digitalAssetAddress === import_viem2.zeroAddress) {
throw new Error("Digital asset address cannot be zero address");
}
if (!(0, import_viem2.isAddress)(delegatedAddress)) {
throw new Error("Invalid delegated address format");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "delegatedAttest",
args: [
signatureParams,
attestationRequest,
digitalAssetAddress,
digitalAssetId,
assetClass,
bondAmount,
delegatedAddress
],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return this.getAttestationDataFromReceipt(receipt);
}
/**
* Create a delegated attestation
*
* This method allows a user to create an attestation on behalf of another account,
* using a signature from that account for authorization.
*
* @param signatureParams - Parameters for the signature verification
* @param attestationRequest - Object containing attestation details
* @param digitalAssetAddress - Address of the digital asset token contract
* @param digitalAssetId - Token ID of the digital asset being attested
* @param assetClass - Asset class ID for the attestation (affects fees and requirements)
* @param bondAmount - Amount of tokens to bond for the attestation
* @param delegatedAddress - Address that will perform the attestation on behalf of the signer
* @returns An object containing the unique identifier (UID) of the created attestation and the address of the deployed Rights Bound Account.
*/
async sponsoredDelegatedAttest(signatureParams, attestationRequest, digitalAssetAddress, digitalAssetId, assetClass, bondAmount, delegatedAddress, payer) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (!(0, import_viem2.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
if (digitalAssetAddress === import_viem2.zeroAddress) {
throw new Error("Digital asset address cannot be zero address");
}
if (!(0, import_viem2.isAddress)(payer)) {
throw new Error("Invalid payer address format");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "sponsoredDelegatedAttest",
args: [
signatureParams,
attestationRequest,
digitalAssetAddress,
digitalAssetId,
assetClass,
bondAmount,
delegatedAddress,
payer
],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return this.getAttestationDataFromReceipt(receipt);
}
/**
* Verify an attestation by bonding tokens
*
* This method allows a verifier to stake tokens against an attestation,
* supporting its validity. Verifiers receive rewards for accurate verifications.
*
* A digital asset can achieve Verified Rights status when it meets either of these thresholds:
* 1. Total bonded tokens reach the level requirement
* 2. Number of unique verifiers reaches the minimum threshold
*
* @param attestationUID - Unique identifier of the attestation to verify
* @param bondAmount - Amount of tokens to bond for the verification
* @returns Transaction hash of the verification transaction
*
* @remarks
* Important notes about the Verified Rights promotion process:
* - Only one endorsement per address is counted towards the verifier threshold
* - Endorsement amounts are cumulative for the token threshold
* - Once Verified Rights level 2 is achieved, the digital asset can be used in licensing and other trust-dependent transactions
* - Professional verifiers' endorsements may carry additional weight in the verification process
* - The level system reflects the trust and verification achieved by the digital asset
*
* @example
* ```typescript
* const txHash = await attestationService.verifyAttestation(
* attestationUID,
* ethers.utils.parseEther("10")
* );
* ```
*/
async verifyAttestation(attestationUID, bondAmount) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (bondAmount <= 0n) {
throw new Error("Bond amount must be greater than 0");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "verifyAttestation",
args: [attestationUID, bondAmount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction reverted");
}
return hash;
}
/**
* Check if an address is a whitelisted verifier
* @param address The address to check
* @returns True if the address is a whitelisted verifier, false otherwise
*/
async isWhitelistedVerifier(address) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "isWLVerifier",
args: [address]
});
}
/**
* Add a new whitelisted verifier
* @param verifierAddress The address to add as a whitelisted verifier
* @returns The transaction hash
*/
async addWhitelistVerifier(verifierAddress) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (!(0, import_viem2.isAddress)(verifierAddress)) {
throw new Error("Invalid address format");
}
if (verifierAddress === import_viem2.zeroAddress) {
throw new Error("Verifier address cannot be zero address");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "addWLVerifier",
args: [verifierAddress],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction reverted");
}
return hash;
}
/**
* Check if an address is the owner of the contract
* @param address The address to check
* @returns True if the address is the owner, false otherwise
*/
async isOwner(address) {
try {
const owner = await this.publicClient.readContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "owner"
});
return owner.toLowerCase() === address.toLowerCase();
} catch (error) {
console.error("Error checking owner:", error);
return false;
}
}
/**
* Get the current nonce for an address
* @param address The address to get the nonce for
* @returns The current nonce as a bigint
*/
async getNonce(address) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "getNonce",
args: [address]
});
}
/**
* Gets the current classId of a digital asset.
*
* The classId is selected by the digital asset minter during attestation and determines
* both the initial bond requirement and the thresholds for verified rights promotion.
*
* @param digitalAssetAddress - Address of the digital asset contract
* @param digitalAssetId - Token ID of the digital asset to check
*
* @remarks
* The classId cannot be changed after attestation and determines the requirements for verified rights level.
* Currently, there is one asset class defined, with each class having its own specific requirements
* for initial bonds, verification thresholds, and trust factors in the verification process.
*
* @group Attestation Service
*/
async getDigitalAssetClassId(digitalAssetAddress, digitalAssetId) {
const uid = getDigitalAssetUID(digitalAssetAddress, digitalAssetId);
const classId = await this.publicClient.readContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "digitalAssetClasses",
args: [uid]
});
return Number(classId);
}
/**
* Get the level of a digital asset
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @returns The level of the digital asset (0 = unverified, 1 = basic, 2 = verified/licensable)
*
* @remarks
* The level system represents the verification status of a digital asset:
* - Level 0: Just minted - Initial state of any newly minted digital asset
* - Level 1: Attested - Digital asset creator has completed attestation, initial bond and fee paid
* - Level 2: Verified Rights - Achieved through community endorsements, meets token threshold or unique verifiers requirement
*
* Important Notes:
* - All digital assets, regardless of classId, can achieve Verified Rights status
* - Verified Rights level 2 is required for licensing and other trust-dependent operations
* - Level status is independent of the digital asset's classId
*
* @example
* ```typescript
* const level = await sdk.attestationService.getDigitalAssetLevel(digitalAssetAddress, tokenId);
* console.log('Digital Asset Level Status:',
* level === 0 ? 'Just Minted' :
* level === 1 ? 'Attested' :
* level === 2 ? 'Verified Rights (Licensable)' : 'Unknown'
* );
* ```
*/
async getDigitalAssetLevel(digitalAssetAddress, digitalAssetId) {
const digitalAssetUID = getDigitalAssetUID(digitalAssetAddress, digitalAssetId);
const level = await this.publicClient.readContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "digitalAssetLevels",
args: [digitalAssetUID]
});
return Number(level);
}
/**
* Remove a whitelisted verifier
* @param verifierAddress The address to remove from the whitelist
* @returns The transaction hash
*/
async removeWhitelistedVerifier(verifierAddress) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
if (!(0, import_viem2.isAddress)(verifierAddress)) {
throw new Error("Invalid address format");
}
if (verifierAddress === import_viem2.zeroAddress) {
throw new Error("Verifier address cannot be zero address");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "removeWLVerifier",
args: [verifierAddress],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction reverted");
}
return hash;
}
/**
* Retrieves detailed information about an attestation by its unique identifier.
*
* Use this method to get complete information about a specific attestation,
* including the recipient, verifier, schema reference, and associated data.
*
* @param uid - Unique identifier of the attestation to retrieve
*
* @returns Complete attestation data including recipient, verifier, schema, digital asset details, and bond amounts
*
* @example
* ```typescript
* const attestation = await sdk.attestationService.getAttestation(attestationUID);
* console.log('Attestation details:', attestation);
* ```
*
* @group Attestation Service
*/
async getAttestation(uid) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CASAbi,
functionName: "getAttestation",
args: [uid]
});
}
/**
* Extracts the rights bound account from a transaction receipt.
*
* @param receipt - The transaction receipt to extract the rights bound account from
* @returns The rights bound account address if found, zero address otherwise
*/
getRightsBoundAccountFromReceipt(receipt) {
const rightsBoundAccountEvent = receipt.logs.find((log) => {
try {
const event = (0, import_viem3.decodeEventLog)({
abi: CASAbi,
data: log.data,
topics: log.topics
});
return event.eventName === "CulturaRightsBoundAccountDeployed";
} catch {
return false;
}
});
let rightsBoundAccount = "0x0000000000000000000000000000000000000000";
if (rightsBoundAccountEvent) {
const decodedEvent = (0, import_viem3.decodeEventLog)({
abi: CASAbi,
data: rightsBoundAccountEvent.data,
topics: rightsBoundAccountEvent.topics
});
rightsBoundAccount = decodedEvent.args.rightsBoundAccount.rightsBoundAccount;
}
return rightsBoundAccount;
}
/**
* Extracts attestation data from a transaction receipt.
*
* @param receipt - The transaction receipt to extract the attestation data from
* @returns The attestation data including UID and rights bound account
* @throws Error if the attestation UID is not found in the logs
*/
getAttestationDataFromReceipt(receipt) {
const attestedEvent = receipt.logs.find((log) => {
try {
const event = (0, import_viem3.decodeEventLog)({
abi: CASAbi,
data: log.data,
topics: log.topics
});
return event.eventName === "Attested";
} catch {
return false;
}
});
if (!attestedEvent) {
throw new Error("Attestation UID not found in transaction logs");
}
const attestedEventData = (0, import_viem3.decodeEventLog)({
abi: CASAbi,
data: attestedEvent.data,
topics: attestedEvent.topics
});
const rightsBoundAccount = this.getRightsBoundAccountFromReceipt(receipt);
return {
attestationUid: attestedEventData.args.uid,
rightsBoundAccount
};
}
/**
* Generates signature parameters required for delegated attestation
*
* @param signature - The signed message signature
* @param signerAddress - The address of the signer
* @returns Signature parameters object with signature, signer, v, r, and s values
*/
generateSignatureParams(signature, signerAddress) {
const signatureBytes = (0, import_viem2.hexToBytes)(signature);
const r = (0, import_viem2.bytesToHex)(signatureBytes.slice(0, 32));
const s = (0, import_viem2.bytesToHex)(signatureBytes.slice(32, 64));
const v = signatureBytes[64];
return {
signature,
signer: signerAddress,
v,
r,
s
};
}
/**
* Signs a message for delegated attestation and returns the signature parameters
*
* @param account - The account performing the signature
* @returns Signature parameters object with signature, signer, v, r, and s values
*/
async signForDelegatedAttestation(account) {
if (!this.walletClient) {
throw new Error("Wallet client required for signing operations");
}
const nonce = await this.getNonce(account);
const signature = await this.walletClient.signTypedData({
account,
domain: {
name: "CulturaAttestationService",
version: "0.0.1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
DelegatedSelfAttest: [
{ name: "signer", type: "address" },
{ name: "nonce", type: "uint256" }
]
},
message: {
signer: account,
nonce
},
primaryType: "DelegatedSelfAttest"
});
return this.generateSignatureParams(signature, account);
}
/**
* Generates multiple signatures for delegated attestations in bulk.
* This is useful when you need to sign for several attestations upfront,
* as each signature will use an incrementing nonce starting from the signer's current nonce.
*
* @param account - The account performing the signatures.
* @param numberOfSignatures - The total number of signatures to generate.
* @returns A promise that resolves to an array of signature parameters objects.
* Each object contains the signature, signer, v, r, and s values.
* These signatures must be used in the order they are returned,
* as they correspond to sequential nonces.
* @throws Error if the wallet client is not available or if numberOfSignatures is not positive.
*/
async signForBulkDelegatedAttestations(account, numberOfSignatures) {
if (!this.walletClient) {
throw new Error("Wallet client required for signing operations");
}
if (numberOfSignatures <= 0) {
throw new Error("Number of signatures must be greater than 0");
}
const startingNonce = await this.getNonce(account);
const signatureParamsArray = [];
const domain = {
name: "CulturaAttestationService",
version: "0.0.1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
};
const types = {
DelegatedSelfAttest: [
{ name: "signer", type: "address" },
{ name: "nonce", type: "uint256" }
]
};
const primaryType = "DelegatedSelfAttest";
for (let i = 0; i < numberOfSignatures; i++) {
const nonceForSignature = startingNonce + BigInt(i);
const message = {
signer: account,
nonce: nonceForSignature
};
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain,
types,
message,
primaryType
});
signatureParamsArray.push(this.generateSignatureParams(signature, account));
}
return signatureParamsArray;
}
};
// src/resources/schemaRegistry.ts
var import_viem4 = require("viem");
var SchemaRegistryClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
/**
* Register a new schema
* @param schema The schema string to register
* @param revocable Whether attestations using this schema can be revoked
* @returns The schema UID (hash)
*/
async register(schema, revocable) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: SchemaRegistryAbi,
functionName: "register",
args: [schema, revocable],
account: this.walletClient.account
});
const txHash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash: txHash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${txHash}`);
}
return this.calculateSchemaHash(schema, revocable);
}
/**
* Get schema by UID
* @param uid The unique identifier (hash) of the schema
* @returns The schema data including the schema string and revocable flag
*/
async getSchema(uid) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: SchemaRegistryAbi,
functionName: "getSchema",
args: [uid]
});
}
/**
* Check if a schema is revocable
* @param uid The unique identifier (hash) of the schema
* @returns Boolean indicating if attestations using this schema can be revoked
*/
async isRevocable(uid) {
const schema = await this.getSchema(uid);
return schema.revocable;
}
/**
* Calculate schema hash using the same method as the contract
* @param schema The schema string
* @param revocable Whether the schema is revocable
* @returns The calculated schema hash
*/
calculateSchemaHash(schema, revocable) {
const encoded = (0, import_viem4.encodeAbiParameters)((0, import_viem4.parseAbiParameters)("string, bool"), [schema, revocable]);
return (0, import_viem4.keccak256)(encoded);
}
/**
* Register a new schema or get existing schema hash
* @param schema The schema string to register
* @param revocable Whether the schema is revocable
* @returns The schema hash
*
* @remarks
* This function is fundamental to the attestation process as it:
* 1. Defines the data structure for digital asset attestations
* 2. Ensures consistency in how digital asset data is stored and verified
* 3. Controls whether attestations can be revoked
*
* Schema Structure:
* The schema string follows Solidity's parameter encoding format and typically includes:
* - `digitalAssetName`: Name of the digital asset
* - `digitalAssetDescription`: Detailed description of the digital asset
* - `grade`: Numerical grade/rating of the digital asset
*
* @example
* ```typescript
* // Define a schema for digital asset attestations
* const schemaStr = 'string digitalAssetName, string digitalAssetDescription, uint256 grade';
* const isRevocable = true;
*
* // Register or get the schema
* const schemaHash = await sdk.schemaRegistry.getOrRegisterSchema(schemaStr, isRevocable);
* ```
*/
async getOrRegisterSchema(schema, revocable) {
try {
const schemaHash = await this.register(schema, revocable);
return schemaHash;
} catch (error) {
if (error?.cause?.data?.errorName === "AlreadyExists") {
const schemaHash = this.calculateSchemaHash(schema, revocable);
const existingSchema = await this.getSchema(schemaHash);
if (existingSchema.schema !== schema || existingSchema.revocable !== revocable) {
throw new Error("Schema hash collision detected");
}
return schemaHash;
}
throw error;
}
}
};
// src/resources/culturaDigitalAsset.ts
var import_viem5 = require("viem");
var CulturaDigitalAssetClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
//TODO fix issue with rpc method is not available with private key wallets and then can merge safeMint and mintDigitalAsset
/**
* Mints a new digital asset token with specified metadata (Script version using low-level transaction handling)
* @param to Address that will receive the minted token
* @param digitalAssetName Name of the digital asset
* @param digitalAssetDescription Description of the digital asset
* @param parentInfo Array of parent digital asset information for derivative works
* @param termsURI URI pointing to the detailed terms of the digital asset
* @param tokenURI Token URI for the ERC-721 metadata
* @returns The ID of the newly minted token
* @private
*/
async _safeMint(to, digitalAssetName, digitalAssetDescription, parentInfo, termsURI, tokenURI) {
if (!(0, import_viem5.isAddress)(to)) {
throw new Error("Invalid address format");
}
if (to === import_viem5.zeroAddress) {
throw new Error("Cannot mint to zero address");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const account = this.walletClient.account;
if (!account.address) {
throw new Error("Account address not found");
}
const data = (0, import_viem5.encodeFunctionData)({
abi: CulturaRightAbi,
functionName: "safeMint",
args: [
to,
digitalAssetName,
digitalAssetDescription,
parentInfo,
termsURI,
tokenURI
]
});
const nonce = await this.publicClient.getTransactionCount({
address: account.address
});
const gasPrice = await this.publicClient.getGasPrice();
const gas = await this.publicClient.estimateGas({
account: account.address,
to: this.contractAddress,
data,
value: 0n
});
const tx = {
account,
chain: this.walletClient.chain,
from: account.address,
to: this.contractAddress,
data,
nonce,
gasPrice,
gas,
chainId: this.walletClient.chain?.id
};
const signedTx = await this.walletClient.signTransaction(tx);
const hash = await this.walletClient.request({
method: "eth_sendRawTransaction",
params: [signedTx]
});
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
const transferEvent = receipt.logs.find(
(log) => log.topics[0] === "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
// Transfer(address,address,uint256)
);
if (!transferEvent || !transferEvent.topics[3])
throw new Error("Transfer event not found or invalid");
return BigInt(transferEvent.topics[3]);
}
/**
* Mints a new digital asset token with specified metadata (React version using high-level contract interaction)
* @param to Address that will receive the minted token
* @param digitalAssetName Name of the digital asset
* @param digitalAssetDescription Description of the digital asset
* @param parentInfo Array of parent digital asset information for derivative works
* @param terms Terms for the digital asset - can be a JSON object (to be uploaded to IPFS) or a string URI (pre-hosted)
* @param tokenURI Token URI for the ERC-721 metadata - can be a JSON object (to be uploaded to IPFS) or a string URI (pre-hosted)
* @returns The ID of the newly minted token
*
* @remarks
* This method mints a new digital asset token with licensing information. For derivative works,
* the parentInfo array should contain:
* - rightsBoundAccount: Address of parent digital asset collection (0x0 for original asset)
* - digitalAssetClass: Token ID of parent digital asset (0 for original asset)
* - royaltySplit: Percentage of royalties allocated to parent digital asset, expressed as a whole number (e.g., 10 for 10%).
*
* **Important:** The sum of `royaltySplit` values across all `parentInfo` must equal exactly 75.
* (Note: This 75% value is currently hardcoded in the contract and may change in future versions).
*/
async mintDigitalAsset(to, digitalAssetName, digitalAssetDescription, parentInfo, terms, tokenURI) {
if (!(0, import_viem5.isAddress)(to)) {
throw new Error("Invalid address format");
}
if (to === import_viem5.zeroAddress) {
throw new Error("Cannot mint to zero address");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const account = this.walletClient.account;
if (!account.address) {
throw new Error("Account address not found");
}
const termsUri = typeof terms === "string" ? terms : terms ? await uploadMetadataToIpfs(terms) : "";
const finalTokenUri = typeof tokenURI === "string" ? tokenURI : await uploadMetadataToIpfs(tokenURI);
if (account.source === "privateKey") {
return await this._safeMint(
to,
digitalAssetName,
digitalAssetDescription,
parentInfo,
termsUri,
finalTokenUri
);
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "safeMint",
args: [
to,
digitalAssetName,
digitalAssetDescription,
parentInfo,
termsUri,
finalTokenUri
],
account: account.address
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
const transferEvent = receipt.logs.find(
(log) => log.topics[0] === "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
// Transfer(address,address,uint256)
);
if (!transferEvent || !transferEvent.topics[3])
throw new Error("Transfer event not found or invalid");
return BigInt(transferEvent.topics[3]);
}
/**
* Gets the complete license information for a token
* @param tokenId The identifier of the token
* @returns Complete license information including name, description, creator, parent Digital Assets, and terms URI
*
* @remarks
* Returns a complete object containing:
* ```typescript
* {
* digitalAssetName: string
* digitalAssetDescription: string
* creator: address
* parentInfo: ParentInfo[]
* termsURI: string
* }
* ```
*/
async getLicenseInfo(tokenId) {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "getLicenseInfo",
args: [tokenId]
});
return result;
}
/**
* Get token owner
*/
async ownerOf(tokenId) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "ownerOf",
args: [tokenId]
});
}
/**
* Get token URI
*/
async tokenURI(tokenId) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "tokenURI",
args: [tokenId]
});
}
/**
* Approve an address to transfer a token
*/
async approve(to, tokenId) {
if (!(0, import_viem5.isAddress)(to)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const account = this.walletClient.account;
if (!account.address) {
throw new Error("Account address not found");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "approve",
args: [to, tokenId],
account: account.address
});
const hash = await this.walletClient.writeContract(request);
return hash;
}
/**
* Set approval for all tokens
*/
async setApprovalForAll(operator, approved) {
if (!(0, import_viem5.isAddress)(operator)) {
throw new Error("Invalid operator address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const account = this.walletClient.account;
if (!account.address) {
throw new Error("Account address not found");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "setApprovalForAll",
args: [operator, approved],
account: account.address
});
const hash = await this.walletClient.writeContract(request);
return hash;
}
/**
* Get the total supply of tokens
* @returns The total supply as a BigInt
*/
async totalSupply() {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "totalSupply",
args: []
});
}
/**
* Get a token by its index
* @param index The index of the token
* @returns Token ID at the specified index
*/
async tokenByIndex(index) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightAbi,
functionName: "tokenByIndex",
args: [index]
});
}
};
// src/resources/rightsBoundAccount.ts
var RightsBoundAccountClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
getContractAddress() {
return this.contractAddress;
}
/**
* Claim rewards for a period
* @param period The period to claim rewards for
* @returns Transaction hash
*
* @remarks
* Allows stakeholders to claim their share of royalties for a specific period.
*
* @example
* ```typescript
* // Stakeholders can claim their share
* await rightsBoundAccount.claim(currentPeriod);
* ```
*/
async claim(period) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "claim",
args: [period],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Claim from a child bound account
* @param childBoundAccount The address of the child bound account to claim from (the derivative bound account)
* @param period The period to claim for
* @returns Transaction hash
*
* @remarks
* This function allows a parent bound account to claim its allocated share from a downstream
* (child) bound account. This is part of the hierarchical royalty distribution system where
* VR (child) bound accounts distribute payments to their parent bound accounts.
* Important Notes:
* - Cannot override fixed distributions to:
* - Verifier module (for verifiers who helped achieve Verified Rights status)
* - Cultura Treasury
* - Used by protocols to define custom royalty distribution logic
* - Must include parent digital asset owners if the digital asset is a derivative work
*
* @example
* ```typescript
* // Parent bound account claims from VR bound account
* await parentBoundAccount.claimFromChild(vrBoundAccountAddress, period);
* ```
*/
async claimFromChild(childBoundAccount, period) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "claimFromChild",
args: [childBoundAccount, period],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Set payment info for a period. This function is used to distribute royalties.
*
* @remarks
* The new simplified flow automatically calculates splits for parents, the Cultura Treasury,
* and the verifier module based on the total amount.
*
* @param info Payment information including total amount, sponsor, and authorization signature.
* @returns Transaction hash
*/
async setPaymentInfo(info) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "setPaymentInfo",
args: [
{
totalAmount: info.totalAmount,
sponsor: info.sponsor,
signature: info.signature,
signer: info.signer
}
],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
return hash;
}
/**
* Generates a signature for setting payment info on a RightsBoundAccount.
*
* @param period - The period index of the royalty payment.
* @param totalAmount - The total amount of the payment.
* @param sponsor - The address that will sponsor the token transfer.
* @returns Signature for setting the payment info.
*/
async signForSetPaymentInfo(period, totalAmount, sponsor) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "CulturaRightsBoundAccount",
version: "1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
PaymentInfo: [
{ name: "period", type: "uint256" },
{ name: "totalAmount", type: "uint256" },
{ name: "sponsor", type: "address" }
]
},
message: {
period,
totalAmount,
sponsor
},
primaryType: "PaymentInfo"
});
return signature;
}
/**
* Get current period
* @returns The current period as a bigint
*/
async getCurrentPeriod() {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "currentPeriod",
args: []
});
}
/**
* Get payment amount for a beneficiary in a specific period
* This can be used to determine if a royalty has been claimed
* @param period The payment period
* @param beneficiary The address of the beneficiary
* @returns The payment amount for the beneficiary in the specified period
*/
async getPaymentAmount(period, beneficiary) {
try {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "getPaymentAmount",
args: [period, beneficiary]
});
return result;
} catch (error) {
console.error("Error in getPaymentAmount:", error);
return BigInt(0);
}
}
/**
* Get verifier module address
* @returns The address of the verifier module contract
*/
async getVerifierModule() {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "verifierModule",
args: []
});
}
/**
* Get Cultura treasury address
* @returns The address of the Cultura treasury
*/
async getCulturaTreasury() {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "culturaTreasury",
args: []
});
}
/**
* Get rights bound account asset address and token id
* @returns The address of the parent bound account
*/
async getRightsBoundAccountAsset() {
const assetAddress = await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "rightsContract",
args: []
});
const tokenId = await this.publicClient.readContract({
address: this.contractAddress,
abi: CulturaRightsBoundAccountAbi,
functionName: "rightsId",
args: []
});
return { assetAddress, tokenId };
}
};
// src/resources/royalties.ts
var RoyaltyClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
/**
* Get the number of royalty info periods for a token
* @param tokenId The ID of the token to get royalty period count for
* @returns The number of royalty periods for the token
*/
async getRoyaltyInfoCount(tokenId) {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "getRoyaltyInfoCount",
args: [tokenId]
});
return result;
}
/**
* Get royalty info for a specific period
* @param tokenId The ID of the token to get royalty period info for
* @param index The index of the royalty period
* @returns Detailed information about the royalty period
*/
async getRoyaltyInfoPeriod(tokenId, index) {
try {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "getRoyaltyInfoPeriod",
args: [tokenId, index]
});
if (Array.isArray(result) && result.length >= 5) {
const periodInfo = {
periodStart: result[0],
periodEnd: result[1],
amountDue: result[2],
amountPaid: result[3],
parentPendingClaims: Array.isArray(result[4]) ? result[4] : []
};
return periodInfo;
}
console.error("Invalid result format from getRoyaltyInfoPeriod:", result);
return {
periodStart: BigInt(0),
periodEnd: BigInt(0),
amountDue: BigInt(0),
amountPaid: BigInt(0),
parentPendingClaims: []
};
} catch (error) {
console.error("Error in getRoyaltyInfoPeriod:", error);
throw error;
}
}
/**
* Register royalty due for a period
* @param tokenId The ID of the token to register royalty for
* @param amountDue The amount of royalty due for the period
* @param startDate The start date of the royalty period (as Unix timestamp)
* @param endDate The end date of the royalty period (as Unix timestamp)
* @param royaltyInfoIndex The index of the royalty info
* @returns Transaction hash
*
* @remarks
* This is an optional step that protocols can use for tracking and transparency.
* This function is part of the reference implementation and can be skipped if
* protocols have their own royalty calculation mechanisms.
*/
async registerRoyaltyDue(tokenId, amountDue, startDate, endDate, royaltyInfoIndex) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "registerRoyaltyDue",
args: [tokenId, amountDue, startDate, endDate, royaltyInfoIndex],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Register royalty due for a period on behalf of a third party
* @param tokenId The ID of the token to register royalty for
* @param amountDue The amount of royalty due for the period
* @param startDate The start date of the royalty period (as Unix timestamp)
* @param endDate The end date of the royalty period (as Unix timestamp)
* @param royaltyInfoIndex The index of the royalty info
* @param signature Signature authorizing the registration
* @returns Transaction hash
*
*/
async delegatedRegisterRoyaltyDue(tokenId, amountDue, startDate, endDate, royaltyInfoIndex, signature) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "delegatedRegisterRoyaltyDue",
args: [tokenId, amountDue, startDate, endDate, royaltyInfoIndex, signature],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Pay royalty for a period
* @param tokenId The ID of the token to pay royalty for
* @param amountPaid The amount of royalty being paid
* @param periodIndex The index of the royalty period being paid
* @param culturaBoundAccount The Cultura bound account address
* @param signature Signature authorizing the payment
* @returns Transaction hash
*
*/
async payRoyalty(tokenId, amountPaid, periodIndex, culturaBoundAccount, signature) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "payRoyalty",
args: [tokenId, amountPaid, periodIndex, culturaBoundAccount, signature],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Pay royalty for a period on behalf of a third party
* @param tokenId The ID of the token to pay royalty for
* @param amountPaid The amount of royalty being paid
* @param periodIndex The index of the royalty period being paid
* @param culturaBoundAccount The Cultura bound account address
* @param signature Signature authorizing the payment
* @param delegatedSignature Signature authorizing the payment on behalf of a third party
* @returns Transaction hash
*
*/
async delegatedPayRoyalty(tokenId, amountPaid, periodIndex, culturaBoundAccount, signature, delegatedSignature) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "delegatedPayRoyalty",
args: [tokenId, amountPaid, periodIndex, culturaBoundAccount, signature, delegatedSignature],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Report an off-chain payment for a royalty period
* @param tokenId The ID of the token the payment is for
* @param periodIndex The period index the payment applies to
* @param amount The amount of the off-chain payment
* @param metadata Additional information about the payment
* @returns Transaction hash
*/
async reportOffChainPayment(tokenId, periodIndex, amount, metadata) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "reportOffChainPayment",
args: [tokenId, periodIndex, amount, metadata],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Report an off-chain payment for a royalty period on behalf of a third party
* @param tokenId The ID of the token the payment is for
* @param periodIndex The period index the payment applies to
* @param amount The amount of the off-chain payment
* @param metadata Additional information about the payment
* @param signature Signature authorizing the payment
* @returns Transaction hash
*/
async delegatedReportOffChainPayment(tokenId, periodIndex, amount, metadata, signature) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "delegatedReportOffChainPayment",
args: [tokenId, periodIndex, amount, metadata, signature],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Accept an off-chain payment that was previously reported by a parent.
* @param tokenId The ID of the token the payment is for
* @param periodIndex The period index the payment applies to
* @param parentBoundAccount The bound account address of the parent for payment processing
* @param signature Signature from the parent's owner authorizing the acceptance against the parent's bound account.
* @param signerAddress The address of the signer.
* @param sponsorAddress The address of the sponsor.
* @returns Transaction hash
*/
async acceptOffChainPaymentByParent(tokenId, periodIndex, parentBoundAccount, signature, signerAddress, sponsorAddress) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "acceptOffChainPaymentByParent",
args: [tokenId, periodIndex, parentBoundAccount, signature, signerAddress, sponsorAddress],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Deny an off-chain payment that was previously reported by a parent.
* @param tokenId The ID of the token the payment is for
* @param periodIndex The period index the payment applies to
* @param parentBoundAccount The bound account of the parent denying the payment.
* @param signature Signature authorizing the denial.
* @param signerAddress The address of the signer.
* @returns Transaction hash
*/
async denyOffChainPaymentByParent(tokenId, periodIndex, parentBoundAccount, signature, signerAddress) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "denyOffChainPaymentByParent",
args: [tokenId, periodIndex, parentBoundAccount, signature, signerAddress],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") {
throw new Error("Transaction failed");
}
return hash;
}
/**
* Create a signature for an off-chain payment acceptance by a parent.
* The signature is created for the `CulturaRightsBoundAccount` of the parent.
* @param rightsBoundAccount The address of the parent's RightsBoundAccount.
* @param totalAmount The total amount of the payment being accepted.
* @param period The royalty period index.
* @param sponsor The address sponsoring the transaction (usually the parent's owner).
* @param chainId Optional chain ID for the signature domain.
* @returns A promise that resolves to the payment signature.
*/
async signForAcceptOffChainPaymentByParent(rightsBoundAccount, totalAmount, period, sponsor) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const domain = {
name: "CulturaRightsBoundAccount",
version: "1",
chainId: this.publicClient.chain?.id,
verifyingContract: rightsBoundAccount
};
const types = {
PaymentInfo: [
{ name: "period", type: "uint256" },
{ name: "totalAmount", type: "uint256" },
{ name: "sponsor", type: "address" }
]
};
const message = {
period,
totalAmount,
sponsor
};
return this.walletClient.signTypedData({
account: this.walletClient.account,
domain,
types,
primaryType: "PaymentInfo",
message
});
}
/**
* Generates a signature for delegated royalty registration
* This allows a third party to register royalty due on behalf of the signer
*
* @param tokenId - The ID of the token to register royalty for
* @param amountDue - The amount of royalty due for the period
* @param startDate - The start date of the royalty period (as Unix timestamp)
* @param endDate - The end date of the royalty period (as Unix timestamp)
* @param royaltyInfoIndex - The index of the royalty info
* @returns The signature that can be used for delegated royalty registration
*/
async signForDelegatedRegisterRoyaltyDue(tokenId, amountDue, startDate, endDate, royaltyInfoIndex) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "CulturaRoyaltySystem",
version: "1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
DelegatedRegisterRoyaltyDue: [
{ name: "tokenId", type: "uint256" },
{ name: "amountDue", type: "uint256" },
{ name: "startDate", type: "uint256" },
{ name: "endDate", type: "uint256" },
{ name: "royaltyInfoIndex", type: "uint256" }
]
},
message: {
tokenId,
amountDue,
startDate,
endDate,
royaltyInfoIndex
},
primaryType: "DelegatedRegisterRoyaltyDue"
});
return signature;
}
/**
* Generates a signature for delegated royalty payment
* This allows a third party to pay royalty on behalf of the signer
*
* @param tokenId - The ID of the token to pay royalty for
* @param amountDue - The amount of royalty being paid
* @param royaltyInfoIndex - The index of the royalty period being paid
* @returns The signature that can be used for delegated royalty payment
*/
async signForDelegatedPayRoyalty(tokenId, amountDue, royaltyInfoIndex) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "CulturaRoyaltySystem",
version: "1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
DelegatedPayRoyalty: [
{ name: "tokenId", type: "uint256" },
{ name: "amountDue", type: "uint256" },
{ name: "royaltyInfoIndex", type: "uint256" }
]
},
message: {
tokenId,
amountDue,
royaltyInfoIndex
},
primaryType: "DelegatedPayRoyalty"
});
return signature;
}
/**
* Generates signature for denying an off-chain payment by a parent.
*
* @param tokenId - The ID of the token the payment is for
* @param periodIndex - The period index of the royalty payment
* @param parentBoundAccount - The bound account of the parent denying the payment.
* @returns Signature for denying the off-chain payment
*/
async signForDenyOffChainPaymentByParent(tokenId, periodIndex, parentBoundAccount) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "CulturaRoyaltySystem",
version: "1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
DenyOffChainPaymentByParent: [
{ name: "tokenId", type: "uint256" },
{ name: "periodIndex", type: "uint256" },
{ name: "parentBoundAccount", type: "address" }
]
},
message: {
tokenId,
periodIndex,
parentBoundAccount
},
primaryType: "DenyOffChainPaymentByParent"
});
return signature;
}
/**
* Generates a signature for delegated off-chain royalty payment
* This allows a third party to pay royalty on behalf of the signer
*
* @param tokenId - The ID of the token to pay royalty for
* @param amountDue - The amount of royalty being paid
* @param royaltyInfoIndex - The index of the royalty period being paid
* @returns The signature that can be used for delegated royalty payment
*/
async signForDelegatedOffchainReportRoyalty(tokenId, royaltyInfoIndex, amount) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "CulturaRoyaltySystem",
version: "1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
DelegatedReportOffChainPayment: [
{ name: "tokenId", type: "uint256" },
{ name: "royaltyInfoIndex", type: "uint256" },
{ name: "amount", type: "uint256" }
]
},
message: {
tokenId,
royaltyInfoIndex,
amount
},
primaryType: "DelegatedReportOffChainPayment"
});
return signature;
}
/**
* Generates a signature for delegated acceptance of an off-chain payment
* This allows a third party to accept an off-chain payment on behalf of the signer
*
* @param tokenId - The ID of the token to accept the off-chain payment for
* @param royaltyInfoIndex - The index of the royalty period being accepted
* @returns The signature that can be used for delegated acceptance of an off-chain payment
*/
async signForDelegatedOffchainAcceptRoyalty(tokenId, royaltyInfoIndex) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const signature = await this.walletClient.signTypedData({
account: this.walletClient.account,
domain: {
name: "CulturaRoyaltySystem",
version: "1",
chainId: await this.publicClient.getChainId(),
verifyingContract: this.contractAddress
},
types: {
DelegatedAcceptOffChainPayment: [
{ name: "tokenId", type: "uint256" },
{ name: "royaltyInfoIndex", type: "uint256" }
]
},
message: {
tokenId,
royaltyInfoIndex
},
primaryType: "DelegatedAcceptOffChainPayment"
});
return signature;
}
/**
* Generates signature parameters required for delegated operations
*
* @param signature - The signed message signature
* @param signerAddress - The address of the signer
* @returns Signature parameters object with signature, signer, v, r, and s values
*/
generateSignatureParams(signature, signerAddress) {
const signatureBytes = Buffer.from(signature.slice(2), "hex");
const r = `0x${signatureBytes.slice(0, 32).toString("hex")}`;
const s = `0x${signatureBytes.slice(32, 64).toString("hex")}`;
const v = signatureBytes[64];
return {
signature,
signer: signerAddress,
v,
r,
s
};
}
async getParentAcceptanceInfo(tokenId, periodIndex, parentBoundAccount) {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "getParentAcceptanceInfo",
args: [tokenId, periodIndex, parentBoundAccount]
});
return {
allocatedAmount: result.allocatedAmount,
status: result.status,
signature: result.signature,
timestamp: result.timestamp
};
}
/**
* Get information about an off-chain payment
* @param tokenId The ID of the token to check
* @param periodIndex The period index to check
* @returns Information about the off-chain payment
*/
async getOffChainPaymentInfo(tokenId, periodIndex) {
try {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "offChainPayments",
args: [tokenId, periodIndex]
});
if (Array.isArray(result) && result.length >= 3) {
return {
reportedAmount: result[0],
metadata: result[1],
reporter: result[2]
};
}
return {
reportedAmount: BigInt(0),
metadata: "",
reporter: "0x0000000000000000000000000000000000000000"
};
} catch (error) {
console.error("Error in getOffChainPaymentInfo:", error);
throw error;
}
}
/**
* Get all parent acceptance information for an off-chain payment
* @param tokenId The ID of the token to check
* @param periodIndex The period index to check
* @param culturaDigitalAssetAddress The address of the Cultura Digital Asset contract
* @returns Array of parent acceptance info with their bound account addresses
*/
async getAllParentAcceptanceInfo(tokenId, periodIndex, culturaDigitalAssetAddress) {
try {
const licenseInfo = await this.publicClient.readContract({
address: culturaDigitalAssetAddress,
abi: CulturaRightAbi,
functionName: "getLicenseInfo",
args: [tokenId]
});
const parentBoundAccounts = licenseInfo.parentInfo.map(
(parent) => parent.rightsBoundAccount
);
const parentAcceptanceInfos = await Promise.all(
parentBoundAccounts.map(async (parentBoundAccount) => {
const acceptanceInfo = await this.getParentAcceptanceInfo(
tokenId,
periodIndex,
parentBoundAccount
);
return { parentBoundAccount, acceptanceInfo };
})
);
return parentAcceptanceInfos;
} catch (error) {
console.error("Error in getAllParentAcceptanceInfo:", error);
throw error;
}
}
/**
* Get the full royalty information for a token
* @param tokenId The ID of the token to get all royalty info for
* @returns Array of royalty info periods
*/
async getFullRoyaltyInfo(tokenId) {
try {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: CRSAbi,
functionName: "getFullRoyaltyInfo",
args: [tokenId]
});
if (Array.isArray(result)) {
return result.map((period) => ({
periodStart: period.periodStart,
periodEnd: period.periodEnd,
amountDue: period.amountDue,
amountPaid: period.amountPaid,
parentPendingClaims: []
// Contract doesn't return this, so use empty array
}));
}
return [];
} catch (error) {
console.error("Error in getFullRoyaltyInfo:", error);
throw error;
}
}
};
// src/resources/utils.ts
var SignatureUtilsClient = class {
constructor(publicClient, contractAddress) {
this.publicClient = publicClient;
this.contractAddress = contractAddress;
}
/**
* Get the delegated self attest typehash
*/
async getDelegatedSelfAttestTypeHash() {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: SignatureUtilsAbi,
functionName: "_DELEGATEDSELFATTEST_TYPEHASH",
args: []
});
}
};
// src/resources/bondToken.ts
var import_viem6 = require("viem");
var BondTokenClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
/**
* Mints new bond tokens to a specified account (only for testing)
* @param account Address that will receive the minted tokens
* @param amount Amount of tokens to mint
* @returns Transaction hash
*
* @remarks
* This function is only available on test networks. In production/mainnet,
* tokens must be acquired through proper channels (exchanges, transfers, etc).
*/
async mint(account, amount) {
if (!(0, import_viem6.isAddress)(account)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: BondTokenAbi,
functionName: "mint",
args: [account, amount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${hash}`);
}
return hash;
}
/**
* Approves an address to spend tokens on behalf of the caller
* @param spender Address that will be approved to spend tokens
* @param amount Amount of tokens to approve
* @returns Transaction hash
*
* @example
* ```typescript
* // Approve tokens for self-attestation
* const bondAmount = parseEther('0.0001');
* await sdk.bondToken.approve(attestationServiceAddress, bondAmount);
* ```
*/
async approve(spender, amount) {
if (!(0, import_viem6.isAddress)(spender)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: BondTokenAbi,
functionName: "approve",
args: [spender, amount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${hash}`);
}
return hash;
}
/**
* Gets the balance of an account
* @param account Address to check balance of
* @returns Balance of the account
*
* @example
* ```typescript
* // Check account balance
* const balance = await sdk.bondToken.balanceOf(userAddress);
* ```
*/
async balanceOf(account) {
if (!(0, import_viem6.isAddress)(account)) {
throw new Error("Invalid address format");
}
return await this.publicClient.readContract({
address: this.contractAddress,
abi: BondTokenAbi,
functionName: "balanceOf",
args: [account]
});
}
/**
* Gets the allowance of an account to spend another account's tokens
* @param owner Address of the token owner
* @param spender Address of the token spender
* @returns Amount of tokens the spender is allowed to spend
*
* @example
* ```typescript
* // Check if contract has enough allowance
* const currentAllowance = await sdk.bondToken.allowance(userAddress, contractAddress);
* if (currentAllowance < requiredAmount) {
* await sdk.bondToken.approve(contractAddress, requiredAmount);
* }
* ```
*/
async allowance(owner, spender) {
if (!(0, import_viem6.isAddress)(owner) || !(0, import_viem6.isAddress)(spender)) {
throw new Error("Invalid address format");
}
return await this.publicClient.readContract({
address: this.contractAddress,
abi: BondTokenAbi,
functionName: "allowance",
args: [owner, spender]
});
}
};
// src/mocks/mockLicensingProtocol.ts
var import_viem9 = require("viem");
// src/query/client.ts
var import_core3 = require("@urql/core");
// src/query/digitalAsset.ts
var import_core = require("@urql/core");
var import_viem7 = require("viem");
var DIGITAL_ASSET_FIELDS = `
id
contractAddress
tokenId
owner {
id
address
tokenCount
}
mintedAt
tokenURI
termsURI
isLicensedAsset
metadata {
id
name
description
image
externalURL
}
parentDigitalAssets {
id
parentCollection
parentDigitalAssetId
owner
rightsBoundAccount
royaltySplit
}
rightsBoundAccount
verifiedRights {
id
digitalAssetAddress
digitalAssetId
attestationUID
owner
assetClass
initialBondAmount
currentBondAmount
verifierCount
createdAt
updatedAt
isVerified
whitelistedVerifierCount
communityVerifierCount
verifications {
id
verifier {
id
address
totalBondAmount
verificationCount
isWhitelisted
}
bondAmount
timestamp
}
}
`;
var DigitalAssetMethods = class {
constructor(client) {
this.client = client;
}
/**
* Get a digital asset by unique asset ID
*
* @param uid The ID of the digital asset
* @returns The digital asset data or null if not found
*
* @example
* ```typescript
* // Get a digital asset by its UID
* const asset = await queryClient.digitalAsset.getByUID("1")
* if (asset) {
* console.log(`Found asset: ${asset.assetName}`)
* console.log(`Owner: ${asset.owner.address}`)
* } else {
* console.log("Asset not found")
* }
* ```
*
* @remarks
* This method fetches a single digital asset by its unique asset ID. It returns null if no matching
* asset is found. The response includes detailed information about the asset, including
* its metadata, ownership, and any associated verified rights.
*/
async getByUID(uid) {
const query = import_core.gql`
query GetDigitalAsset($uid: ID!) {
digitalAsset(id: $uid) {
${DIGITAL_ASSET_FIELDS}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, { uid }).toPromise();
if (error || !data) {
return null;
}
return data.digitalAsset;
}
/**
* Get a digital asset by its contract address and token ID
*
* @param contractAddress The contract address of the digital asset
* @param tokenId The token ID of the digital asset
* @returns The digital asset data or null if not found
*
* @example
* ```typescript
* // Get a digital asset by its contract address and token ID
* const asset = await queryClient.digitalAsset.getByContractAndTokenId("0x123...", "1")
* if (asset) {
* console.log(`Found asset: ${asset.metadata?.name}`)
* } else {
* console.log("Asset not found")
* }
* ```
*/
async getByContractAndTokenId(contractAddress, tokenId) {
if (!(0, import_viem7.isAddress)(contractAddress)) {
throw new Error("Invalid contract address format");
}
const uid = getDigitalAssetUID(contractAddress, tokenId);
return this.getByUID(uid);
}
/**
* Get digital assets owned by a specific address
*
* @param ownerAddress The owner's address
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of digital assets
*
* @example
* ```typescript
* // Get all digital assets owned by an address
* const assets = await queryClient.digitalAsset.getByOwner("0x123...789")
* console.log(`Found ${assets.length} assets owned by this address`)
*
* // With pagination
* const firstPage = await queryClient.digitalAsset.getByOwner("0x123...789", 10, 0)
* const secondPage = await queryClient.digitalAsset.getByOwner("0x123...789", 10, 10)
*
* // Display asset names
* assets.forEach(asset => {
* console.log(`Asset: ${asset.assetName || "Unnamed asset"} (ID: ${asset.tokenId})`)
* })
* ```
*
* @remarks
* This method returns all digital assets owned by a specific address. The address must be
* a valid Ethereum address. Results can be paginated using the first and skip parameters.
* This is particularly useful for creating user dashboards or galleries showing all assets
* owned by a particular user.
*/
async getByOwner(ownerAddress, first = 100, skip = 0) {
if (!(0, import_viem7.isAddress)(ownerAddress)) {
throw new Error("Invalid address format");
}
const query = import_core.gql`
query GetDigitalAssetsByOwner($owner: String!, $first: Int!, $skip: Int!) {
digitalAssets(where: { owner: $owner }, first: $first, skip: $skip) {
${DIGITAL_ASSET_FIELDS}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, {
owner: ownerAddress.toLowerCase(),
first,
skip
}).toPromise();
if (error || !data) {
return [];
}
return data.digitalAssets;
}
/**
* Get licensed assets derived from a parent asset
*
* @param parentAssetId The parent asset ID
* @param parentAssetAddress The parent asset contract address
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of digital assets
*
* @example
* ```typescript
* // Get licensed assets derived from a parent asset
* const assets = await queryClient.digitalAsset.getLicensedAssets(
* "1", // parent asset ID
* "0x456...789" // parent asset contract address
* )
* console.log(`Found ${assets.length} licensed assets derived from this parent`)
*
* // Display license information
* assets.forEach(asset => {
* console.log(`Licensed asset: ${asset.metadata?.name} (ID: ${asset.tokenId})`)
* console.log(`Parent asset details: ${asset.parentDigitalAssets?.[0]?.parentCollection}`)
* })
* ```
*
* @remarks
* This method returns all licensed assets that were derived from a specific parent asset.
* This is useful for tracking all licensing activity for a given intellectual property.
* For example, you can use this to see all derivative works that have been properly
* licensed from an original creation. The parent asset address must be a valid Ethereum address.
*/
async getLicensedAssets(parentAssetId, parentAssetAddress, first = 100, skip = 0) {
if (!(0, import_viem7.isAddress)(parentAssetAddress)) {
throw new Error("Invalid address format");
}
const query = import_core.gql`
query GetLicensedAssets($parentAssetId: String!, $parentAssetAddress: String!, $first: Int!, $skip: Int!) {
digitalAssets(
where: {
isLicensedAsset: true,
parentDigitalAssets_: {
parentDigitalAssetId: $parentAssetId,
parentCollection: $parentAssetAddress
}
},
first: $first,
skip: $skip
) {
${DIGITAL_ASSET_FIELDS}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, {
parentAssetId,
parentAssetAddress: parentAssetAddress.toLowerCase(),
first,
skip
}).toPromise();
if (error || !data) {
return [];
}
return data.digitalAssets;
}
/**
* Get all digital assets
*
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of digital assets
*
* @example
* ```typescript
* // Get the first 10 digital assets
* const assets = await queryClient.digitalAsset.getAll(10, 0)
* console.log(`Retrieved ${assets.length} digital assets`)
*
* // Iterate through pages of results
* let allAssets = []
* let pageSize = 50
* let currentPage = 0
*
* while (true) {
* const batch = await queryClient.digitalAsset.getAll(pageSize, currentPage * pageSize)
* if (batch.length === 0) break
* allAssets = [...allAssets, ...batch]
* currentPage++
* }
* console.log(`Total digital assets collected: ${allAssets.length}`)
* ```
*
* @remarks
* This method returns all digital assets in the system, ordered by mint date (newest first).
* Use pagination parameters to efficiently handle large result sets. This query is useful
* for creating explorers or galleries that display all assets in the system. For large
* collections, it's recommended to use pagination to improve performance and user experience.
*/
async getAll(first = 100, skip = 0) {
const query = import_core.gql`
query GetAllDigitalAssets($first: Int!, $skip: Int!) {
digitalAssets(
orderBy: mintedAt,
orderDirection: desc,
first: $first,
skip: $skip
) {
${DIGITAL_ASSET_FIELDS}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, { first, skip }).toPromise();
if (error || !data) {
return [];
}
return data.digitalAssets;
}
};
// src/query/verifiedRights.ts
var import_core2 = require("@urql/core");
var import_viem8 = require("viem");
var VERIFIED_RIGHTS_FIELDS = `
id
digitalAssetAddress
digitalAssetId
attestationUID
owner
assetClass
initialBondAmount
currentBondAmount
verifierCount
createdAt
updatedAt
isVerified
whitelistedVerifierCount
communityVerifierCount
rightsBoundAccount
verifications {
id
bondAmount
timestamp
verifier {
id
address
totalBondAmount
verificationCount
isWhitelisted
}
}
`;
var VerifiedRightsMethods = class {
constructor(client) {
this.SINGLE = "verifiedRights";
this.COLLECTION = "verifiedRights_collection";
this.client = client;
}
/**
* Get verified rights by ID
*
* @param id The ID of the verified rights
* @returns The verified rights data or null if not found
*
* @example
* ```typescript
* // Get verified rights by ID
* const rights = await queryClient.verifiedRights.getById("1")
* if (rights) {
* console.log(`Found verified rights with asset class ${rights.assetClass}`)
* } else {
* console.log("No verified rights found with that ID")
* }
* ```
*
* @remarks
* This method fetches a single verified rights entry by its ID. It returns null if no
* matching rights are found. The ID is typically a unique identifier generated when
* the rights are created through attestation.
*/
async getById(id) {
const query = import_core2.gql`
query GetVerifiedRights($id: ID!) {
${this.SINGLE}(id: $id) {
${VERIFIED_RIGHTS_FIELDS}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, { id }).toPromise();
if (error || !data) {
return null;
}
return data[this.SINGLE];
}
/**
* Get verified rights by digital asset info
*
* @param assetAddress The address of the digital asset contract
* @param assetId The ID of the digital asset
* @returns The verified rights data or null if not found
*
* @example
* ```typescript
* // Get verified rights for a specific digital asset
* const rights = await queryClient.verifiedRights.getByDigitalAsset(
* "0x1234567890abcdef1234567890abcdef12345678",
* "42"
* )
*
* if (rights) {
* console.log(`Asset verified with asset class ${rights.assetClass} and ${rights.verifierCount} verifiers`)
* } else {
* console.log("No verified rights found for this asset")
* }
* ```
*
* @remarks
* This method allows you to find the verified rights associated with a specific digital asset.
* It's useful when you know the asset's contract address and token ID, and want to check if
* it has been attested and what asset class it received. The method validates that the provided
* address has the correct format.
*/
async getByDigitalAsset(assetAddress, assetId) {
if (!(0, import_viem8.isAddress)(assetAddress)) {
throw new Error("Invalid address format");
}
const query = import_core2.gql`
query GetVerifiedRightsByDigitalAsset($assetAddress: String!, $assetId: String!) {
${this.COLLECTION}(
where: { digitalAssetAddress: $assetAddress, digitalAssetId: $assetId }
) {
${VERIFIED_RIGHTS_FIELDS}
digitalAsset {
id
contractAddress
tokenId
isLicensedAsset
owner {
id
address
tokenCount
}
metadata {
id
name
description
image
externalURL
}
parentDigitalAssets {
id
parentCollection
parentDigitalAssetId
owner
royaltySplit
}
rightsBoundAccount
}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, {
assetAddress: assetAddress.toLowerCase(),
assetId
}).toPromise();
if (error) {
console.error("GraphQL error in getByDigitalAsset:", error);
return null;
}
if (!data || !data[this.COLLECTION] || data[this.COLLECTION].length === 0) {
return null;
}
return data[this.COLLECTION][0];
}
/**
* Get verified rights by owner
*
* @param ownerAddress The owner's address
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of verified rights
*
* @example
* ```typescript
* // Get all verified rights owned by an address
* const rights = await queryClient.verifiedRights.getByOwner("0x123...789")
* console.log(`Found ${rights.length} verified rights owned by this address`)
*
* // With pagination
* const firstPage = await queryClient.verifiedRights.getByOwner("0x123...789", 10, 0)
* const secondPage = await queryClient.verifiedRights.getByOwner("0x123...789", 10, 10)
* ```
*
* @remarks
* This method returns all verified rights entries owned by a specific address. The address
* must be a valid Ethereum address. Results are ordered by creation date (newest first)
* and can be paginated using the first and skip parameters. This is useful for creating
* user dashboards that show all assets a user has had verified.
*/
async getByOwner(ownerAddress, first = 100, skip = 0) {
if (!(0, import_viem8.isAddress)(ownerAddress)) {
throw new Error("Invalid address format");
}
const query = import_core2.gql`
query GetVerifiedRightsByOwner($owner: Bytes!, $first: Int!, $skip: Int!) {
${this.COLLECTION}(
where: { owner: $owner },
orderBy: createdAt,
orderDirection: desc,
first: $first,
skip: $skip
) {
${VERIFIED_RIGHTS_FIELDS}
digitalAsset {
id
tokenId
isLicensedAsset
owner {
id
address
tokenCount
}
metadata {
id
name
description
image
externalURL
}
parentDigitalAssets {
id
parentCollection
parentDigitalAssetId
owner
royaltySplit
}
rightsBoundAccount
}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, {
owner: ownerAddress.toLowerCase(),
first,
skip
}).toPromise();
if (error || !data) {
return [];
}
return data[this.COLLECTION] || [];
}
/**
* Get verified rights by asset class
*
* @param assetClass The asset class to filter by (e.g. "0", "1", "2", "3")
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of verified rights
*
* @example
* ```typescript
* // Get all verified rights with a specific asset class
* const generalClassRights = await queryClient.verifiedRights.getByAssetClass("0")
* console.log(`Found ${generalClassRights.length} General class verified rights`)
*
* // Get different asset classes for comparison
* const class1Rights = await queryClient.verifiedRights.getByAssetClass("1")
* const class2Rights = await queryClient.verifiedRights.getByAssetClass("2")
* ```
*
* @remarks
* This method returns all verified rights with a specific asset class. Currently, there is only
* the general class (0=General) available. This function is designed for future use when
* additional asset classes are added, each with their own specific requirements for
* verification. This query will be useful for filtering assets by their asset class.
*/
async getByAssetClass(assetClass, first = 100, skip = 0) {
const query = import_core2.gql`
query GetVerifiedRightsByAssetClass($assetClass: String!, $first: Int!, $skip: Int!) {
${this.COLLECTION}(
where: { assetClass: $assetClass },
first: $first,
skip: $skip
) {
${VERIFIED_RIGHTS_FIELDS}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, { assetClass, first, skip }).toPromise();
if (error || !data) {
return [];
}
return data[this.COLLECTION] || [];
}
/**
* Get all verified rights
*
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of verified rights
*
* @example
* ```typescript
* // Get the first 10 verified rights
* const rights = await queryClient.verifiedRights.getAll(10, 0)
* console.log(`Retrieved ${rights.length} verified rights`)
*
* // Iterate through pages of results
* let allRights = []
* let pageSize = 50
* let currentPage = 0
*
* while (true) {
* const batch = await queryClient.verifiedRights.getAll(pageSize, currentPage * pageSize)
* if (batch.length === 0) break
* allRights = [...allRights, ...batch]
* currentPage++
* }
* console.log(`Total verified rights collected: ${allRights.length}`)
* ```
*
* @remarks
* This method returns all verified rights in the system, ordered by creation date (newest first).
* Use pagination parameters to efficiently handle large result sets. This query is useful for
* creating explorers or dashboards that display all verified rights in the system. For large
* datasets, it's recommended to use pagination to improve performance and user experience.
*/
async getAll(first = 100, skip = 0) {
const query = import_core2.gql`
query GetAllVerifiedRights($first: Int!, $skip: Int!) {
${this.COLLECTION}(
orderBy: createdAt,
orderDirection: desc,
first: $first,
skip: $skip
) {
${VERIFIED_RIGHTS_FIELDS}
digitalAsset {
id
tokenId
isLicensedAsset
owner {
id
address
tokenCount
}
metadata {
id
name
description
image
externalURL
}
parentDigitalAssets {
id
parentCollection
parentDigitalAssetId
owner
royaltySplit
}
rightsBoundAccount
}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, { first, skip }).toPromise();
if (error || !data) {
return [];
}
return data[this.COLLECTION] || [];
}
/**
* Get verified rights that have been successfully verified (isVerified = true)
*
* @param first Number of items to fetch (default: 100)
* @param skip Number of items to skip (default: 0)
* @returns Array of verified rights that have been successfully verified
*
* @remarks
* This method returns all rights that have been successfully verified (where isVerified = true), and assets have reached level 2.
*/
async getVerified(first = 100, skip = 0) {
const query = import_core2.gql`
query GetVerifiedRights($first: Int!, $skip: Int!) {
${this.COLLECTION}(
where: { isVerified: true },
orderBy: createdAt,
orderDirection: desc,
first: $first,
skip: $skip
) {
${VERIFIED_RIGHTS_FIELDS}
digitalAsset {
id
contractAddress
tokenId
isLicensedAsset
owner {
id
address
tokenCount
}
tokenURI
metadata {
id
name
description
image
externalURL
}
parentDigitalAssets {
id
parentCollection
parentDigitalAssetId
owner
royaltySplit
}
rightsBoundAccount
}
}
}
`;
const { data, error } = await this.client.graphqlClient.query(query, { first, skip }).toPromise();
if (error || !data) {
return [];
}
return data[this.COLLECTION] || [];
}
};
// src/query/proofOfPopularity.ts
var ProofOfPopularityMethods = class {
constructor(queryClient) {
this.queryClient = queryClient;
this.client = queryClient.graphqlClient;
}
/**
* Get all POP attestations with pagination
* @param limit Maximum number of attestations to return
* @param offset Number of attestations to skip
* @returns Array of POP attestations
*/
async getAll(limit = 10, offset = 0) {
const { data, error } = await this.client.query(
`
query GetPOPAttestations($limit: Int!, $offset: Int!) {
popAttestations(first: $limit, skip: $offset) {
id
totalVotedAmount
popularityScore
isTopAttestation
topAttestationRank
topAttestationScore
}
}
`,
{ limit, offset }
).toPromise();
if (error) throw error;
return data?.popAttestations || [];
}
/**
* Get a specific POP attestation by its UID
* @param uid Attestation UID
* @returns The POP attestation if found
*/
async getByUID(uid) {
const { data, error } = await this.client.query(
`
query GetPOPAttestation($id: ID!) {
popAttestation(id: $id) {
id
totalVotedAmount
popularityScore
isTopAttestation
topAttestationRank
topAttestationScore
userVotes {
id
user
amount
unlockTime
}
}
}
`,
{ id: uid }
).toPromise();
if (error) throw error;
return data?.popAttestation;
}
/**
* Get top POP attestations by popularity score
* @param limit Maximum number of top attestations to return
* @returns Array of top POP attestations sorted by popularity score
*/
async getTopAttestations(limit = 3) {
const { data, error } = await this.client.query(
`
query GetTopPOPAttestations($limit: Int!) {
popAttestations(
first: $limit,
where: { isTopAttestation: true },
orderBy: popularityScore,
orderDirection: desc
) {
id
totalVotedAmount
popularityScore
isTopAttestation
topAttestationRank
topAttestationScore
}
}
`,
{ limit }
).toPromise();
if (error) throw error;
return data?.popAttestations || [];
}
/**
* Get user votes for a specific attestation
* @param attestationUID Attestation UID
* @param limit Maximum number of votes to return
* @param offset Number of votes to skip
* @returns Array of user votes for the attestation
*/
async getUserVotes(attestationUID, limit = 10, offset = 0) {
const { data, error } = await this.client.query(
`
query GetUserVotes($attestationUID: String!, $limit: Int!, $offset: Int!) {
popUserVotes(
first: $limit,
skip: $offset,
where: { attestation: $attestationUID }
) {
id
user
amount
unlockTime
attestation {
id
popularityScore
}
}
}
`,
{ attestationUID, limit, offset }
).toPromise();
if (error) throw error;
return data?.popUserVotes || [];
}
/**
* Get votes by a specific user
* @param userAddress User wallet address
* @param limit Maximum number of votes to return
* @param offset Number of votes to skip
* @returns Array of votes made by the user
*/
async getVotesByUser(userAddress, limit = 10, offset = 0) {
const { data, error } = await this.client.query(
`
query GetVotesByUser($userAddress: String!, $limit: Int!, $offset: Int!) {
popUserVotes(
first: $limit,
skip: $offset,
where: { user: $userAddress }
) {
id
user
amount
unlockTime
attestation {
id
popularityScore
isTopAttestation
topAttestationRank
}
}
}
`,
{ userAddress, limit, offset }
).toPromise();
if (error) throw error;
return data?.popUserVotes || [];
}
};
// src/query/client.ts
var THE_GRAPH_CONFIG = {
local: {
url: (typeof process !== "undefined" ? process.env.CULTURA_GRAPH_LOCAL_URL : void 0) || "http://localhost:8000/subgraphs/name/cultura"
},
devnet: {
url: (typeof process !== "undefined" ? process.env.CULTURA_GRAPH_DEVNET_URL : void 0) || // Default to the 'latest' tag for general use
"https://api.goldsky.com/api/public/project_cm87g4518bkcs01x36po8cua3/subgraphs/cultura-devnet/latest/gn"
},
testnet: {
url: (typeof process !== "undefined" ? process.env.CULTURA_GRAPH_TESTNET_URL : void 0) || // Default to the 'latest' tag for general use
"https://api.goldsky.com/api/public/project_cm87g4518bkcs01x36po8cua3/subgraphs/cultura-testnet/latest/gn"
}
};
var QueryClient = class {
constructor(environment) {
this.environment = environment;
this.config = THE_GRAPH_CONFIG[environment] || THE_GRAPH_CONFIG.testnet;
this.graphqlClient = (0, import_core3.createClient)({
url: this.config.url,
exchanges: [
(0, import_core3.mapExchange)({
onError: (error) => {
if (error instanceof import_core3.CombinedError) {
error.graphQLErrors.forEach(({ message, ...params }) => {
console.error("[GraphQL Error]:", message, JSON.stringify(params, null, 2));
});
}
}
}),
import_core3.fetchExchange,
(0, import_core3.mapExchange)({
onError: (error) => {
if (error instanceof import_core3.CombinedError && error.networkError) {
const { message, ...params } = error.networkError;
console.error("[Network Error]:", message, JSON.stringify(params, null, 2));
}
}
})
],
fetchOptions: {}
});
this.digitalAsset = new DigitalAssetMethods(this);
this.verifiedRights = new VerifiedRightsMethods(this);
this.pop = new ProofOfPopularityMethods(this);
}
};
// src/mocks/mockLicensingProtocol.ts
var MockLicensingProtocolClient = class {
constructor(publicClient, walletClient, contractAddress, culturaDigitalAssetAddress, attestationServiceAddress, chainType) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
this.culturaDigitalAssetAddress = culturaDigitalAssetAddress;
this.attestationServiceAddress = attestationServiceAddress;
this.chainType = chainType;
this.attestationServiceClient = new AttestationServiceClient(
this.publicClient,
this.walletClient,
this.attestationServiceAddress
);
this.culturaDigitalAssetClient = new CulturaDigitalAssetClient(
this.publicClient,
this.walletClient,
this.culturaDigitalAssetAddress
);
this.queryClient = new QueryClient(this.chainType);
}
/**
* Simulate registering a token ID as licensed within the mock protocol.
* @param collectionAddress The address of the collection that the token is licensed from
* @param tokenId The ID of the token to license
* @returns Transaction hash
*
* @remarks
* This method simulates the action of a licensing protocol granting a license
* for a specific parent token. It records this "license granted" status within
* the mock contract's state for the given `collectionAddress` and `tokenId`.
*
* This should typically be called _before_ minting the Licensed Creative Asset.
* It represents securing the rights needed for the next step.
*
* In a real-world scenario, this step would involve interacting with an actual
* licensing protocol, potentially involving off-chain agreements, payments,
* and specific license term negotiations.
*
* @example
* ```typescript
* // License an existing token
* const collectionAddress = "0xcollection123...";
* const tokenId = BigInt(42);
*
* const txHash = await mockLicensingClient.licenseDigitalAsset(
* collectionAddress,
* tokenId
* );
*
* console.log(`Token licensed with transaction: ${txHash}`);
* ```
*/
async licenseDigitalAsset(collectionAddress, tokenId) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: MockLicensingAttestationAbi,
functionName: "fakeLicenseIp",
args: [collectionAddress, tokenId],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
await this.publicClient.waitForTransactionReceipt({ hash });
return hash;
}
/**
* Simulate verifying the attestation of a Licensed Creative Asset.
* @param attestationUID The attestation UID to verify
* @param bondedAmount The amount to bond for verification
* @returns Transaction hash
*
* @remarks
* This method simulates a licensing protocol performing a verification check on an
* _attestation_ associated with a Licensed Creative Asset. It takes the
* `attestationUID` (obtained after calling `sdk.attestationService.attest` on the
* _new_ Licensed Creative Asset) and a `bondAmount`.
*
* In the context of the mock protocol, this function likely interacts with the main
* `CAS.verifyAttestation` function, effectively acting as a verifier endorsing the
* new asset's attestation. It represents the final step where the licensing body
* confirms the validity of the newly created and attested licensed asset.
*
* The `bondedAmount` is used for the underlying CAS verification.
*
* @example
* ```typescript
* // Verify a licensed asset
* const attestationUID = "0xattestation123...";
* const bondAmount = BigInt("500000000000000000"); // 0.5 tokens
*
* const txHash = await mockLicensingClient.verifyLicensedAsset(
* attestationUID,
* bondAmount
* );
*
* console.log(`Asset verification initiated with transaction: ${txHash}`);
* ```
*/
async verifyLicensedAsset(attestationUID, bondedAmount) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: MockLicensingAttestationAbi,
functionName: "verifyLicensedAsset",
args: [attestationUID, bondedAmount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
await this.publicClient.waitForTransactionReceipt({ hash });
return hash;
}
/**
* Get licensed tokens for a specific address.
* @param address The address to check licensed tokens for
* @returns Array of licensed tokens with their collection addresses and token IDs
*/
async getLicensedTokens(address) {
try {
let i = 0;
const licensedTokens = [];
while (true) {
try {
const [collectionAddress, tokenId] = await this.publicClient.readContract({
address: this.contractAddress,
abi: MockLicensingAttestationAbi,
functionName: "licensedTokens",
args: [address, BigInt(i)]
});
licensedTokens.push({ collectionAddress, tokenId });
i++;
} catch (error) {
break;
}
}
return licensedTokens;
} catch (error) {
console.error("Error getting licensed tokens:", error);
return [];
}
}
/**
* Check if a specific address has licensed a specific token.
* @param address The address to check
* @param collectionAddress The collection address to check
* @param tokenId The token ID to check
* @returns Boolean indicating whether the address has licensed the token
*/
async isTokenLicensedByAddress(address, collectionAddress, tokenId) {
try {
const licensedTokens = await this.getLicensedTokens(address);
const tokenIdStr = tokenId.toString();
const hasLicense = licensedTokens.some(
(token) => token.collectionAddress.toLowerCase() === collectionAddress.toLowerCase() && token.tokenId.toString() === tokenIdStr
);
return hasLicense;
} catch (error) {
console.error("Error checking token license:", error);
return false;
}
}
/**
* Check if a token is properly licensed by the current wallet
* @param collectionAddress The collection address to check
* @param tokenId The token ID to check
* @returns Boolean indicating whether the token is properly licensed by the current wallet
*/
async isLicensedToken(collectionAddress, tokenId) {
try {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const tokenExists = await this.culturaDigitalAssetClient.ownerOf(tokenId).catch(() => null);
if (!tokenExists) {
return false;
}
const hasLicense = await this.isTokenLicensedByAddress(
this.walletClient.account.address,
collectionAddress,
tokenId
);
return hasLicense;
} catch (error) {
console.error("Error checking if token is licensed:", error);
return false;
}
}
/**
* Check if a Rights Bound Account corresponds to a verified asset
* @param rightsBoundAccount The Rights Bound Account address to check
* @returns Boolean indicating whether the RBA corresponds to a verified asset
*
* @remarks
* This method uses the RightsBoundAccountClient to get the associated
* digital asset information, then checks the on-chain verification level.
* This approach is more reliable than depending on subgraph indexing.
*/
async isRightsBoundAccountVerified(rightsBoundAccount) {
try {
const rbaClient = new RightsBoundAccountClient(
this.publicClient,
this.walletClient,
rightsBoundAccount
);
const { assetAddress, tokenId } = await rbaClient.getRightsBoundAccountAsset();
const level = await this.attestationServiceClient.getDigitalAssetLevel(assetAddress, tokenId);
return level >= 2;
} catch (error) {
console.error("Error checking if Rights Bound Account is verified:", error);
return false;
}
}
/**
* (Convenience Function) Create and attest a Licensed Creative Asset in one step.
* This method allows for creation of licenses for both Cultura and external NFTs.
*
* @param licensedAssetDetails License details including name, description, and terms
* @param licenseeSignature The licensee's signature validating acceptance of terms
* @param schemaUID Schema UID to use for the attestation
* @param bondAmount Amount to bond for the attestation (defaults to 1.1 tokens in wei)
* @param assetClass The asset class assigned to this license (higher means more permissions)
* @param parentRights Array of parent rights information for derivative works
* @param externalNFT Optional information about an external NFT being licensed
* @param termsURI Optional URI pointing to the terms document (defaults to the imageUrl or a dummy value)
* @returns Object containing the newly created asset details, attestation info, and compliance status
*
* @remarks
* **Note:** This is a **convenience function** specific to the mock protocol that
* combines the minting and attestation steps for a Licensed Creative Asset.
* **Crucially, it requires that `licenseDigitalAsset` has already been called**
* for each parent asset involved to register the license grant within the mock contract.
* This function *checks* for that pre-existing license state; it does *not* perform
* the initial licensing simulation itself.
*
* For a clearer understanding of the individual protocol interactions, refer to the
* step-by-step flow:
* 1. `licenseDigitalAsset` (for each parent)
* 2. `sdk.culturaDigitalAsset.mintDigitalAsset`
* 3. `sdk.attestationService.attest`
*
* This function performs the following actions:
* 1. **Checks** if a license has been registered for the parent asset(s) via prior
* calls to `licenseDigitalAsset` for the current wallet address.
* 2. Mints a new **Licensed Creative Asset** NFT via the `CulturaDigitalAsset` contract,
* linking it to the parents.
* 3. Immediately creates an **attestation** for the _newly minted_ asset via the `CAS`
* contract, using the provided `licenseeSignature`, `schemaUID`, `bondAmount`, and `assetClass`.
* 4. Returns the `licensedAssetId` (the tokenId of the new asset) and `attestationInfo`
* (including the `attestationUid`).
*
* It includes transaction state tracking (`transactionState`) to indicate success or failure.
* Use the `externalNFT` parameter if the license pertains to an asset outside the
* Cultura `CulturaDigitalAsset` contract.
*
* @example
* ```typescript
* // Create a license for a derivative work
* const result = await mockLicensingClient.createLicensedAsset(
* {
* name: "Derivative Artwork License",
* description: "License for derivative work based on CryptoKitty #123",
* imageUrl: "https://example.com/license-image.jpg"
* },
* {
* // Licensee signature details
* signer: "0xabc...",
* signature: "0x123...",
* deadline: BigInt(Date.now() + 3600000) // 1 hour from now
* },
* "0xschema123...", // Schema UID
* BigInt("1100000000000000000"), // 1.1 tokens bond amount
* BigInt(2), // Asset class 2
* [
* {
* rightsBoundAccount: "0xRightsBoundAccount...",
* royaltySplit: BigInt(10) // 10% royalty split
* }
* ]
* );
*
* console.log(`New licensed asset created with ID: ${result.licensedAssetId}`);
* console.log(`Attestation UID: ${result.attestationInfo.attestationUid}`);
* ```
*/
async createLicensedAsset(licensedAssetDetails, licenseeSignature, schemaUID, bondAmount = BigInt("1100000000000000000"), classId, parentRights, externalNFT, termsURI) {
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const account = this.walletClient.account;
let transactionState = "initial";
let newTokenId = null;
try {
for (const parentRight of parentRights) {
const isParentVerified = await this.isRightsBoundAccountVerified(
parentRight.rightsBoundAccount
);
if (!isParentVerified) {
throw new Error(
`Parent Rights Bound Account ${parentRight.rightsBoundAccount} is not associated with a verified asset.`
);
}
}
transactionState = "parentChecked";
const finalTermsURI = termsURI || "ipfs://dummy-terms-uri";
const tokenMetadata = {
name: licensedAssetDetails.name,
description: licensedAssetDetails.description,
image: licensedAssetDetails.imageUrl || ""
};
newTokenId = await this.culturaDigitalAssetClient.mintDigitalAsset(
account.address,
licensedAssetDetails.name,
licensedAssetDetails.description,
parentRights,
finalTermsURI,
tokenMetadata
);
transactionState = "tokenMinted";
const licenseData = (0, import_viem9.stringToHex)(
JSON.stringify({
parentRights: parentRights.map((pr) => ({
rightsBoundAccount: pr.rightsBoundAccount,
royaltySplit: pr.royaltySplit.toString()
})),
...externalNFT && {
externalNFT: {
collection: externalNFT.collection,
tokenId: externalNFT.tokenId.toString(),
owner: externalNFT.owner
}
}
})
);
console.log("Creating attestation with delegated attestation call...");
const attestationRequest = {
schema: schemaUID,
data: {
recipient: account.address,
expirationTime: BigInt(Math.floor(Date.now() / 1e3) + 365 * 24 * 60 * 60),
// 1 year
revocable: false,
refUID: "0x0000000000000000000000000000000000000000000000000000000000000000",
data: licenseData
}
};
const attestationInfo = await this.attestationServiceClient.delegatedAttest(
licenseeSignature,
attestationRequest,
this.culturaDigitalAssetAddress,
newTokenId,
classId,
bondAmount,
account.address
);
transactionState = "attestationCreated";
transactionState = "complete";
return {
licensedAssetId: newTokenId,
attestationInfo,
transactionState: "complete"
};
} catch (error) {
console.error("Error in createLicensedAsset:", error);
const lastState = transactionState;
transactionState = "failed";
if (lastState === "tokenMinted" && newTokenId !== null) {
console.error(
`Transaction interrupted: Token minted (ID: ${newTokenId}) but attestation failed. Manual recovery required.`
);
}
if (error instanceof Error) {
throw new Error(`Licensed asset creation failed at state '${lastState}': ${error.message}`);
} else {
throw new Error(`Licensed asset creation failed at state '${lastState}': Unknown error`);
}
}
}
/**
* Get assets with verified rights.
* @param limit Optional limit for the number of results to return (defaults to 20)
* @param offset Optional offset for pagination (defaults to 0)
* @returns Object containing an array of verified assets and the total count.
*
* @remarks
* This method uses the query system to retrieve digital assets that have been
* verified (e.g., reached a certain level or status within the protocol).
* The method returns details about each asset including its tokenId, name,
* description, collection address, owner, attestation UID, and assetClass.
*
* Verified assets are those that have successfully passed the verification process,
* meaning they comply with all licensing terms of their parent assets (if applicable).
* These assets can potentially be used as parent assets for further derivative works,
* depending on the protocol rules.
*
* @example
* ```typescript
* // Get verified licensed assets with pagination
* const result = await mockLicensingClient.getVerifiedLicensedAssets(10, 0);
*
* console.log(`Found ${result.total} verified assets`);
*
* // Display the assets
* result.assets.forEach(asset => {
* console.log(`Asset ID: ${asset.tokenId}`);
* console.log(`Name: ${asset.name}`);
* console.log(`Owner: ${asset.owner}`);
* });
* ```
*/
async getVerifiedLicensedAssets(limit = 20, offset = 0) {
try {
const verifiedRights = await this.queryClient.verifiedRights.getVerified(limit, offset);
const assets = verifiedRights.filter((right) => right.digitalAsset !== void 0).map((right) => right.digitalAsset);
return {
assets,
total: assets.length
};
} catch (error) {
console.error("Error querying verified assets:", error);
return {
assets: [],
total: 0
};
}
}
};
// src/resources/verifierModule.ts
var import_viem10 = require("viem");
var VerifierModuleClient = class {
constructor(publicClient, walletClient, contractAddress) {
this.publicClient = publicClient;
this.walletClient = walletClient;
this.contractAddress = contractAddress;
}
/**
* Distributes rewards from the bound account to the verifier module
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @param boundAccount The address of the CulturaRightsBoundAccount
* @param period The payment period to claim from
* @returns Transaction hash
*/
async distributeRewards(digitalAssetAddress, digitalAssetId, boundAccount, period) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress) || !(0, import_viem10.isAddress)(boundAccount)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "distributeRewards",
args: [digitalAssetAddress, digitalAssetId, boundAccount, period],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${hash}`);
}
return hash;
}
/**
* Allows a verifier to claim their rewards for a specific verified right
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @returns Transaction hash
*/
async claimRewards(digitalAssetAddress, digitalAssetId) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "claimRewards",
args: [digitalAssetAddress, digitalAssetId],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${hash}`);
}
return hash;
}
/**
* Calculate the claimable rewards for a verifier for a specific verified right
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @param verifier The address of the verifier
* @returns The amount of tokens the verifier can claim
*/
async calculateClaimableRewards(digitalAssetAddress, digitalAssetId, verifier) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress) || !(0, import_viem10.isAddress)(verifier)) {
throw new Error("Invalid address format");
}
return await this.publicClient.readContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "calculateClaimableRewards",
args: [digitalAssetAddress, digitalAssetId, verifier]
});
}
/**
* Get the amount of tokens a verifier has bonded for a specific verified right
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @param verifier The address of the verifier
* @returns The amount of tokens bonded by the verifier
*/
async getVerifierBond(digitalAssetAddress, digitalAssetId, verifier) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress) || !(0, import_viem10.isAddress)(verifier)) {
throw new Error("Invalid address format");
}
return await this.publicClient.readContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "getVerifierBond",
args: [digitalAssetAddress, digitalAssetId, verifier]
});
}
/**
* Get the total amount of tokens bonded for a specific verified right
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @returns The total amount of tokens bonded for the verified right
*/
async getTotalBondedAmount(digitalAssetAddress, digitalAssetId) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
return await this.publicClient.readContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "getTotalBondedAmount",
args: [digitalAssetAddress, digitalAssetId]
});
}
/**
* Get the total rewards (collected fees) for a specific verified right
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @returns The total amount of rewards accumulated for the verified right
*/
async getTotalRewards(digitalAssetAddress, digitalAssetId) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
const encodedData = (0, import_viem10.encodeAbiParameters)(
[{ type: "address" }, { type: "uint256" }],
[digitalAssetAddress, digitalAssetId]
);
const vrId = (0, import_viem10.keccak256)(encodedData);
return await this.publicClient.readContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "vrRewards",
args: [vrId]
});
}
/**
* Manually send fees to the verifier module for a specific verified right
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @param amount The amount of fees to send
* @param sender The address of the sender
* @returns Transaction hash
*/
async receiveFees(digitalAssetAddress, digitalAssetId, amount, sender) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress) || !(0, import_viem10.isAddress)(sender)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "receiveFees",
args: [digitalAssetAddress, digitalAssetId, amount, sender],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${hash}`);
}
return hash;
}
/**
* Allows a verifier to bond tokens for a specific digital asset
* @param digitalAssetAddress The address of the digital asset contract
* @param digitalAssetId The token ID of the digital asset
* @param amount The amount of tokens to bond
* @returns Transaction hash
*/
async bondTokens(digitalAssetAddress, digitalAssetId, amount) {
if (!(0, import_viem10.isAddress)(digitalAssetAddress)) {
throw new Error("Invalid address format");
}
if (!this.walletClient.account) {
throw new Error("No account connected");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: VerifierModuleAbi,
functionName: "registerVerifierBond",
args: [digitalAssetAddress, digitalAssetId, this.walletClient.account.address, amount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
const receipt = await this.publicClient.waitForTransactionReceipt({
hash
});
if (receipt.status !== "success") {
throw new Error(`Transaction failed with hash: ${hash}`);
}
return hash;
}
};
// src/adapters/PrivySmartWalletAdapter.ts
var import_viem11 = require("viem");
var PrivySmartWalletAdapter = class {
// transport is likely not needed as sub-clients use publicClient for reads
constructor(privyClient) {
this.type = "privy-smart-wallet-adapter";
if (!privyClient) {
throw new Error("Privy client cannot be null or undefined.");
}
this.privyClient = privyClient;
this.account = privyClient.account ? {
address: privyClient.account.address,
type: "json-rpc"
// Assuming standard JSON-RPC type for compatibility
} : void 0;
this.chain = privyClient.chain;
}
// Implement writeContract by encoding data and passing minimal params to Privy client
async writeContract(params) {
if (!this.account) {
throw new Error("Adapter not initialized with an account.");
}
if (!this.privyClient) {
throw new Error("Privy client is not available.");
}
const encodedData = (0, import_viem11.encodeFunctionData)({
abi: params.abi,
functionName: params.functionName,
args: params.args
});
const paramsForPrivy = {
account: this.account,
// Required by Privy/permissionless
to: params.address,
// The contract address
data: encodedData,
// The encoded function call
value: params.value,
// Optional ETH value
chain: this.chain
// Optional chain context
};
try {
const txHash = await this.privyClient.sendTransaction(paramsForPrivy);
return txHash;
} catch (error) {
console.error("Error sending transaction via Privy adapter:", error);
throw error;
}
}
// Other WalletClient methods (signMessage, etc.) are not implemented
};
// src/resources/proofOfPopularity.ts
var import_viem12 = require("viem");
var POPModuleClient = class {
/**
* Creates an instance of the POPModuleClient.
* @param publicClient - The Viem Public Client.
* @param contractAddress - The contract address of the POP module.
* @param walletClient - The Viem Wallet Client (optional).
*/
constructor(publicClient, contractAddress, walletClient) {
this.publicClient = publicClient;
this.contractAddress = contractAddress;
this.walletClient = walletClient;
// Default decimals for ERC20 tokens (most common)
this.DEFAULT_DECIMALS = 18;
}
/**
* Votes on an attestation.
* @param attestationUID - The UID of the attestation to vote on.
* @param amount - The amount of tokens to vote with (in ether).
* @returns The transaction hash.
*
* @example
* ```ts
* // Vote 10 tokens on an attestation
* const txHash = await popClient.voteOnAttestation(
* "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
* "10"
* );
* console.log(`Vote transaction: ${txHash}`);
* ```
*/
async voteOnAttestation(attestationUID, amount) {
if (!this.walletClient || !this.walletClient.account) {
throw new Error("WalletClient required for this action.");
}
const voteAmount = (0, import_viem12.parseUnits)(amount, this.DEFAULT_DECIMALS);
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "voteOnAttestation",
args: [attestationUID, voteAmount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
return hash;
}
/**
* Requests withdrawal of voted tokens for an attestation.
* @param attestationUID - The UID of the attestation.
* @param amount - The amount of tokens to request withdrawal for (in ether).
* @returns The transaction hash.
*
* @example
* ```ts
* // Request withdrawal of 5 tokens from an attestation
* const txHash = await popClient.requestVoteWithdrawal(
* "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
* "5"
* );
* console.log(`Withdrawal request transaction: ${txHash}`);
* ```
*/
async requestVoteWithdrawal(attestationUID, amount) {
if (!this.walletClient || !this.walletClient.account) {
throw new Error("WalletClient required for this action.");
}
const withdrawalAmount = (0, import_viem12.parseUnits)(amount, this.DEFAULT_DECIMALS);
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "requestVoteWithdrawal",
args: [attestationUID, withdrawalAmount],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
return hash;
}
/**
* Withdraws voted tokens after the timelock period.
* @param attestationUID - The UID of the attestation.
* @returns The transaction hash.
*
* @example
* ```ts
* // Withdraw tokens after timelock period
* const txHash = await popClient.withdrawVotes(
* "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
* );
* console.log(`Withdrawal transaction: ${txHash}`);
* ```
*/
async withdrawVotes(attestationUID) {
if (!this.walletClient || !this.walletClient.account) {
throw new Error("WalletClient required for this action.");
}
const { request } = await this.publicClient.simulateContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "withdrawVotes",
args: [attestationUID],
account: this.walletClient.account
});
const hash = await this.walletClient.writeContract(request);
return hash;
}
/**
* Gets the popularity score of an attestation.
* @param attestationUID - The UID of the attestation.
* @returns The popularity score as a string (in ether).
*
* @example
* ```ts
* // Get popularity score of an attestation
* const score = await popClient.getPopularityScore(
* "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
* );
* console.log(`Popularity score: ${score}`);
* ```
*/
async getPopularityScore(attestationUID) {
const score = await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "getPopularityScore",
args: [attestationUID]
});
return (0, import_viem12.formatUnits)(score, this.DEFAULT_DECIMALS);
}
/**
* Gets the amount of tokens a user has voted on an attestation.
* @param attestationUID - The UID of the attestation.
* @param user - The address of the user.
* @returns The voted amount as a string (in ether).
*
* @example
* ```ts
* // Get amount voted by a user on an attestation
* const votedAmount = await popClient.getUserVotedAmount(
* "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
* "0xabcdef1234567890abcdef1234567890abcdef1234"
* );
* console.log(`User voted: ${votedAmount} tokens`);
* ```
*/
async getUserVotedAmount(attestationUID, user) {
const amount = await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "getUserVotedAmount",
args: [attestationUID, user]
});
return (0, import_viem12.formatUnits)(amount, this.DEFAULT_DECIMALS);
}
/**
* Gets the total amount of tokens voted on an attestation.
* @param attestationUID - The UID of the attestation.
* @returns The total voted amount as a string (in ether).
*/
async getTotalVotedAmount(attestationUID) {
const amount = await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "getTotalVotedAmount",
args: [attestationUID]
});
return (0, import_viem12.formatUnits)(amount, this.DEFAULT_DECIMALS);
}
/**
* Gets the unlock time for a user's voted tokens.
* @param attestationUID - The UID of the attestation.
* @param user - The address of the user.
* @returns The unlock time as a Unix timestamp (BigInt).
*/
async getUnlockTime(attestationUID, user) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "getUnlockTime",
args: [attestationUID, user]
});
}
/**
* Gets the top attestations by popularity score.
* @param count - The maximum number of attestations to return.
* @returns An array of attestation UIDs.
*
* @example
* ```ts
* // Get top 3 attestations
* const topAttestations = await popClient.getTopAttestations(3);
* console.log("Top attestations:", topAttestations);
* ```
*/
async getTopAttestations(count) {
return await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "getTopAttestations",
args: [BigInt(count)]
});
}
/**
* Gets the top 3 attestations and their scores.
* @returns An object containing arrays of the top 3 attestation UIDs and their scores (as strings in ether).
*
* @example
* ```ts
* // Get top attestations with their scores
* const { attestations, scores } = await popClient.getTopAttestationsWithScores();
*
* // Display top attestations and their scores
* attestations.forEach((attestationUID, index) => {
* console.log(`Attestation ${index + 1}: ${attestationUID} - Score: ${scores[index]}`);
* });
* ```
*/
async getTopAttestationsWithScores() {
const result = await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "getTopAttestationsWithScores"
});
const attestations = result[0];
const scoresBigInt = result[1];
const scores = scoresBigInt.map((score) => (0, import_viem12.formatUnits)(score, this.DEFAULT_DECIMALS));
const filteredAttestations = attestations.filter(
(att) => att !== "0x0000000000000000000000000000000000000000000000000000000000000000"
);
return { attestations: [...filteredAttestations], scores: [...scores] };
}
/**
* Gets the maximum vote amount allowed per user per attestation.
* @returns The maximum vote amount as a string (in ether).
*/
async getMaxVotePerUser() {
const maxVote = await this.publicClient.readContract({
address: this.contractAddress,
abi: POPAbi,
functionName: "maxVotePerUser"
});
return (0, import_viem12.formatUnits)(maxVote, this.DEFAULT_DECIMALS);
}
};
// src/client.ts
function toEnvironmentName(chainNameOrId) {
if (typeof chainNameOrId === "number") {
const chainName = getChainName(chainNameOrId);
return Object.keys(ENVIRONMENTS).includes(chainName) ? chainName : "testnet";
}
if (Object.keys(ENVIRONMENTS).includes(chainNameOrId)) {
return chainNameOrId;
}
console.warn(`Unrecognized environment: ${chainNameOrId}, defaulting to testnet`);
return "testnet";
}
var CulturaSDK = class _CulturaSDK {
constructor(config) {
this._attestationService = null;
this._schemaRegistry = null;
this._culturaDigitalAsset = null;
this._rightsBoundAccount = null;
this._royalty = null;
this._signatureUtils = null;
this._verifierModule = null;
this._bondToken = null;
this._mockLicensingProtocol = null;
this._query = null;
this._popModule = null;
if (!config.chain) {
config.chain = "testnet";
}
const chainId = config.chain ? getChainId(config.chain) : culturaChain.id;
this.config = {
...config,
chain: chainId
};
if (!this.config.transport) {
const envName2 = toEnvironmentName(chainId);
const rpcUrl = ENVIRONMENTS[envName2]?.rpcUrl || culturaChain.rpcUrls.default.http[0];
this.config.transport = (0, import_viem13.http)(rpcUrl);
}
const envName = toEnvironmentName(chainId);
const specificChain = createChainConfig(envName);
const clientConfig = {
chain: specificChain,
transport: this.config.transport
};
this.publicClient = (0, import_viem13.createPublicClient)(clientConfig);
const contractsEnvName = toEnvironmentName(chainId);
const envAddresses = ENVIRONMENTS[contractsEnvName]?.contracts || {};
this.config.contracts = {
...envAddresses,
...config.contracts
// Allow overrides if explicitly provided
};
if (config.wallet) {
if (config.wallet.chain?.id !== void 0 && config.wallet.chain.id !== chainId) {
console.warn(
`Warning: Provided wallet's chain (${config.wallet.chain.id}) differs from configured chain (${chainId}). This might cause issues.`
);
}
this.walletClient = config.wallet;
} else if (config.account) {
this.walletClient = (0, import_viem13.createWalletClient)({
...clientConfig,
account: config.account
});
}
if (this.config.contracts?.bondToken && this.walletClient) {
this._bondToken = new BondTokenClient(
this.publicClient,
this.walletClient,
this.config.contracts.bondToken
);
}
if (this.config.contracts?.mockLicensingProtocol && this.walletClient) {
if (!this.config.contracts.culturaDigitalAsset) {
throw new Error(
"Cultura Digital Asset contract address required for Mock Licensing Protocol"
);
}
if (!this.config.contracts.attestationService) {
throw new Error("Attestation Service contract address required for Mock Licensing Protocol");
}
this._mockLicensingProtocol = new MockLicensingProtocolClient(
this.publicClient,
this.walletClient,
this.config.contracts.mockLicensingProtocol,
this.config.contracts.culturaDigitalAsset,
this.config.contracts.attestationService,
toEnvironmentName(this.config.chain || "testnet")
);
}
}
/**
* Get the current chain configuration
*/
get chain() {
return this.publicClient.chain;
}
/**
* Set the rights bound account address for the rightsBoundAccount client
* This is needed when working with licensedAssets created via mockLicenseRight
*
* @param rightsBoundAccountAddress - The address of the Rights Bound Account
*/
setRightsBoundAccount(rightsBoundAccountAddress) {
if (!rightsBoundAccountAddress || !(0, import_viem13.isAddress)(rightsBoundAccountAddress)) {
throw new Error("Invalid rights bound account address");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Rights Bound Account operations");
}
this._rightsBoundAccount = new RightsBoundAccountClient(
this.publicClient,
this.walletClient,
rightsBoundAccountAddress
);
}
/**
* Create a new SDK instance
* @param config SDK configuration
*/
static create(config = {}) {
if (!config.chain) {
config.chain = "testnet";
}
return new _CulturaSDK(config);
}
/**
* Create a new SDK instance with a wallet
* @param ethereum Ethereum provider (e.g., window.ethereum)
* @param config Additional SDK configuration
*/
static createWithWallet(ethereum, config = {}) {
const chainToUse = config.chain || "testnet";
const chainId = typeof chainToUse === "string" ? getChainId(chainToUse) : chainToUse;
const envName = toEnvironmentName(chainId);
const specificChain = createChainConfig(envName);
const walletClient = (0, import_viem13.createWalletClient)({
chain: specificChain,
transport: (0, import_viem13.custom)(ethereum),
account: config.account
});
return new _CulturaSDK({ ...config, wallet: walletClient });
}
/**
* Create a new SDK instance with a specific account
* @param account Ethereum account address or Viem Account object created with privateKeyToAccount()
* @param config Additional SDK configuration
* @example
* ```typescript
* // With an address (limited signing capability)
* const sdk = CulturaSDK.createWithAccount('0x123...');
*
* // With a private key (full signing capability)
* import { privateKeyToAccount } from 'viem/accounts';
* const account = privateKeyToAccount('0xYourPrivateKeyHere');
* const sdk = CulturaSDK.createWithAccount(account);
* ```
*/
static createWithAccount(account, config = {}) {
return new _CulturaSDK({ ...config, account });
}
/**
* Create a new SDK instance with a Privy Smart Wallet Client
* @param privyClient The Privy SmartWalletClientType instance
* @param config Additional SDK configuration
*/
static createWithSmartWalletClient(privyClient, config = {}) {
if (!privyClient?.account?.address) {
throw new Error("Privy client must have an account address.");
}
const adapter = new PrivySmartWalletAdapter(privyClient);
const chainToUse = config.chain || adapter.chain?.id || "testnet";
const chainId = typeof chainToUse === "string" ? getChainId(chainToUse) : chainToUse;
const sdkConfig = {
...config,
chain: chainId,
wallet: adapter,
// Cast the adapter
account: adapter.account?.address
// Get account from adapter
};
return new _CulturaSDK(sdkConfig);
}
/**
* Access the Attestation Service client for creating and verifying attestations.
*
* The Attestation Service manages the creation and verification of attestations
* that prove Digital Asset ownership and rights.
*
* @returns The Attestation Service client instance
*
* @example
* ```typescript
* // Create a attestation
* const attestationUID = await sdk.attestationService.attest(
* attestationRequest,
* rightsBoundAccountAddress,
* tokenId,
* assetClass,
* bondAmount
* );
* ```
*/
get attestationService() {
if (!this._attestationService) {
if (!this.config.contracts?.attestationService) {
throw new Error("Attestation Service contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Attestation Service operations");
}
this._attestationService = new AttestationServiceClient(
this.publicClient,
this.walletClient,
this.config.contracts.attestationService
);
}
return this._attestationService;
}
/**
* Get the SchemaRegistry client instance
*/
get schemaRegistry() {
if (!this._schemaRegistry) {
if (!this.config.contracts?.schemaRegistry) {
throw new Error("SchemaRegistry contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for SchemaRegistry operations");
}
this._schemaRegistry = new SchemaRegistryClient(
this.publicClient,
this.walletClient,
this.config.contracts.schemaRegistry
);
}
return this._schemaRegistry;
}
/**
* Get the CulturaDigitalAsset client instance
*/
get culturaDigitalAsset() {
if (!this._culturaDigitalAsset) {
if (!this.config.contracts?.culturaDigitalAsset) {
throw new Error("Digital Asset contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Digital Asset operations");
}
this._culturaDigitalAsset = new CulturaDigitalAssetClient(
this.publicClient,
this.walletClient,
this.config.contracts.culturaDigitalAsset
);
}
return this._culturaDigitalAsset;
}
/**
* Get the culturaDigitalAsset client instance (alias for culturaDigitalAsset for backward compatibility)
* @deprecated Use culturaDigitalAsset instead
*/
get digitalAsset() {
return this.culturaDigitalAsset;
}
/**
* Get the Rights Bound Account client instance
* This needs to be set manually using setRightsBoundAccount before use
*/
get rightsBoundAccount() {
if (!this._rightsBoundAccount) {
throw new Error("Rights Bound Account not set - call setRightsBoundAccount first");
}
return this._rightsBoundAccount;
}
/**
* Get the Royalty client instance
*/
get royalty() {
if (!this._royalty) {
if (!this.config.contracts?.royaltyModule) {
throw new Error("Royalty contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Royalty operations");
}
this._royalty = new RoyaltyClient(
this.publicClient,
this.walletClient,
this.config.contracts.royaltyModule
);
}
return this._royalty;
}
/**
* Get the Signature Utils client instance
*/
get signatureUtils() {
if (!this._signatureUtils) {
if (!this.config.contracts?.signatureUtils) {
throw new Error("Signature Utils contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Signature Utils operations");
}
this._signatureUtils = new SignatureUtilsClient(
this.publicClient,
this.config.contracts.signatureUtils
);
}
return this._signatureUtils;
}
/**
* Get the Verifier Module client instance
*/
get verifierModule() {
if (!this._verifierModule) {
if (!this.config.contracts?.verifierModule) {
throw new Error("Verifier Module contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Verifier Module operations");
}
this._verifierModule = new VerifierModuleClient(
this.publicClient,
this.walletClient,
this.config.contracts.verifierModule
);
}
return this._verifierModule;
}
/**
* Get the balance of the connected wallet
*/
async getWalletBalance() {
if (!this.walletClient?.account) {
throw new Error("No account connected");
}
return this.getBalance(this.walletClient.account.address);
}
/**
* Get the balance of any address
* @param address Ethereum address
*/
async getBalance(address) {
if (!(0, import_viem13.isAddress)(address)) {
throw new Error("Invalid address format");
}
return await this.publicClient.getBalance({
address: (0, import_viem13.getAddress)(address)
});
}
/**
* Get the Query client instance for querying indexed blockchain data
*/
get query() {
if (!this._query) {
const envName = toEnvironmentName(this.config.chain);
this._query = new QueryClient(envName);
}
return this._query;
}
/**
* Get the Bond Token client instance
*/
get bondToken() {
if (!this._bondToken) {
if (!this.config.contracts?.bondToken) {
throw new Error("Bond Token contract address not configured");
}
if (!this.walletClient) {
throw new Error("Wallet client required for Bond Token operations");
}
this._bondToken = new BondTokenClient(
this.publicClient,
this.walletClient,
this.config.contracts.bondToken
);
}
return this._bondToken;
}
/**
* Get the Mock Licensing Protocol client instance
*/
get mockLicensingProtocol() {
if (!this._mockLicensingProtocol) {
if (!this.walletClient) {
throw new Error("Wallet client required for Mock Licensing Protocol operations");
}
if (!this.config.contracts?.mockLicensingProtocol) {
throw new Error("Mock Licensing Protocol contract address not configured");
}
if (!this.config.contracts.culturaDigitalAsset) {
throw new Error(
"Cultura Digital Asset contract address required for Mock Licensing Protocol"
);
}
if (!this.config.contracts.attestationService) {
throw new Error("Attestation Service contract address required for Mock Licensing Protocol");
}
this._mockLicensingProtocol = new MockLicensingProtocolClient(
this.publicClient,
this.walletClient,
this.config.contracts.mockLicensingProtocol,
this.config.contracts.culturaDigitalAsset,
this.config.contracts.attestationService,
toEnvironmentName(this.config.chain || "testnet")
);
}
return this._mockLicensingProtocol;
}
/**
* Get the POP Module client instance
*/
get pop() {
if (!this._popModule) {
if (!this.config.contracts?.POP) {
throw new Error("Proof of Popularity contract address not configured");
}
this._popModule = new POPModuleClient(
this.publicClient,
this.config.contracts.POP,
this.walletClient
);
}
return this._popModule;
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CulturaSDK,
ENVIRONMENTS,
QueryClient,
createChainConfig,
culturaChain,
getChainDisplayName,
getNetworkName,
utils
});