Integration Guide
This guide provides information for developers who want to integrate ATP into their applications.
Use Cases
1. Multi-Asset Cross-Chain Swaps
ATP enables users to swap entire portfolios across different blockchains without needing to individually transfer each asset. This simplifies complex cross-chain operations:
- DeFi Portfolio Transfers: Move an entire DeFi position (including staked tokens, liquidity positions, etc.) from one chain to another
- NFT Collection Transfers: Transfer a collection of NFTs in a single operation
- Multi-Token Wallets: Swap wallets containing various tokens and assets
2. Decentralized Exchange Integration
DEXs can integrate with ATP to offer more sophisticated trading options:
- Portfolio Swapping: Instead of token-to-token trades, users can swap entire portfolios
- Cross-Chain Trading: Enable trading between assets on different blockchains without bridges
- Batch Trading: Execute multiple trades in a single transaction by swapping accounts
3. Blockchain Gaming
Game developers can use ATP to enable secure and efficient in-game asset transfers:
- Character/Inventory Transfer: Move a game character with all its inventory items across game worlds
- Cross-Game Asset Usage: Enable assets to be used across multiple games on different chains
- Account Trading: Allow players to trade entire game accounts securely
4. Credential Management
Organizations can use ATP for secure credential management:
- Corporate Access Control: Transfer access credentials between employees
- Temporary Access Grants: Grant temporary access to systems by transferring accounts
- Credential Rotation: Easily rotate access credentials across multiple systems
Integration Steps
1. Deploy the ATP Canister
First, deploy the ATP canister to your Internet Computer environment:
dfx deploy atp
And create a type declaration for the canister:
dfx generate atp
2. Create an Account Interface
Create an interface that allows users to interact with ATP accounts:
import { Actor, HttpAgent } from '@dfinity/agent';
import { idlFactory } from './atp.did.js';
// Initialize agent and actor
const agent = new HttpAgent();
const atp = Actor.createActor(idlFactory, {
agent,
canisterId: process.env.ATP_CANISTER_ID,
});
// Create an account
async function createAccount(signingAlgorithm, curve, owner) {
return await atp.create_account(signingAlgorithm, curve, owner);
}
// Transfer an account
async function transferAccount(accountId, newOwner) {
return await atp.transfer_account(accountId, newOwner);
}
// Activate an account
async function activateAccount(accountId) {
return await atp.activate_account(accountId);
}
// Sign a message with an account
async function signMessage(accountId, message) {
const messageBytes = new TextEncoder().encode(message);
const hexMessage = Array.from(messageBytes)
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
return await atp.sign(accountId, hexMessage);
}
3. Implement Account Lifecycle Management
Implement functions to handle the full lifecycle of accounts:
// Account lifecycle management
async function completeAccountTransfer(accountId, currentOwner, newOwner) {
// Step 1: Current owner approves transfer
await atp.approve_address(accountId, newOwner);
// Step 2: New owner initiates transfer
await atp.transfer_account(accountId, newOwner);
// Step 3: New owner activates the account
await atp.activate_account(accountId);
return { success: true, message: 'Account transferred successfully' };
}
4. Error Handling
Implement proper error handling for ATP interactions:
async function safeCreateAccount(signingAlgorithm, curve, owner) {
try {
const result = await createAccount(signingAlgorithm, curve, owner);
return { success: true, accountId: result.id };
} catch (error) {
console.error('Error creating account:', error);
return { success: false, error: error.message };
}
}
5. Testing Your Integration
Test your integration with the ATP canister:
async function testAtpIntegration() {
// Get user principal
const identity = await window.ic?.plug?.getPrincipal();
if (!identity) {
console.error('No identity available');
return;
}
// Create account
const createResult = await safeCreateAccount(
{ ecdsa: null },
{ secp256k1: null },
identity,
);
if (!createResult.success) {
console.error('Failed to create account');
return;
}
console.log('Account created:', createResult.accountId);
// Test signing
const signResult = await signMessage(createResult.accountId, 'Hello, ATP!');
console.log('Signature:', signResult);
}
Best Practices
Security Considerations
- Always verify ownership before performing operations on accounts
- Use secure identity management for authentication
- Implement proper error handling for all canister calls
- Consider rate limiting for account creation to prevent abuse
Performance Optimization
- Batch operations when possible to reduce the number of canister calls
- Cache account information client-side to reduce redundant queries
- Implement pagination for listing multiple accounts
User Experience
- Provide clear feedback during account operations
- Implement confirmation workflows for important actions like transfers
- Offer account recovery options for users
- Display account state clearly in your UI