Which properties are required for Solana NFT metadata? - web3js

This seems to be the most authoritative documentation that I've found so far: https://docs.metaplex.com/nft-standard
{
"name": "Solflare X NFT",
"symbol": "",
"description": "Celebratory Solflare NFT for the Solflare X launch",
"seller_fee_basis_points": 0,
"image": "https://www.arweave.net/abcd5678?ext=png",
"animation_url": "https://www.arweave.net/efgh1234?ext=mp4",
"external_url": "https://solflare.com",
"attributes": [
{ "trait_type": "web", "value": "yes" },
{ "trait_type": "mobile", "value": "yes" },
{ "trait_type": "extension", "value": "yes" }
],
"collection": { "name": "Solflare X NFT", "family": "Solflare" },
"properties": {
"files": [
{
"uri": "https://www.arweave.net/abcd5678?ext=png",
"type": "image/png"
},
{
"uri": "https://watch.videodelivery.net/9876jkl",
"type": "unknown",
"cdn": true
},
{ "uri": "https://www.arweave.net/efgh1234?ext=mp4", "type": "video/mp4" }
],
"category": "video",
"creators": [
{ "address": "SOLFLR15asd9d21325bsadythp547912501b", "share": 100 }
]
}
}
These same docs state clearly that many fields are optional and should be omitted when not used. But which fields are required and which ones are optional?

Depends what you want to use it for. The simplest requirements I have used were:
{
"name": "Solflare X NFT",
"seller_fee_basis_points": 0,
"image": "https://www.arweave.net/abcd5678?ext=png",
"properties": {
"files": [
{
"uri": "https://www.arweave.net/abcd5678?ext=png",
"type": "image/png"
}
],
"category": "image",
"creators": [
{ "address": "SOLFLR15asd9d21325bsadythp547912501b", "share": 100 }
]
}
}
There is no reason to not include the rest as the cost of hosting this off-chain is minimal. I think most things would be optional but the important ones for an NFT would be the image attribute, as otherwise the NFT wont be able to be displated anywhere, and probably then the propertiess field because some wallets, DApps and marketplaces might use these fields to check file type. Creators should also be added if you want to receive royalties and without this field could result in your collection failing to be listed on marketplaces.
A short answer though, the minimum is not defined anywhere as removing certain things could break certain third party DApps. Depending how/where you want to use your NFT I would find out the requirements if you are desperately trying to minimise the metadata. Otherwise try to keep most of it.

Related

logic apps dictionary variables

I think I want to use a dictionary variable in my logic apps. The contains function seems useful to me, especially if my collection is a dictionary.  I can't see how to Initialize a variable as a dictionary, though. Have any of you done anything like that?
More specifically,
I get a collection of objects from an API like: 
[
{
"Name": "Mr. Test Smith",
"Type": "ACCOUNTSPAYABLE"
},
{
"Name": "Mr. Test Smith",
"Type": "DISPATCH"
},
{
"Name": "Different Name",
"Type": "ACCOUNTSPAYABLE"
}
]
I want to 'merge' them, using name as a key, to get something like this:
[
{
"Name": "Mr. Test Smith",
"Types": [
"ACCOUNTSPAYABLE",
"DISPATCH"
]
},
{
"Name": "Different Name",
"Types": [
"ACCOUNTSPAYABLE"
]
}
]
You can call api from http trigger or action and initialize response from api into an array variable.
Used a HTTP trigger in logic app and assigned body of api response to an array variable as shown below,
Payload of http trigger is,
{
"items": {
"properties": {
"Name": {
"type": "string"
},
"Type": {
"type": "string"
}
},
"required": [
"Name",
"Type"
],
"type": "object"
},
"type": "array"
}
The variable value will be assigned like this,
[
{
"Name": "Mr. Test Smith",
"Type": "ACCOUNTSPAYABLE"
},
{
"Name": "Mr. Test Smith",
"Type": "DISPATCH"
},
{
"Name": "Different Name",
"Type": "ACCOUNTSPAYABLE"
}
]
Once value assigned to variable, use inline action to merge objects
based on Name property as mentioned SO

Arm Templates Copy Function - Skip Properties in loop if not present - Network Security Group - sourceAddressPrefix/sourceAddressPrefixes

I am trying to implement a copy function in a arm template used to deploy Network security group.
I have previously deployed templates using this format but due to Microsoft deciding to use two distinct names depending on if the Property is a single item or a list I am unable to use the copy function.
I have had to look into using If statements to ignore null parameters if present in a loop, which I have not been able to achieve.
So my question is how to go through a loop and ignore a specific Property if it not present in a loop.
The two Properties in question are
sourceAddressPrefix or sourceAddressPrefixes.
This is causing problems in the 2nd interation, I will get an error message
The
language expression property 'sourceAddressPrefixes' doesn't exist (if i switch the order of the paramater file, ie sourceAddressPrefixes is first, then the error message will point to 'sourceAddressPrefix'
Parameter file,
as you can see there are two secutiry rules, one set as sourceAddressPrefix, and the other sourceAddressPrefixes
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "westeurope"
},
"SecurityRule":{
"value": [
{
"name": "AllowSyncWithAzureAD",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 101,
"direction": "Inbound"
},
{
"name": "AllowPSRemotingSliceP",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "5986",
"sourceAddressPrefixes": "[variables('PSRemotingSlicePIPAddresses')]",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 301,
"direction": "Inbound"
}
]
}
}
}
in the Template file I have added both properties with if statements, but clearly I have not written them correctly, as the intended outcome is, if in a loop the property does not exist, ignore property.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"SecurityRule": {
"type": "array"
}
},
"variables": {
"domainServicesNSGName": "AGR01MP-NSGAADDS01",
"PSRemotingSlicePIPAddresses": [
"52.182.100.238",
"52.180.177.87"
],
"RDPIPAddresses": [
"210.66.188.40/27",
"15.156.75.52/27",
"134.104.124.36/27",
"144.122.4.96/27"
],
"PSRemotingSliceTIPAddresses": [
"56.180.182.67",
"56.180.121.39",
"56.175.228.121"
]
},
"resources": [
{
"apiVersion": "2018-10-01",
"type": "Microsoft.Network/networkSecurityGroups",
"name": "[variables('domainServicesNSGName')]",
"location": "[parameters('location')]",
"properties": {
"copy": [
{
"name":"securityRules",
"count": "[length(parameters('securityRule'))]",
"mode": "serial",
"input": {
"name": "[concat(parameters('securityRule')[copyIndex('securityRules')].name)]",
"properties": {
"protocol": "[concat(parameters('securityRule')[copyIndex('securityRules')].protocol)]",
"sourcePortRange": "[concat(parameters('securityRule')[copyIndex('securityRules')].sourcePortRange)]",
"destinationPortRange": "[concat(parameters('securityRule')[copyIndex('securityRules')].destinationPortRange)]",
"sourceAddressPrefixes": "[if(equals(parameters('securityRule')[copyIndex('securityRules')].sourceAddressPrefixes,''), json('null'), parameters('securityRule')[copyIndex('securityRules')].sourceAddressPrefixes)]",
"sourceAddressPrefix": "[if(equals(parameters('securityRule')[copyIndex('securityRules')].sourceAddressPrefix,''), json('null'), parameters('securityRule')[copyIndex('securityRules')].sourceAddressPrefix)]",
"destinationAddressPrefix": "[concat(parameters('securityRule')[copyIndex('securityRules')].destinationAddressPrefix)]",
"access": "[concat(parameters('securityRule')[copyIndex('securityRules')].access)]",
"priority": "[concat(parameters('securityRule')[copyIndex('securityRules')].priority)]",
"direction": "[concat(parameters('securityRule')[copyIndex('securityRules')].direction)]"
}
}
}
]
}
}
],
"outputs": {}
}
found solution
"sourceAddressPrefix": "[if(equals(parameters('SecurityRule')[copyIndex('securityRules')].name, 'SyncWithAzureAD'), parameters('SecurityRule')[copyIndex('securityRules')].sourceAddressPrefix, json('null'))]" ,
"sourceAddressPrefixes": "[if(contains(parameters('SecurityRule')[copyIndex('securityRules')].name, 'Allow'), parameters('SecurityRule')[copyIndex('securityRules')].sourceAddressPrefixes, json('null'))]" ,
the above code allows me to deploy to change to ignore a null value in an array. Though I had to change AllowSyncWithAzureAD to SyncWithAzureAD, in order for it not to be picked up by the 2nd line

SchemaForm array conditional

Background
I am making a form using http://schemaform.io/
Setup
I am trying to make an array of objects that a user can make using a form. So, the user can add as many items into the array as they want.
The array of items contains a type, then another field depending on what the type was.
If the user clicks REST, I want it to offer a field called method.
If the user clicks SSH, I want it to offer a field called path.
Code so far
SCHEMA
{
"type": "object",
"title": "Command Asset",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"commands": {
"type": "array",
"title": "Actions",
"items": {
"type": "object",
"properties": {
"commandType": {
"title": "Command Type",
"type": "string",
"enum": [
"REST",
"SSH"
]
},
"path": {
"title": "Path",
"type": "string"
},
"method": {
"title": "Method",
"type": "string"
}
}
}
}
}
}
FORM
[
{
"type": "help",
"helpvalue": "<h5>Command</h5>"
},
"name",
{
"title":"Command",
"key": "commands",
"items": [
"commands[].commandType",
{
"type": "conditional",
"condition": "modelData.commands[0].commandType=='SSH'",
"items": [
{
"key": "commands[].path"
}
]
},
{
"type": "conditional",
"condition": "modelData.commands[0].commandType=='REST'",
"items": [
{
"key": "commands[].method"
}
]
}
]
}
]
One can test this code here: http://schemaform.io/examples/bootstrap-example.html
Question
As one can see, the code I have now makes all the items' secondary properties (path or method) dependent on the first item in the array's commandType (at [0]), but I want it to depend on the commandType of the corresponding item. So, if item one has commandType of REST, it offers a method field and if item two has a command type of SSH it offers a field of path and so on.
I found an answer.
Replace the [0] with [arrayIndex].
I found it from here: https://github.com/json-schema-form/angular-schema-form/commit/21f6d3ab64435b032456dfe19e03f96b29366320

Non-Primitive Values from a Registered Content Provider are not showing a value

I'm using the /v2/registrations endpoint to register a content provider with the legacyForwarding flag being set. Therefore my Content Provider is offering the v1/queryContext endpoint
When I am returning a simple value (Integer, String etc.) such as a temperature the data is added to the context correctly:
{
"contextResponses": [
{
"contextElement": {
"attributes": [
{
"name": "temperature",
"type": "Number",
"value": 27
}
],
"id": "urn:ngsi-ld:Store:001",
"isPattern": "false",
"type": "Store"
},
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}
]
}
However when trying to return an array of strings as shown from a Context Provider.
{
"contextResponses": [
{
"contextElement": {
"attributes": [
{
"name": "tweets",
"type": "Array",
"value": [
"String 1",
"String 2"
]
}
],
"id": "urn:ngsi-ld:Store:002",
"isPattern": "false",
"type": "Store"
},
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}
]
}
I can see the request being sent in the log and I can retrieve the following entity:
{
"id": "urn:ngsi-ld:Store:002",
"type": "Store",
"address": {
"type": "PostalAddress",
"value": "",
"metadata": {}
},
"location": {
"type": "geo:json",
"value": "",
"metadata": {}
},
"name": {
"type": "Text",
"value": "Checkpoint Markt",
"metadata": {}
},
"tweets": {
"type": "Array",
"value": "",
"metadata": {}
}
}
As you can see the "tweets" value is blank, but the attribute exists and the type has been successfully received.
My question is how should I return an Array or an Object as a value from a Content Provider so that Orion is able to display the data received correctly?
Further investigation from the Orion Team shows that this was indeed a bug and an issue was raised against Orion 2.0.0. With the latest release, the bug has now been fixed.
The solution is to upgrade to a later version of Orion - currently 2.1.0 (at the time of writing)

JSON Schema draft 4 with unordered array

I would like to create schema which allows me to add multiple addresses when the following is true:
1)Correspondence address must be there
2)Residence address must be there
3)Other types of addresses could be there
4) They can appear in any order
Is this possible to solve with JSON schema? I heard about "contains" in draft 6. But since we are using Altova XML SPY (2018), which is only supporting draft 4, for schema creation, I would like to know how to solve this in draft 4. Are you aware of any good editor for draft 6?
I read JSON schema to enforce array contents but cannot find the answer there. I also read https://gist.github.com/anonymous/7359001 which explains how to have "contains" in draft 4, but was unable to apply it to my case.
So if you can guide me, how to use it for the following schema(which fullfills my requirements except number 4), I would be very thankfull.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Corespondence"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Residence"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
}
],
"additionalItems": {
"$ref": "#/definitions/Address"
}
}
},
"definitions": {
"Address": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Corespondence",
"Residence",
"Other"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
}
}
}
draft-06 has "contains" keyword allowing to test the presence of items matching the schema in the array.
Alternatively, instead of heterogenous array you could use a map with difference address types defined in different properties, so your data could be:
{
addresses: {
correspondence: {/*...*/},
residence: {/*...*/}
// etc...
}
}
The reason contains was added to draft-06 is that it is not possible to accomplish the same thing with draft-04 keywords.
There are several implementations supporting draft-06 on the software page: http://json-schema.org/implementations.html

Resources