@xrdna/blockchain-sdk
v2.0.0
Published
This repository contains several SDKs used by various roles to execute the XRDNA Metaverse Interoperability Protocol. The roles within the protocol follow this hierarchy: XRDNA -> Registrar -> World -> Company -> Experience -> Avatar. Each of these roles
Downloads
47
Readme
Background
This repository contains several SDKs used by various roles to execute the XRDNA Metaverse Interoperability Protocol. The roles within the protocol follow this hierarchy: XRDNA -> Registrar -> World -> Company -> Experience -> Avatar. Each of these roles is responsible for specific activity to ensure that metadata shared across metaverse ecosystems is trusted and accessible.
XRDNA
XRDNA is the equivalent of iCann for domain registrations. XRDNA issues base 'vector addresses' for use across metaverse environments. Think of a vector address as a globally unique identifier that maps back to its owning authority. A registrar requests base vector addresses from XRDNA in order to register worlds. XRDNA acts as the Registrar Authority as well.
Registrar Authority
The registrar authority is responsible for authorizing others to request and issue vector addresses to Worlds. A registrar in this context is anyone able to add new Worlds to the ecosystem and information about those worlds is accessible using the interoperability protocol.
Registrar
A registrar assigns vector addresses to Worlds. Worlds register through a Registrar and the Registrar goes to XRDNA for authorized vector addresses. There is only one current Registrar and that's XRDNA. Others will be added in the future.
Vector Address
A vector address is a unique spatial address obtained from XRDNA and assigned by a Registrar. Every World is given a "base" address and when things are added to the World, they are assigned a sub-vector address derived from the base address. Vector addresses have x, y, and z fields, which represent their 3-d spatial position. In addition, there is a 't' field which represent a temporal or time based position. There is also a 'p' field which represents a 'plane'. Finally, there is a 'p_sub' field which is a sub-position within a plane.
The protocol starts each World with a base address, with p and p_sub fields set to 0. When a Company registers with a World, its base address will have a 1-up 'p' value assigned, but have p_sub 0. When Companies register Experiences, the Experience will have the parent Company's base address but it's p_sub value will be incremented with each experience added by the Company.
World
A world is a metaverse ecosystem operator. They provide a virtual environment in which Companies and Avatars can engage. Worlds register themselves with the interoperability layer through a Registrar. Worlds are assigned a base vector address and then derive sub-addresses for Companies that are registered with the World.
Company
Companies are entities that wish to offer Experiences within a virtual World. They register with Worlds to gain authority to add new Experiences within the World. A World's base vector address is derived from the World's vector address, except its 'p' value is incremented with each Company registered in the World. When adding Experiences, a new vector address is assigned to the experience with the p_sub value of the Company's base incrementing with each experience added.
Experience
Experiences represent sub-environments that an Avatar can jump or portal into. Companies own the experiences they offer and control access and costs associated with the experiences. Experiences are registered by a Company through its parent World. Portals are attached to Experiences so that Avatars can find and launch the experience while in a virtual world.
Avatar
Avatars represent users within a World. They register through World and are assigned a dynamic vector address that generally matches whatever Experience they are in. Avatars own assets which are coins, tokens, and/or wearables. They can configure wearables and certain wearables are visible in multiple worlds.
Usage Overview
These SDKs offered in this repository:
- RegistrarCreatorSDK
- RegistrarSDK
- WorldSDK
Each of these requires an RPC endpoint along with one or more "signers". The RPC endpoint must correlate to the layer-3 blockchain or a node in that blockhain for web3 RPC calls. The Signers are wallets that sign transactions or messages depending on the action being performed. It is assumed that anyone using the interoperability protocol has the ability to provide a signer or private key to the SDKs to execute transactions on the interoperability blockchain.
RPC Endpoint
The XRDNA blockchain is a dedicated layer-3 blockchain. It operates as a rollup with the Base blockchain as its security layer, along with Celestia as its data access provider. Currently, this layer-3 is a testnet with chain id 26379 using Base-sepolia as its security layer. The SDKs are configured to reference contracts in this testnet as well as a default RPC endpoint. If there are alternative RPC endpoints offered in the future, they can be provided in the constructors of SDKs to override the default setting.
If you create an SDK instance with only the chainId option, it becomes a read-only SDK for getting information from the smart contracts. Otherwise, a signer will be required to submit transactions on-chain.
RegistrarCreatorSDK
The RegistrarCreatorSDK is used by XRDNA to register new Registrars and sign vector addresses issued to those Registrars. It therefore has two different authorities, which can be the same signer:
- Registrar registry administrator
- Vector address authority
Registrar Admin
This is the XRDNA administrator signer which is responsible for adding and removing Registrars from the Registry smart contract on-chain.
Vector Address Authority
This is the XRDNA signer that must sign all issued vector addresses. Registrars requesting vector addresses must be returned both the vector address along with the authoritative signature of that address so that it can be authorized within the smart contracts on-chain.
const sdk = new RegistrarCreatorSDK({
chainId: 26379,
signer: xrdnaSigner,
vectorAuthoritySigner: vectorAddressAuthoritySigner,
});
const vectorAddress = ... //vector address derived from some XRDNA service
const r = await sdk.signVectorAddress({ vectorAddress })
return {
vectorAddress,
vectorAddressSignature: r.signature
}
In this code snippet, XRDNA would creates an instance of the RegistrarCreatorSDK using its signers. It uses the SDK to sign vector addresses that it creates likely in response to Registrars requesting new address assignments. The default RPC endpoint is being used in this case.
const sdk = new RegistrarCreatorSDK({
chainId: 26379,
signer: xrdnaSigner,
vectorAuthoritySigner: vectorAddressAuthoritySigner,
});
const r = await sdk.createRegistrar({
address: registrarSignerAddress,
tokens: ethers.parseEther('100_000')
});
return {
registrarID: r.registrarID
}
In this case, XRDNA is create a new Registrar. It assigns some tokens to the Registrar signer address so that they can submit transactions on the layer-3 chain.
RegistrarSDK
This SDK is used by Registrars to register new Worlds. They must callback to XRDNA's Registrar service to get signed vector addresses to assign to new Worlds on-chain. The SDK assumes that process is handled between Registrar and XRDNA. This SDK requires two values:
- Signer
- RegistrarID
Signer
When registering with XRDNA as a registrar, a default signing address must be provided. When using the RegistrarSDK, you must provide a signer attached to that signing address in order to authorize World creations.
RegistrarID
XRDNA should return a unique RegistrarID which correlates to the on-chain identifier associated with the default signing address provided during registration. With the signer and this registrarID, other signing addresses can be added or removed from the on-chain RegistrarRegistry smart contract using the RegistrarSDK.
const sdk = new RegsitrarSDK({
chainId: 26379,
registrarID: myAssignedId,
privateKey: myPK
});
const r = await sdk.registerWorld({
name: worldName,
worldOwner: worldSigner,
vectorAddress: assignedVectorAddress,
vectorAddressAuthorizedSignature: vectorAddressSignature,
tokens: ethers.parseEther('100'),
allocateTokensTo: 'owner'
});
return {
contractAddress: r.worldAddress,
vectorAddress: assignedVectorAddress
}
In this example, a RegistrarSDK is created using a private key versus a Signer implementation. The Registrar uses the SDK to register a new World on-chain by providing appropriate parameters. The SDK returns the contract address for the newly created World smart contract. The Registrar should give back the contract and vector addresses to the requesting client.
WorldSDK
This is used by Worlds that register with a Registrar. It is assumed that a World will go through a Registrar process to create a new World. That world will be given a smart contract address which represents the shared metadata information for the World (name, base vector address, companies, etc). The SDK requires this as constructor args:
- Signer
- ContractAddress
Signer
Just like other SDKs, when a World registers through a Registrar, it provides one or more signing authorities for the World. One of those signers must be provided to the WorldSDK so that interactions with the World smart contract are properly authorized.
Contract Address
When registering a World through a Registrar, a smart contract is created on-chain. The address of that contract must be used to create the SDK so that authorization and state changes are being made to the appropriate World contract.
const sdk = new WorldSDK({
chainId: 26379,
signer: worldOwner,
worldAddress: worldContractAddress
});
await sdk.addSigners({
addresses: [<new signer addresses>]
});
This snippet allows a World owner to add new signing authorities for the World smart contract. While this SDK is limited at the moment, a future version will allow Company and Experience registrations similar to the RegistrarSDK.
Testing
Integration tests
Integration tests are run against a live RPC endpoint, and a mock backend api server. The RPC endpoint is forked from the current block, and state is reset after each test. The mock backend api server is used to simulate the XRDNA backend api server.
Requirements:
- Node.js
- Docker
# Run integration tests
yarn test:integration
# Log debug messages from test containers
DEBUG=testcontainers:* yarn test:integration