I've been trying to solve this for weeks but I'm new to this. Atomic Assets use C++ variants to hold asset data. I've tried a range of ways to create structs and enums that can be encoded into variants, no luck. Here are some details from the creators of the Atomic Assets standard:

The main issue is using Swift's Codable to interact with the C++ Variants used in this Atomic Assets NFT Standard. The Serialization doesn't seem to work, I'm getting a code 500 "failed to deserialize variant" response among other things.

"In the Atomic Assets smart contract, the ATTRIBUTE_MAP type is a map from string to the ATTRIBUTE type, and the ATTRIBUTE type is a variant of lots of different types. Maps are represented of a vector of key / value pairs.

To pass maps to nodes/ eosjs, use the following format: [{"key": MYKEY, value: MYVALUE}, ...]. For this map, keys are strings and values are variants, so for example:

[{"key": "id", "value": ["uint64", 1024]}, {"key": "color", "value": ["string", "pink"]}]

You can read more here: https://github.com/pinknetworkx/atomicassets-contract/wiki/Custom-Types

I'm assuming in the swift sdk you also have to pass it as a vector / array of key / value structs, and I'm not sure how variants work in the swift sdk" - Pink Network on Telegram

I hesitate to put up my latest attempt, pretty sure it's way off, but here it is:

enum AtomicEnum: Encodable {

    case string(String)
    case data8(UInt8)
    case data16(UInt16)
    case data32(UInt32)

    enum CodingKeys: CodingKey {
        case string, data8, data16, data32

    func encode(to encoder: Encoder) throws {

        switch self {
        case .string(let str):
        try str.encode(to: encoder)
        case .data8(let int):
        try int.encode(to: encoder)
        case .data16(let int):
        try int.encode(to: encoder)
        case .data32(let int):
        try int.encode(to: encoder)

struct AtomicAttribute: Encodable {
        var key: String
        var value: [AtomicEnum]

    struct MintingData: Encodable {
        var authorized_minter: EosioName
        var collection_name: EosioName
        var schema_name: EosioName
        var template_id: Int32
        var new_asset_owner: EosioName
        var immutable_data: [AtomicAttribute]
        var mutable_data: [AtomicAttribute]
        var tokens_to_back: [Int]

let nameAttribute = AtomicAttribute(key: "name", value: [AtomicEnum.string("string"), AtomicEnum.string(atomicName)])
let imgAttribute = AtomicAttribute(key: "img", value: [AtomicEnum.string("string"), AtomicEnum.string("")])
let resonanceAttribute = AtomicAttribute(key: "resonance", value: [AtomicEnum.string("uint32"), AtomicEnum.data32(UInt32(hybridSporeResonance))])

let attributeMap: [AtomicAttribute] = [nameAttribute, imgAttribute, resonanceAttribute]

 let transaction = transactionFactory?.newTransaction()
 let sporemintingData = try? MintingData(authorized_minter: EosioName(minter), collection_name: EosioName(collection), schema_name: EosioName(schema), template_id: atomicTemplateId, new_asset_owner: EosioName(recipient), immutable_data: attributeMap, mutable_data: [], tokens_to_back: [])

                 let action = try EosioTransaction.Action(
                     account: EosioName("atomicassets"),
                     name: EosioName("mintasset"),
                     authorization: [EosioTransaction.Action.Authorization(
                         actor: EosioName(recipient),
                         permission: EosioName("active"))
                     data: sporemintingData
                transaction?.add(action: action)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.