Relay Validators
WIP
The relay validators are comparatively thin. Each validator is comprised of
a set of accounts one per account standard,
a set of private keys for signing transactions in the bridged blockchains,
Validators' code distribution
For security & reliability purposes part of the validators' functionality resides in the bridged blockchains inside the bridge pallet for XP.network and inside the smart contracts for the other ledgers.
Blockchain connection settings:
Connection parameter
Value
Transaction Port
3001
XP.network testnet
https://explorer.xp.network
Elrond Devnet
Elrond Smart Contract
erd1qqqqqqqqqqqqqpgqfy5zmm64avweyq3rcw65xczwkwedfz5zs3ysmja8la
HECO Testnet
HECO SC
0x8b9c95147C185A9d0940DC26a6EA774eE05D8853
BSC Testnet
BSC SC
0x5b5C8b16937F60D02aFaC76bf6614c33911636FC
Ropsten SC
0xf6fceC833bFb9bd26a898143A6b41799F5Abfe0f
1. ElrondHelper
Signature
class ElrondHelper implements
ChainListener<
// Listens to the events:
TransferEvent |
TransferUniqueEvent |
UnfreezeEvent |
UnfreezeUniqueEvent,
TransactionHash>,
ChainEmitter<
// Emits events:
string,
void,
TransferEvent |
TransferUniqueEvent |
UnfreezeEvent |
UnfreezeUniqueEvent>,
ChainIdentifier
{ ... }
Functionality
Verifies the following transactions:
eGLD transfer to a foreign blockchain
ESDT NFT transfer to a foreign chain
minting wrapped semi-fungible tokens to an account on Elrond e.g.: (XPNET-<hex>-<nonce>)
minting wrapped NFT to an account in Elrond
Signature
class PolkadotPalletHelper
implements
ChainEmitter<
// Emits the events:
EventRecord,
void,
TransferEvent |
TransferUniqueEvent |
UnfreezeEvent |
UnfreezeUniqueEvent
>,
ChainListener<
// Listens to the events:
TransferEvent |
TransferUniqueEvent |
UnfreezeEvent |
UnfreezeUniqueEvent,
Hash>,
ChainIdentifier
{
Functionality
Verifies the following transactions:
XPNET transfer to a foreign blockchain
NFT transfer to a foreign chain
minting wrapped fungible tokens to an account on XP.network
minting wrapped NFT to an account on XP.network
3. Web3Helper
Signature
class Web3Helper
implements ChainEmitter<
// Emits events
SolEvent,
void,
TransferEvent |
UnfreezeEvent
>,
ChainListener<
// Listens to events
TransferEvent |
UnfreezeEvent,
string
>, ChainIdentifier
{ ... }
Functionality
Verifies the following transactions:
Native Tokens transfer to a foreign blockchain
NFT transfer to a foreign chain
minting wrapped fungible tokens to an account on a web3 compatible chain
minting wrapped NFT to an account on a web3 compatible chain
4. Validator Events
Custom types and dependency injection interfaces used in the module:
// ===================== Interfaces: ==========================
// Ensures an entity has a 'chain_nonce' data field
interface MultiChainEvent {readonly chain_nonce: number;}
// Ensures an entity has a 'chainNonce' data field
interface ChainIdentifier {readonly chainNonce: number;}
// Ensures an entity has a 'toString()' method
interface IntoString {toString(): string;}
// A bridged blockchain that emits events
interface ChainEmitter<
EmissionEvent, // Raw event
Iter, // Iterator over the raw event
SupportedEvents // [[TransferEvent]], [[UnfreezeEvent]], [[ScCallEvent]]
> {
// Event iterator over raw events
eventIter(cb: (event: EmissionEvent) => Promise<void>): Promise<Iter>;
// Convert a raw event to a known event
eventHandler(event: EmissionEvent): Promise<SupportedEvents | undefined>;
}
// Ensures an entity has an 'emittedEventHandler' method
interface ChainListener<
SupportedEvents, // [[TransferEvent]], [[UnfreezeEvent]], [[ScCallEvent]]
TxnHash // a TX hash
> {
emittedEventHandler(
event: SupportedEvents, // [[TransferEvent]], [[UnfreezeEvent]], [[ScCallEvent]]
origin_nonce: number // the original blockchain ID
): Promise<TxnHash>; // returns a TX hash in a Promise
}
// =========================== Types: ==========================
// Union type comprising all the events & event handlers for a chain
declare type FullChain<Event, Iter, Handlers, Tx extends IntoString> =
ChainEmitter<Event, Iter, Handlers> &
ChainListener<Handlers, Tx> &
ChainIdentifier;
// A chain mapper type
type ChainMap<Event, Iter, Handlers, Tx extends IntoString> = {
[index: number]: FullChain<Event, Iter, Handlers, Tx>;
}
4.1. TransferEvent
An event of fungible liquidity transfer. It indicates that the tokens were locked in the source chain and are ready to be minted as wrapped tokens in the target blockchain and released to a designated account.
Signature:
class TransferEvent implements MultiChainEvent { ... }
Inner fields:
readonly action_id: BigNumber; // an action ID
readonly chain_nonce: number; // a unique target chain ID
readonly to: string; // target account
readonly value: BigNumber; // amount of transmitted tokens
4.2 TransferUniqueEvent
An event for non-fungible tokens moving from the original to a foreign blockchain. It indicates that an NFT was locked in its original chain and is ready to be minted as wrapped NFTs and released to a target account on a target blockchain.
Signature:
class TransferUniqueEvent implements MultiChainEvent { ... }
Inner fields:
readonly action_id: BigNumber; // an action ID
readonly chain_nonce: number; // a unique target chain ID
readonly to: string; // target account
readonly id: Uint8Array; // NFT identifier (see below)
// For XP.network - it is a hash
// For Elrond it is an ID + nonce
// For web3 compatible chains it is:
// 1. for ERC-721 tokens: contract address
// 2. for ERC-1155 tokens: contract address + ID
4.3. UnfreezeEvent
An event of fungible liquidity transfer. It indicates that the tokens were burned in a foreign chain and are ready to be unlocked as native tokens in the original blockchain and released to a designated account.
Signature:
class UnfreezeEvent implements MultiChainEvent { ... }
Inner fields:
readonly action_id: BigNumber; // an action ID
readonly chain_nonce: number; // a unique target chain ID
readonly to: string; // target account
readonly value: BigNumber; // amount of transmitted tokens
4.4 UnfreezeUniqueEvent
An event for non-fungible tokens returning to the original blockchain. It indicates that an NFT was burned in a foreign chain and is ready to be unlocked as native NFTs and released to a target account on the original blockchain.
Signature:
class UnfreezeUniqueEvent implements MultiChainEvent { ... }
Inner fields:
readonly action_id: BigNumber; // an action ID
readonly chain_nonce: number; // a unique target chain ID
readonly to: string; // target account
readonly id: Uint8Array; // NFT identifier (see below)
// For XP.network - it is a hash
// For Elrond it is an ID + nonce
// For web3 compatible chains it is:
// 1. for ERC-721 tokens: contract address
// 2. for ERC-1155 tokens: contract address + ID
4.5 Event Emission
The function call signature:
export async function emitEvents<Handlers extends MultiChainEvent>(
// The socket: Server<ServerEvents>
io: TxnSocketServe,
// Bridged blockchain array
chains: Array<FullChain<any, any, Handlers, IntoString>>
//
): Promise<void>
Internal fields
// Internal chain mapper
const map: ChainMap<any, any, Handlers, IntoString> = {};
Internal subfunctions
// Event handler function
const handleEvent = async (
// Chain listener handlers
listener: ChainListener<Handlers, IntoString> & ChainIdentifier,
// The handled event
event: Handlers,
// The ID of the original blockchain
origin_nonce: number
) => {
const tx = await listener.emittedEventHandler(event, origin_nonce);
if (event instanceof TransferUniqueEvent) {
io.emit(
"transfer_nft_event",
listener.chainNonce,
event.action_id.toString(),
tx.toString());
} else if (event instanceof UnfreezeUniqueEvent) {
io.emit(
"unfreeze_nft_event",
listener.chainNonce,
event.id.toString(),
tx.toString());
}
}
Listening to the events of the chains in a loop
for (const chain of chains) {
if (map[chain.chainNonce] !== undefined) {
throw Error("Duplicate chain nonce!")
}
map[chain.chainNonce] = chain;
listenEvents(chain);
}
Last updated
Was this helpful?