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)
}
}
} // END OF ENUM
struct AtomicAttribute: Encodable {
var key: String
var value: [AtomicEnum]
}
// ATOMIC MINTING DATA
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()
// FILL MINTING DATA STRUCT
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)
transaction?.signAndBroadcast