> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cultura.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Update (v0.2.0)

> Migration guide for Cultura SDK v0.2.0 - Key changes, new features, and breaking changes.

## Product Update - Cultura SDK v0.2.0 Released

This release implements a new streamlined royalty claiming process for off-chain payments and UX improvements to make implementation and sponsorship easier. The parent asset structure has been refactored to use Rights Bound Account addresses, simplifying derivative asset creation. Enhanced query capabilities provide richer data, and new utility functions improve developer experience.

This release represents a major update to the Cultura SDK with significant architectural improvements, new features, and some breaking changes. This guide will help you migrate from v0.1.10 to v0.2.0.

## Major Changes & New Features

### 1. **BREAKING CHANGE: Parent Asset Structure Refactor**

The most significant change in v0.2.0 is the restructuring of parent asset handling for derivative works.

#### What Changed

* **v0.1.10**: Used `ParentDigitalAsset` type with `parentCollection`, `parentDigitalAssetId`, `owner`, `royaltySplit`
* **v0.2.0**: Uses `ParentInfo` type with `rightsBoundAccount`, `royaltySplit`

#### Migration Required

**Old v0.1.10 Structure:**

```typescript theme={null}
// v0.1.10 - Parent asset info included collection, tokenId, and owner
const parentAssets: ParentDigitalAsset[] = [
  {
    parentCollection: "0x123...",
    parentDigitalAssetId: 42n,
    owner: "0xabc...",
    royaltySplit: 75n,
  },
];

await sdk.culturaDigitalAsset.mintDigitalAsset(
  to,
  name,
  description,
  parentAssets, // Old structure
  termsData,
  tokenURI
);
```

**New v0.2.0 Structure:**

```typescript theme={null}
// v0.2.0 - Parent asset info uses Rights Bound Account address
const parentInfo: ParentInfo[] = [
  {
    rightsBoundAccount: "0xdef...", // RBA address of parent asset
    royaltySplit: 75n,
  },
];

await sdk.culturaDigitalAsset.mintDigitalAsset(
  to,
  name,
  description,
  parentInfo, // New structure
  termsData,
  tokenURI
);
```

#### How to Get Rights Bound Account Address

You can obtain the Rights Bound Account address for a parent asset in several ways:

```typescript theme={null}
// Method 1: Query from subgraph data
const parentAsset = await sdk.query.digitalAsset.getByContractAndTokenId(
  parentContractAddress,
  parentTokenId
);
const rightsBoundAccount = parentAsset?.rightsBoundAccount;

// Method 2: Query from verified rights data
const verifiedRights = await sdk.query.verifiedRights.getByDigitalAsset(
  parentContractAddress,
  parentTokenId.toString()
);
const rightsBoundAccount = verifiedRights?.rightsBoundAccount;

// Method 3: If you have attestation receipt from parent creation
const rightsBoundAccount =
  sdk.attestationService.getRightsBoundAccountFromReceipt(receipt);
```

### 2. Enhanced Query System with Richer Data

#### New Query Features

* **Enhanced Verification Data**: `verifiedRights` queries now include detailed `verifications` array with individual verifier information
* **Owner Token Counts**: `digitalAsset.owner` now includes `tokenCount` field
* **Nested Asset Information**: Better cross-referencing between digital assets and verified rights

#### Example of Enhanced Data Usage

```typescript theme={null}
// v0.2.0 - Access richer verification data
const verifiedRights = await sdk.query.verifiedRights.getAll(10, 0);
verifiedRights.forEach((right) => {
  console.log(`Asset: ${right.digitalAsset?.assetName}`);
  console.log(`Owner Token Count: ${right.digitalAsset?.owner.tokenCount}`);

  // New: Detailed verification information
  right.verifications.forEach((verification) => {
    console.log(`Verifier: ${verification.verifier.address}`);
    console.log(`Bond Amount: ${verification.bondAmount}`);
    console.log(`Timestamp: ${verification.timestamp}`);
    console.log(`Is Whitelisted: ${verification.verifier.isWhitelisted}`);
  });
});
```

### 3. New Utility Functions

#### Digital Asset and Verified Rights ID Generation

```typescript theme={null}
import { getDigitalAssetUID, getVerifiedRightsId } from "@cultura/sdk/utils";

// Generate unique identifiers for assets and rights
const digitalAssetUID = getDigitalAssetUID(contractAddress, tokenId);
const verifiedRightsId = getVerifiedRightsId(contractAddress, tokenId);

// Use these IDs for queries
const asset = await sdk.query.digitalAsset.getByUID(digitalAssetUID);
const rights = await sdk.query.verifiedRights.getById(verifiedRightsId);
```

### 4. Royalty System UX Improvements

#### New Off-Chain Payment Methods (Continued from v0.1.10)

The off-chain payment workflow introduced in v0.1.10 has been refined with improved UX:

```typescript theme={null}
// Report off-chain payment
await sdk.royalty.reportOffChainPayment(tokenId, periodIndex, amount, metadata);

// Accept off-chain payment by parent
await sdk.royalty.acceptOffChainPaymentByParent(
  tokenId,
  periodIndex,
  parentBoundAccount,
  signature,
  signerAddress,
  sponsorAddress
);

// Deny off-chain payment by parent
await sdk.royalty.denyOffChainPaymentByParent(
  tokenId,
  periodIndex,
  parentBoundAccount,
  signature,
  signerAddress
);
```

#### New Signature Helper Methods

```typescript theme={null}
// Generate signatures for off-chain payment acceptance
const acceptanceSignature =
  await sdk.royalty.signForAcceptOffChainPaymentByParent(
    rightsBoundAccount,
    totalAmount,
    period,
    sponsor
  );

// Generate signatures for off-chain payment denial
const denialSignature = await sdk.royalty.signForDenyOffChainPaymentByParent(
  tokenId,
  periodIndex,
  parentBoundAccount
);
```

### 5. **NEW: Sponsorship Support**

v0.2.0 introduces extensive sponsorship capabilities across the entire royalty and attestation system, enabling third parties to cover transaction costs and execute operations on behalf of others.

#### Delegated Royalty Operations

```typescript theme={null}
// Delegated royalty registration - sponsor registers royalty on behalf of asset owner
const registrationSignature =
  await sdk.royalty.signForDelegatedRegisterRoyaltyDue(
    tokenId,
    amountDue,
    startDate,
    endDate,
    royaltyInfoIndex
  );
await sponsorSDK.royalty.delegatedRegisterRoyaltyDue(
  tokenId,
  amountDue,
  startDate,
  endDate,
  royaltyInfoIndex,
  registrationSignature
);

// Delegated royalty payment - sponsor pays royalty on behalf of licensee
const paymentSignature = await sdk.royalty.signForDelegatedPayRoyalty(
  tokenId,
  amountDue,
  royaltyInfoIndex
);
await sponsorSDK.royalty.delegatedPayRoyalty(
  tokenId,
  amountPaid,
  periodIndex,
  culturaBoundAccount,
  signature,
  paymentSignature
);
```

#### Delegated Off-Chain Payment Flow

```typescript theme={null}
// Sponsor reports off-chain payment on behalf of licensee
const reportSignature = await sdk.royalty.signForDelegatedOffchainReportRoyalty(
  tokenId,
  royaltyInfoIndex,
  amount
);
await sponsorSDK.royalty.delegatedReportOffChainPayment(
  tokenId,
  periodIndex,
  amount,
  metadata,
  reportSignature
);

// Example from licensing flow - sponsor handles all off-chain payment operations
const offchainSignature =
  await licenseeSDK.royalty.signForDelegatedRegisterRoyaltyDue(
    licensedAssetId,
    offchainRoyaltyDue,
    offchainPeriodStartDate,
    offchainPeriodEndDate,
    offchainPeriodIndex
  );
await sponsorSDK.royalty.delegatedRegisterRoyaltyDue(
  licensedAssetId,
  offchainRoyaltyDue,
  offchainPeriodStartDate,
  offchainPeriodEndDate,
  offchainPeriodIndex,
  offchainSignature
);
```

#### Rights Bound Account Sponsorship

```typescript theme={null}
// Sponsor sets payment info on behalf of asset owner
const paymentSignature = await sdk.rightsBoundAccount.signForSetPaymentInfo(
  period,
  totalAmount,
  sponsorAddress
);

// Sponsor SDK executes the transaction
sponsorSDK.setRightsBoundAccount(rightsBoundAccountAddress);
await sponsorSDK.rightsBoundAccount.setPaymentInfo({
  totalAmount,
  sponsor: sponsorAddress,
  signature: paymentSignature,
  signer: assetOwnerAddress, // Original signer but sponsor executes
});
```

#### Attestation Sponsorship

```typescript theme={null}
// Sponsored attestation creation
const { attestationUid, rightsBoundAccount } =
  await sdk.attestationService.sponsoredAttest(
    attestationRequest,
    digitalAssetAddress,
    digitalAssetId,
    classId,
    bondAmount,
    sponsorAddress
  );

// Delegated attestation with sponsor
const delegatedSignature =
  await sdk.attestationService.signForDelegatedAttestation(recipientAddress);
const { attestationUid, rightsBoundAccount } =
  await sponsorSDK.attestationService.sponsoredDelegatedAttest(
    attestationRequest,
    digitalAssetAddress,
    digitalAssetId,
    classId,
    bondAmount,
    delegatedSignature,
    recipientAddress,
    sponsorAddress
  );
```

#### Sponsorship Benefits

* **Gas-Free User Experience**: Users can interact without owning native tokens
* **Platform Integration**: Marketplaces can sponsor user interactions seamlessly
* **Enterprise Workflows**: Complex multi-party operations with clear cost attribution
* **Accessibility**: Removes technical barriers for non-crypto native users
* **Flexible Business Models**: Enables subscription, freemium, and sponsored content models
* **Scalable Operations**: Third parties can batch and optimize transaction execution

### 6. Enhanced Rights Bound Account Management

#### New Methods

```typescript theme={null}
// Get asset information associated with a Rights Bound Account
const assetInfo = await sdk.rightsBoundAccount.getRightsBoundAccountAsset();
console.log(`Asset Address: ${assetInfo.assetAddress}`);
console.log(`Token ID: ${assetInfo.tokenId}`);

// Improved payment info signing with sponsor support
const signature = await sdk.rightsBoundAccount.signForSetPaymentInfo(
  period,
  totalAmount,
  sponsor
);
```

### 7. Improved UX with Attestation

#### Better Developer Experience for Attestation Functions

v0.2.0 improves the developer experience by having attestation functions return the `attestationUid` and `rightsBoundAccount` directly instead of just transaction hashes. This eliminates the need for developers to manually wait for transactions and parse receipts.

```typescript theme={null}
// v0.2.0 - Direct returns for better UX
const { attestationUid, rightsBoundAccount } =
  await sdk.attestationService.attest(
    attestationRequest,
    digitalAssetAddress,
    digitalAssetId,
    assetClass,
    bondAmount
  );

// No need to wait for transaction or parse receipts manually
console.log(`Attestation UID: ${attestationUid}`);
console.log(`Rights Bound Account: ${rightsBoundAccount}`);

// Same improvement applies to other attestation methods:
// - sponsoredAttest()
// - delegatedAttest()
// - sponsoredDelegatedAttest()
```

## Migration Checklist

### **Critical - Required Changes**

#### 1. Update Parent Asset Structure

* [ ] **Replace all `ParentDigitalAsset[]` with `ParentInfo[]`**
* [ ] **Update minting calls to use Rights Bound Account addresses instead of collection/tokenId/owner**
* [ ] **Implement Rights Bound Account address lookup for existing parent assets**

#### 2. Update Import Statements

```typescript theme={null}
// Add new utility imports if needed
import { getDigitalAssetUID, getVerifiedRightsId } from "@cultura/sdk/utils";
```

### **Recommended - Optional Enhancements**

#### 3. Leverage Enhanced Query Data

* [ ] Update query result handling to use new `verifications` array data
* [ ] Use `owner.tokenCount` information where relevant
* [ ] Implement richer verification displays using detailed verifier information

#### 4. Implement New Utility Functions

* [ ] Use `getDigitalAssetUID` and `getVerifiedRightsId` for consistent ID generation
* [ ] Replace manual ID generation with utility functions

#### 5. Enhanced Error Handling

* [ ] Update error handling for new Rights Bound Account requirements
* [ ] Add validation for Rights Bound Account address existence

## Example Migration

### Before (v0.1.10)

```typescript theme={null}
// v0.1.10 minting with parent assets
const parentAssets: ParentDigitalAsset[] = [
  {
    parentCollection: "0x123...",
    parentDigitalAssetId: 42n,
    owner: "0xabc...",
    royaltySplit: 75n,
  },
];

const tokenId = await sdk.culturaDigitalAsset.mintDigitalAsset(
  recipientAddress,
  "Derivative Work",
  "Based on parent asset",
  parentAssets,
  termsData,
  tokenURI
);
```

### After (v0.2.0)

```typescript theme={null}
// v0.2.0 minting with parent info
// First, get the Rights Bound Account address for the parent
const parentAsset = await sdk.query.digitalAsset.getByContractAndTokenId(
  "0x123...", // parent collection
  42n // parent token ID
);

if (!parentAsset?.rightsBoundAccount) {
  throw new Error("Parent asset Rights Bound Account not found");
}

const parentInfo: ParentInfo[] = [
  {
    rightsBoundAccount: parentAsset.rightsBoundAccount,
    royaltySplit: 75n,
  },
];

const tokenId = await sdk.culturaDigitalAsset.mintDigitalAsset(
  recipientAddress,
  "Derivative Work",
  "Based on parent asset",
  parentInfo, // Updated structure
  termsData,
  tokenURI
);
```

## Common Migration Issues

### Issue 1: Rights Bound Account Not Found

**Problem**: Parent asset doesn't have a Rights Bound Account address
**Solution**: Ensure the parent asset has been properly attested and verified

```typescript theme={null}
// Check if parent asset has been attested
const verifiedRights = await sdk.query.verifiedRights.getByDigitalAsset(
  parentCollection,
  parentTokenId.toString()
);

if (!verifiedRights) {
  throw new Error("Parent asset must be attested before use in derivatives");
}
```

### Issue 2: Type Errors with Parent Info

**Problem**: TypeScript errors when switching from `ParentDigitalAsset` to `ParentInfo`
**Solution**: Update type imports and structure

```typescript theme={null}
// Update imports
import type { ParentInfo } from "@cultura/sdk";

// Use correct type
const parentInfo: ParentInfo[] = [
  /* ... */
];
```

## Testing Your Migration

1. **Test Parent Asset Queries**: Ensure you can successfully retrieve Rights Bound Account addresses
2. **Test Minting**: Verify derivative asset minting works with new parent info structure
3. **Test Enhanced Queries**: Confirm enhanced query data is accessible
4. **Test Royalty Flows**: Verify royalty distribution still works correctly

## Getting Help

If you encounter issues during migration:

* Check the [SDK Reference Documentation](../sdk-reference/v0.2.0/)
* Review the [Core SDK Workflows](../building-on-cultura/core-sdk-workflows/)
* Consult the [Query Examples](../sdk-reference/v0.2.0/quickstart#query-example)

The v0.2.0 update provides a more robust and feature-rich SDK while maintaining backward compatibility where possible. The main breaking change around parent asset structure enables better royalty distribution and cleaner architecture going forward.
