Attributes
The Attributes extension allows creating a list of on-chain values (key/value pairs) for an asset. The on-chain aspect means these values can be read by other Solana programs and therefore be used by them (e.g., for gaming).
The extension consists of a list of Traits, where each trait has a name and a value field:
| Field | Description |
|---|---|
values[0..n] | List of Trait objects. |
Each Trait object is represented by: | |
name | Name of the trait. |
value | The value associated with the trait. |
Creating Attributes
The Attributes extension can be created using either the allocate, create or update instructions.
- JavaScript
- Rust
- Rust (on-chain)
import { allocate, attributes } from '@nifty-oss/asset';
await allocate(umi, {
asset,
payer,
extension: attributes([{ name: 'head', value: 'hat' }]),
}).sendAndConfirm(umi);
use nifty_asset::{
extensions::{Attributes, AttributesBuilder, ExtensionBuilder},
instructions::AllocateBuilder,
types::{ExtensionInput, ExtensionType},
};
let mut attributes = AttributesBuilder::default();
attributes.add("head", "hat");
let ix = AllocateBuilder::new()
.asset(asset.pubkey())
.payer(Some(payer.pubkey()))
.system_program(Some(system_program::id()))
.extension(ExtensionInput {
extension_type: ExtensionType::Attributes,
length: attributes.len() as u32,
data: Some(attributes),
})
.instruction();
use nifty_asset::{
extensions::{Attributes, AllocateCpiBuilder, ExtensionBuilder},
instructions::AllocateBuilder,
types::{ExtensionInput, ExtensionType},
};
let mut attributes = AttributesBuilder::default();
attributes.add("head", "hat");
AllocateCpiBuilder::new(ctx.accounts.nifty_asset_program)
.asset(ctx.accounts.group)
.payer(Some(ctx.accounts.payer))
.system_program(Some(ctx.accounts.system_program))
.extension(ExtensionInput {
extension_type: ExtensionType::Attributes,
length: attributes.len() as u32,
data: Some(attributes),
})
.invoke();
Fetching Attributes
Given an asset account, it is possible to retrieve the attributes of an asset. Note that not all assets might have the extension, therefore it is necessary to assert if the extension was found.
- JavaScript
- Rust
- Rust (on-chain)
import {
ExtensionType,
fetchAsset,
getExtension
} from '@nifty-oss/asset';
const asset = await fetchAsset(umi, address);
const attributes = getExtension(asset, ExtensionType.Attributes);
if (attributes) {
attributes.values.forEach(({ name, value }) => {
console.log(name + '=' + value);
});
}
use nifty_asset::{
extensions::Attributes,
state::Asset,
};
let account = get_account(address)
.await
.unwrap();
let account_data = account.data.as_ref();
if let Some(attributes) = Asset::get::<Attributes>(account_data) {
println!("attributes: {:?}", attributes);
}
use nifty_asset::{
extensions::Attributes,
state::Asset,
};
let data = (*ctx.accounts.asset.data).borrow();
if let Some(attributes) = Asset::get::<Attributes>(&data) {
msg!("attributes: {:?}", attributes);
}