radix-native-sdk 1.3.1

A library for developing native blueprints, from the Radix DLT project.
Documentation
use crate::modules::metadata::Metadata;
use crate::modules::role_assignment::RoleAssignment;
use radix_common::data::scrypto::scrypto_encode;
use radix_common::prelude::ScryptoEncode;
use radix_common::types::GlobalAddress;
use radix_engine_interface::api::*;
use radix_engine_interface::object_modules::metadata::{
    MetadataSetInput, MetadataVal, METADATA_SET_IDENT,
};
use radix_engine_interface::object_modules::ModuleConfig;
use radix_engine_interface::prelude::*;
use radix_engine_interface::types::NodeId;
use radix_rust::indexmap;
use sbor::rust::prelude::*;
use sbor::rust::prelude::{Debug, ToOwned};

#[derive(Debug)]
pub struct BorrowedObject(pub NodeId);

impl BorrowedObject {
    pub fn new<T>(node_id: T) -> Self
    where
        T: Into<[u8; NodeId::LENGTH]>,
    {
        Self(NodeId(node_id.into()))
    }

    pub fn set_metadata<Y: SystemApi<E>, E: SystemApiError, S: AsRef<str>, V: MetadataVal>(
        &mut self,
        key: S,
        value: V,
        api: &mut Y,
    ) -> Result<(), E> {
        api.call_module_method(
            &self.0,
            AttachedModuleId::Metadata,
            METADATA_SET_IDENT,
            scrypto_encode(&MetadataSetInput {
                key: key.as_ref().to_owned(),
                value: value.to_metadata_value(),
            })
            .unwrap(),
        )?;

        Ok(())
    }
}

pub fn globalize_object<Y: SystemApi<E>, E: SystemApiError>(
    object_id: NodeId,
    owner_role: OwnerRole,
    address_reservation: GlobalAddressReservation,
    main_roles: RoleAssignmentInit,
    metadata: ModuleConfig<MetadataInit>,
    api: &mut Y,
) -> Result<GlobalAddress, E> {
    let role_assignment = {
        let roles = indexmap!(
            ModuleId::Main => main_roles,
            ModuleId::Metadata => metadata.roles,
        );
        RoleAssignment::create(owner_role, roles, api)?.0 .0
    };

    let metadata = Metadata::create_with_data(metadata.init, api)?.0;

    let address = api.globalize(
        object_id,
        indexmap!(
            AttachedModuleId::RoleAssignment => role_assignment,
            AttachedModuleId::Metadata => metadata,
        ),
        Some(address_reservation),
    )?;

    Ok(address)
}

#[allow(clippy::too_many_arguments)]
pub fn globalize_object_with_inner_object_and_event<
    Y: SystemApi<E>,
    E: SystemApiError,
    V: ScryptoEncode,
>(
    object_id: NodeId,
    owner_role: OwnerRole,
    address_reservation: GlobalAddressReservation,
    main_roles: RoleAssignmentInit,
    metadata: ModuleConfig<MetadataInit>,
    inner_object_bp: &str,
    inner_object_fields: IndexMap<FieldIndex, FieldValue>,
    event_name: &str,
    event: V,
    api: &mut Y,
) -> Result<(GlobalAddress, NodeId), E> {
    let role_assignment = {
        let roles = indexmap!(
            ModuleId::Main => main_roles,
            ModuleId::Metadata => metadata.roles,
        );
        RoleAssignment::create(owner_role, roles, api)?.0 .0
    };
    let metadata = Metadata::create_with_data(metadata.init, api)?.0;

    let (address, inner_object) = api
        .globalize_with_address_and_create_inner_object_and_emit_event(
            object_id,
            indexmap!(
                AttachedModuleId::RoleAssignment => role_assignment,
                AttachedModuleId::Metadata => metadata,
            ),
            address_reservation,
            inner_object_bp,
            inner_object_fields,
            event_name,
            scrypto_encode(&event).unwrap(),
        )?;

    Ok((address, inner_object))
}