Registration
Deprecated: The
registerDomainName
function is being deprecated as it relies on the older Pyth smart contract on Solana, which is scheduled to be sunsetted at the end of May 2024. Please transition to usingregisterDomainNameV2
for future domain registrations.
Easily integrate SNS domain registrations into your applications using our SNS Widget React Component. See a default usage example below. You can also customize the widget to fit your unique needs. More information is available here: https://github.com/Bonfida/sns-widget/blob/main/README.md
import Widget from "@bonfida/sns-widget";
// Apart from the component itself, you also need to import styles separately
import "@bonfida/sns-widget/style.css";
// Link to public RPC for Solana connection. Solana provides free public RPCs
// with rate limiters, so you might want to use your own RPC Node provider
const PUBLIC_RPC = "https://api.mainnet-beta.solana.com";
export const Component = () => {
return <Widget endpoint={PUBLIC_RPC} />;
};
You can also opt to create registration instructions via our SDK or API, both methods are equivalent. To register a domain you will have to specify the following:
- Domain names
- Space (between 1kb and 10kb)
- The public key of the buyer
Domain names can be registered with the following tokens: USDC, USDT, wSOL, FIDA, mSOL, BONK and BAT.
Note: The registration instruction does not support native SOL but wrapped SOL
Asset pricing
Token pricing data during domain registration is provided to us by our friends at Pyth Network. Learn more about their Blockchain Oracle at Pyth Network.
SDK
Unregistered domains can be registered using the SDK @bonfida/spl-name-service
with the following instructions:
import { registerDomainNameV2 } from "@bonfida/spl-name-service";
const name = "bonfida"; // We want to register bonfida.sol
const space = 1 * 1_000; // We want a 1kB sized domain (max 10kB)
const buyer = new PublicKey("..."); // Publickey of the buyer
const buyerTokenAccount = new PublicKey("..."); // Publickey of the token account of the buyer (USDC)
const ix = await registerDomainNameV2(name, space, buyer, buyerTokenAccount);
// sign and send the instruction
API
Registration instructions can also be created via API (equivalent to using the SDK):
GET https://sns-sdk-proxy.bonfida.workers.dev/register?buyer={buyer}&domain={domain}&space={space}&serialize={serialize}
This endpoint can be used to register domain for buyer. Additionaly, the buyer dans specify the space it wants to allocate for the domain account. In the case where serialize is true the endpoint will return the transaction serialized in the wire format base64 encoded. Otherwise it will return the instruction in the following format: { programId: string, keys: {isWritable: boolean, isSigner: boolean, pubkey: string}[], data: string }
where data
is base64 encoded.
This endpoint also supports the optional mint parameter to change the mint of the token used for registration (currently supports USDC, USDT, FIDA and wSOL), if mint is omitted it defaults to USDC.
Registration via CPI
Add the sns-registrar
dependency to your Cargo.toml
:
[dependencies]
sns-registrar = { git = "ssh://git@github.com/Bonfida/sns-registrar.git", features = ["no-entrypoint"] }
In your code make sure to import the required functions
#![allow(unused)] fn main() { use sns_registrar::{instruction_auto::create_split_v2, processor::create_split_v2}; }
The main function for domain registration is create_split_v2
. Here's how to use it:
#![allow(unused)] fn main() { let registration_instruction = create_split_v2( sns_registrar::ID, create_split_v2::Accounts { naming_service_program: accounts.spl_name_service.key, root_domain: accounts.root_domain.key, name: accounts.name_account.key, reverse_lookup: accounts.reverse_lookup.key, system_program: accounts.system_program.key, central_state: accounts.sns_registrar_central_state.key, buyer: accounts.buyer.key, domain_owner: accounts.new_domain_owner.key, buyer_token_source: accounts.buyer_token_source.key, pyth_feed_account: accounts.pyth_feed_account.key, vault: accounts.bonfida_fee_vault.key, spl_token_program: accounts.spl_token_program.key, rent_sysvar: accounts.rent_sysvar.key, state: accounts.sns_registrar_state.key, referrer_account_opt: None, fee_payer: accounts.fee_payer.key, }, create_split_v2::Params { name: domain_name, space: 0, referrer_idx_opt: None, }, ); }
Important Account Keys:
sns_registrar
: Constant keyjCebN34bUfdeUYJT13J1yG16XWQpt5PDx6Mse9GUqhR
naming_service_program
: Constant keynamesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX
root_domain
: Constant key58PwtjSDuFHuUkYjH9BYnnQKHfwo9reZhC2zMJv9JPkx
central_state
: Constant key33m47vH6Eav6jr5Ry86XjhRft2jRBLDnDgPSHoquXi2Z
name
: Computed usingsns_registrar::utils::get_name_key("something", None)?;
for registeringsomething.sol
reverse_lookup
: Computed usingsns_registrar::utils::get_reverse_key(accounts.name_account.key, None)?;
pyth_feed_account
: Derived based on the mint used for registration. See Pyth price feed derivation and token utilitiesvault
: ATA of5D2zKog251d6KPCyFyLMt3KroWwXXPWSgTPyhV22K2gR
for the mint used in registrationstate
: PDA derived as:Pubkey::find_program_address(&[&accounts.name_account.key.to_bytes()], accounts.sns_registrar.key).0
domain_owner
andbuyer
can be different this flexibility enables scenarios where one account pays for the registration while another becomes the owner of the domain.buyer_token_source
is the associated token account ofbuyer
for the mint used for the registration and used to pay the registration
After creating the instruction, invoke it like this:
#![allow(unused)] fn main() { invoke_signed( ®istration_instruction, &[ accounts.sns_registrar.clone(), accounts.spl_name_service.clone(), accounts.root_domain.clone(), accounts.name_account.clone(), accounts.reverse_lookup.clone(), accounts.system_program.clone(), accounts.sns_registrar_central_state.clone(), accounts.central_state.clone(), accounts.fee_payer.clone(), accounts.destination_token_vault.clone(), accounts.pyth_feed_account.clone(), accounts.bonfida_fee_vault.clone(), accounts.spl_token_program.clone(), accounts.rent_sysvar.clone(), accounts.sns_registrar_state.clone(), accounts.new_domain_owner.clone(), ], &[&signer_seeds], )?; }
- The
space
parameter increate_split_v2::Params
is set to0
in this example. - The
referrer_account_opt
andreferrer_idx_opt
are set toNone
here. Use these for referral functionality if required.