xcm-lib-zkverify
Version:
XCM asset teleportation and remote EVM calls for ZKVerify
204 lines • 9.14 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XcmTeleportService = void 0;
const validation_1 = require("../utils/validation");
const api_connection_1 = require("../utils/api-connection");
const transaction_executor_1 = require("../utils/transaction-executor");
class XcmTeleportService {
constructor(config) {
// Basic validation - at least one private key required
if (!config.relayPrivateKey && !config.evmParachainPrivateKey) {
throw new Error('At least one private key is required: relayPrivateKey (for relay->parachain) or evmParachainPrivateKey (for parachain->relay)');
}
// Validate private keys if provided
if (config.relayPrivateKey) {
(0, validation_1.validatePrivateKey)(config.relayPrivateKey, 'Relay private key');
}
if (config.evmParachainPrivateKey) {
(0, validation_1.validatePrivateKey)(config.evmParachainPrivateKey, 'EVM parachain private key');
}
this.config = config;
this.xcmVersion = config.xcmRelayVersion || 'V5';
}
async initialize() {
const errors = [];
// Initialize relay API if endpoint is provided
if (this.config.relayWsEndpoint) {
try {
this.relayApi = await api_connection_1.ApiConnection.createApi(this.config.relayWsEndpoint);
// Only create keypair if private key is available
if (this.config.relayPrivateKey) {
this.relayKeyPair = api_connection_1.ApiConnection.createKeyPair(this.config.relayPrivateKey, 'sr25519');
}
}
catch (error) {
errors.push(`Failed to initialize relay chain connection: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
// Initialize parachain API if endpoint is provided
if (this.config.evmParachainWsEndpoint) {
try {
this.evmParachainApi = await api_connection_1.ApiConnection.createApi(this.config.evmParachainWsEndpoint);
// Only create keypair if private key is available
if (this.config.evmParachainPrivateKey) {
this.evmParachainKeyPair = api_connection_1.ApiConnection.createKeyPair(this.config.evmParachainPrivateKey, 'ethereum');
}
}
catch (error) {
errors.push(`Failed to initialize parachain connection: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
// If there were any initialization errors, throw them
if (errors.length > 0) {
throw new Error(`Initialization failed:\n${errors.join('\n')}`);
}
}
async teleportToEvmParachain(params) {
// Validate required configuration for relay->parachain operation
if (!this.config.relayPrivateKey) {
throw new Error('relayPrivateKey is required for relay->parachain teleport operations');
}
if (!this.config.evmParachainId) {
throw new Error('evmParachainId is required for relay->parachain teleport operations');
}
if (!this.relayApi || !this.relayKeyPair) {
throw new Error('Relay chain not initialized. Ensure relayWsEndpoint is provided and call initialize() first.');
}
(0, validation_1.validateEvmAddress)(params.destinationAddress, 'Destination address');
try {
// Create XCM message for teleport
const destination = this.relayApi.createType('XcmVersionedLocation', {
[this.xcmVersion]: {
parents: 0,
interior: {
X1: [{
Parachain: this.config.evmParachainId
}]
}
}
});
const beneficiary = this.relayApi.createType('XcmVersionedLocation', {
[this.xcmVersion]: {
parents: 0,
interior: {
X1: [{
AccountKey20: {
network: null,
key: params.destinationAddress
}
}]
}
}
});
const assets = this.relayApi.createType('XcmVersionedAssets', {
[this.xcmVersion]: [{
id: {
interior: 'Here',
parents: 0
},
fun: {
Fungible: params.amount
}
}]
});
const feeAssetItem = 0;
const tx = this.relayApi.tx.xcmPallet.teleportAssets(destination, beneficiary, assets, feeAssetItem);
return await transaction_executor_1.TransactionExecutor.executeTransaction(this.relayApi, tx, this.relayKeyPair, { returnSuccess: true, skipNonce: true });
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
async teleportFromEvmParachain(params) {
// Validate required configuration for parachain->relay operation
if (!this.config.evmParachainPrivateKey) {
throw new Error('evmParachainPrivateKey is required for parachain->relay teleport operations');
}
if (!this.evmParachainApi || !this.evmParachainKeyPair) {
throw new Error('EVM parachain not initialized. Ensure evmParachainWsEndpoint is provided and call initialize() first.');
}
// For reverse teleport, destination should be a Substrate address
try {
// Create XCM message for teleport from EVM parachain to relay chain
const destination = this.evmParachainApi.createType('XcmVersionedLocation', {
[this.xcmVersion]: {
parents: 1,
interior: 'Here'
}
});
// For relay chain destination, use AccountId32 with direct 0x address
const beneficiary = this.evmParachainApi.createType('XcmVersionedLocation', {
[this.xcmVersion]: {
parents: 0,
interior: {
X1: [{
AccountId32: {
network: null,
id: params.destinationAddress
}
}]
}
}
});
const assets = this.evmParachainApi.createType('XcmVersionedAssets', {
[this.xcmVersion]: [{
id: {
interior: 'Here',
parents: 1
},
fun: {
Fungible: params.amount
}
}]
});
const feeAssetItem = 0;
const tx = this.evmParachainApi.tx.zkvXcm.teleportAssets(destination, beneficiary, assets, feeAssetItem);
return await transaction_executor_1.TransactionExecutor.executeTransaction(this.evmParachainApi, tx, this.evmParachainKeyPair, { returnSuccess: true, skipNonce: true });
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
};
}
}
async getRelayChainBalance(address) {
if (!this.relayApi) {
throw new Error('Service not initialized. Call initialize() first.');
}
const accountInfo = await this.relayApi.query.system.account(address);
return accountInfo.data.free.toString();
}
async getEvmParachainBalance(address) {
if (!this.evmParachainApi) {
throw new Error('Service not initialized. Call initialize() first.');
}
const accountInfo = await this.evmParachainApi.query.system.account(address);
return accountInfo.data.free.toString();
}
getRelayAccountAddress() {
if (!this.relayKeyPair) {
throw new Error('Service not initialized. Call initialize() first.');
}
return this.relayKeyPair.address;
}
getEvmParachainAccountAddress() {
if (!this.evmParachainKeyPair) {
throw new Error('Service not initialized. Call initialize() first.');
}
return this.evmParachainKeyPair.address;
}
async disconnect() {
if (this.relayApi) {
await this.relayApi.disconnect();
}
if (this.evmParachainApi) {
await this.evmParachainApi.disconnect();
}
}
}
exports.XcmTeleportService = XcmTeleportService;
//# sourceMappingURL=xcm-teleport.js.map