import { CulturaSDK } from "@cultura/sdk";
import { parseEther } from "viem"; // Example utility
/**
* Attests an asset, moving it from Level 0 to Level 1.
* Assumes the SDK is initialized for the ASSET OWNER.
*/
async function attestAsset(
sdk: CulturaSDK,
recipientAddress: `0x${string}`, // Usually the owner's address
assetAddress: `0x${string}`,
assetId: bigint,
grade: bigint, // e.g., 3n for Grade C
bondAmount: bigint // e.g., parseEther("0.0001") for Grade C bond fee
) {
try {
// --- 1. Ensure Schema Exists ---
// Define the schema string used for your attestations
const schemaStr =
"string digitalAssetName, string digitalAssetDescription, uint256 grade"; // Example
const isRevocable = true; // Or false, depending on your use case
const schemaUID = await sdk.schemaRegistry.getOrRegisterSchema(
schemaStr,
isRevocable
);
console.log("Using Schema UID:", schemaUID);
// --- 2. Approve Bond Token Spending ---
const casAddress = sdk.config.contracts?.attestationService;
if (!casAddress) throw new Error("CAS address not configured in SDK");
console.log(
`Approving ${bondAmount.toString()} bond tokens for CAS (${casAddress})...`
);
// Ensure the owner has sufficient bond tokens before approving
const approveTxHash = await sdk.bondToken.approve(casAddress, bondAmount);
console.log("Bond Token Approval Tx:", approveTxHash);
// It's crucial to wait for this transaction to be mined before proceeding
await sdk.publicClient.waitForTransactionReceipt({ hash: approveTxHash });
console.log("Approval confirmed.");
// --- 3. Prepare Attestation Request ---
// Encode data according to your schema if necessary. For the example schema,
// you might encode the asset name, description, and grade again here,
// or leave data as '0x' if the core info is implicitly linked via assetId.
const encodedData = "0x" as `0x${string}`; // Placeholder
const attestationRequest = {
schema: schemaUID,
data: {
recipient: recipientAddress,
expirationTime: 0n, // 0 for non-expiring attestations
revocable: isRevocable,
refUID:
"0x0000000000000000000000000000000000000000000000000000000000000000" as `0x${string}`, // Use if referencing another attestation
data: encodedData,
},
};
// --- 4. Call Attest ---
console.log("Submitting attestation to CAS...");
// The attest method waits for the transaction and returns the UID directly
const attestationUid = await sdk.attestationService.attest(
attestationRequest,
assetAddress,
assetId,
grade,
bondAmount // This is the fee/initial bond required by the grade
);
console.log(`Attestation Successful! UID: ${attestationUid}`);
console.log(`Asset is now Level 1 (Attested)`);
// Note: The RightsBoundAccount is deployed automatically during attest.
// You can query for it later using the attestation UID or asset details if needed.
// For simplicity, we're not retrieving it explicitly here.
return { attestationUid }; // Return only the UID for this example
} catch (error) {
console.error("Error during attestation:", error);
throw error; // Re-throw for higher-level handling
}
}
/**
* Verifies an existing Level 1 attestation, potentially promoting it to Level 2.
* Assumes the SDK is initialized for the VERIFIER.
*/
async function verifyAssetAttestation(
sdk: CulturaSDK, // SDK instance initialized for the VERIFIER
attestationUID: `0x${string}`,
verificationBond: bigint // Amount the verifier wants to bond, e.g., parseEther("0.01")
) {
try {
// --- 1. Approve Bond Token Spending ---
const casAddress = sdk.config.contracts?.attestationService;
if (!casAddress) throw new Error("CAS address not configured in SDK");
console.log(
`Approving ${verificationBond.toString()} tokens for CAS (${casAddress})...`
);
// Ensure the verifier has sufficient bond tokens
const approveTxHash = await sdk.bondToken.approve(
casAddress,
verificationBond
);
console.log("Approval Tx:", approveTxHash);
await sdk.publicClient.waitForTransactionReceipt({ hash: approveTxHash });
console.log("Approval confirmed.");
// --- 2. Call Verify Attestation ---
console.log(`Verifying attestation ${attestationUID}...`);
const verifyTxHash = await sdk.attestationService.verifyAttestation(
attestationUID,
verificationBond
);
console.log("Verify Tx:", verifyTxHash);
const receipt = await sdk.publicClient.waitForTransactionReceipt({
hash: verifyTxHash,
});
if (receipt.status !== "success") {
throw new Error("Verification transaction failed");
}
console.log(`Verification submitted successfully.`);
// --- 3. Check the new level (Optional - requires querying state) ---
// This requires knowing the assetAddress and assetId associated with the UID.
// You'd typically fetch this using the attestationUID via the SDK query client or getAttestation.
// Example:
// const attestationData = await sdk.attestationService.getAttestation(attestationUID);
// if (attestationData) {
// const newLevel = await sdk.attestationService.getDigitalAssetLevel(
// attestationData.digitalAssetAddress,
// attestationData.digitalAssetId
// );
// console.log(`Asset level is now: ${newLevel}`);
// if (newLevel === 2) {
// console.log("Asset promoted to Level 2 (Verified Rights / Licensable)!");
// }
// }
return verifyTxHash;
} catch (error) {
console.error("Error during verification:", error);
throw error; // Re-throw for higher-level handling
}
}