Closed ZhongFuze closed 6 months ago
https://github.com/NextDotID/relation_server/pull/128
Docs: https://github.com/Bonfida/sns-sdk/tree/main?tab=readme-ov-file#rust Cargo.toml Notice: If sns-sdk version=1.4.0,other depends should version<1.16.0 (Must not upgrade to 1.16.16)
solana-sdk = "<1.16.0"
solana-client = "~1.14.1"
spl-name-service = { version = "0.2.0", features = ["no-entrypoint"] }
spl-token = "3.0.0"
solana-account-decoder = "<1.16.0"
solana-program = "<1.16.0"
sns-sdk = "=1.4.0"
borsh = "0.9"
Independent query Twitter handle binding. https://sns.guide/domain-name/wallet-guide/twitter-handles.html
There aren't two twitter handle methods in the Rust SDK.
Using the JavaScript library as a guide, I replicated and encapsulated get_twitter_registry
and get_handle_and_registry_key
.
lazy_static! {
pub static ref TWITTER_VERIFICATION_AUTHORITY: Pubkey =
Pubkey::from_str("FvPH7PrVrLGKPfqaf3xJodFTjZriqrAXXLTVWEorTFBi")
.expect("Invalid public key");
pub static ref TWITTER_ROOT_PARENT_REGISTRY_KEY: Pubkey =
Pubkey::from_str("4YcexoW3r78zz16J2aqmukBLRwGq6rAvWzJpkYAXqebv")
.expect("Invalid public key");
}
To find the Twitter handle associated to a public key
async fn get_handle_and_registry_key(
rpc_client: &RpcClient,
pubkey: &str,
) -> Result<Option<String>, Error> {
let verified_pubkey = Pubkey::from_str(pubkey)?;
let hashed_verified_pubkey = get_hashed_name(&verified_pubkey.to_string());
let (reverse_registry_key, _) = get_seeds_and_key(
&spl_name_service::id(),
hashed_verified_pubkey,
Some(&TWITTER_VERIFICATION_AUTHORITY),
Some(&TWITTER_ROOT_PARENT_REGISTRY_KEY),
);
let ascii_start_index = 33; // Starting index of "dansform"
let handle = match resolve_name_registry(rpc_client, &reverse_registry_key).await? {
Some((_, vec_u8)) => {
// Skip null bytes at the beginning of the ASCII part
let ascii_part = &vec_u8[ascii_start_index..];
let trimmed_ascii_part = ascii_part
.iter()
.skip_while(|&&byte| byte == 0)
.cloned()
.collect::<Vec<u8>>();
Some(deserialize_record_v2_content(
&trimmed_ascii_part,
Record::Twitter,
)?)
}
None => None,
};
Ok(handle)
}
To find the public key associated to a Twitter handle
async fn get_twitter_registry(
rpc_client: &RpcClient,
twitter_handle: &str,
) -> Result<Option<Pubkey>, Error> {
let hashed_twitter_handle = get_hashed_name(twitter_handle);
let (twitter_handle_registry_key, _) = get_seeds_and_key(
&spl_name_service::id(),
hashed_twitter_handle,
None, // Assuming no name class
Some(&TWITTER_ROOT_PARENT_REGISTRY_KEY),
);
// Some(NameRecordHeader { parent_name: 4YcexoW3r78zz16J2aqmukBLRwGq6rAvWzJpkYAXqebv, owner: CLnUobvN8Fy7vhDMkQqNF7STxk5CT7MoePXvkgUGgdc9, class: 11111111111111111111111111111111 })
match resolve_name_registry(rpc_client, &twitter_handle_registry_key).await? {
Some((header, _)) => Ok(Some(header.owner)),
None => Ok(None),
}
}
Solana name service: https://www.sns.id