Skip to content

Create Royal ID and Delegate

Imagine you’re building a digital creation tool - perhaps a music production suite or an AI-assisted art platform. Your users need Royal IDs to establish provenance for their work, and they need to delegate authority to your platform to register their creations. Having users complete these steps separately would be like asking someone to fill out two different forms at the DMV when one would do. The Royal Protocol’s combined registration and delegation flow solves this elegantly.

FunctionInterfaceImplementation
registerAndDelegate 🔗 🔗
registerAndDelegateFor 🔗 🔗

Understanding the Need

Traditional web3 onboarding often creates friction through multiple transaction steps:

  1. Create an account/ID
  2. Grant permissions to the platform
  3. Configure specific settings

Each step requires a separate signature or transaction, increasing complexity and potential drop-off points. The Royal Protocol’s combined registration and delegation flow collapses these steps into a single, atomic operation.

Core Concept

The combined flow wraps two fundamental operations into one:

  • Creating a new Royal ID for the user
  • Establishing a full delegation to the registrar

Think of it like getting a new credit card where the activation and PIN setup happen in the same call - two logically separate but commonly paired operations combined for efficiency.

Implementation Approaches

Direct Flow

// User has ETH and initiates directly
await idGateway.registerAndDelegate(
username, // User's chosen username
recovery, // Optional recovery address
delegateeId, // Your platform's Royal ID
);
// Platform sponsors transaction, user just signs
const deadline = Date.now() + 3600; // 1 hour from now
const signature = await wallet.signTypedData({
custody: userAddress,
username: chosenUsername,
recovery: recoveryAddress,
delegateeId: platformId,
deadline,
});
await idGateway.registerAndDelegateFor(
userAddress,
chosenUsername,
recoveryAddress,
platformId,
deadline,
signature,
);

Best Practices

Timing Considerations

  • Set reasonable signature deadlines - typically 15-60 minutes
  • Implement retry logic for network issues
  • Handle signature expiration gracefully

Error Handling

  • Validate usernames before requesting signatures
  • Check for existing delegations
  • Verify platform Royal ID status

User Experience

  • Explain the delegation scope clearly
  • Provide visual feedback during the process
  • Offer clear paths to modify delegations later

Security Considerations

The combined operation creates a powerful delegation - essentially giving your platform broad authority to act on behalf of the user. While this enables smooth operations, it comes with responsibilities:

  • Clearly communicate the scope of delegation to users
  • Implement robust security around your platform’s Royal ID
  • Provide easy methods for users to revoke or modify delegations
  • Consider implementing more granular delegations for specific features

Verification and Monitoring

After successful registration and delegation:

  1. Verify Royal ID creation:

    const user = await idRegistry.getUserByAddress(userAddress);
    assert(user.id > 0);
  2. Check delegation status:

    const canAct = await idRegistry.canAct(
    user.id, // User's Royal ID
    platformId, // Your platform's ID
    contractAddress, // Target contract
    rights, // Specific rights to check
    );

Integration Examples

Simple Integration

class RoyalProtocolService {
async registerNewUser(username: string, recoveryAddress?: string) {
const platformId = await this.getPlatformId();
if (this.canSponsorGas()) {
return this.sponsorRegistration(username, recoveryAddress, platformId);
} else {
return this.directRegistration(username, recoveryAddress, platformId);
}
}
}

Advanced Integration with Retry Logic

class RobustRoyalProtocolService {
async registerWithRetry(
username: string,
recoveryAddress?: string,
maxAttempts = 3,
) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await this.registerNewUser(username, recoveryAddress);
} catch (error) {
if (attempt === maxAttempts) throw error;
if (this.isRetryableError(error)) {
await this.delay(attempt * 1000);
continue;
}
throw error;
}
}
}
}

Common Pitfalls

  1. Signature Expiration: Don’t store signatures for later use - process them promptly.

  2. Gas Estimation: Remember that the combined operation uses more gas than simple registration. Estimate accordingly.

  3. Error Messages: Network errors can be opaque. Map common errors to user-friendly messages:

    const ERROR_MESSAGES = {
    UsernameAlreadyRegistered: "This username is taken",
    DelegateeDoesNotExist: "Platform configuration error",
    InsufficientFee: "Transaction fee too low",
    };