├── src ├── Examples │ ├── Demo │ │ ├── Roboto-Regular.ttf │ │ ├── qr_transparent.png │ │ ├── RobotoMono-Regular.ttf │ │ ├── Scenes │ │ │ ├── SampleScene │ │ │ │ ├── LightingData.asset │ │ │ │ ├── ReflectionProbe-0.exr │ │ │ │ ├── Lightmap-0_comp_dir.png │ │ │ │ ├── Lightmap-0_comp_light.exr │ │ │ │ ├── Lightmap-1_comp_dir.png │ │ │ │ ├── Lightmap-1_comp_light.exr │ │ │ │ ├── LightingData.asset.meta │ │ │ │ ├── OcclusionCullingData.asset.meta │ │ │ │ ├── ReflectionProbe-0.exr.meta │ │ │ │ ├── Lightmap-0_comp_dir.png.meta │ │ │ │ ├── Lightmap-0_comp_light.exr.meta │ │ │ │ ├── Lightmap-1_comp_dir.png.meta │ │ │ │ ├── Lightmap-1_comp_light.exr.meta │ │ │ │ └── OcclusionCullingData.asset │ │ │ ├── SampleScene.unity.meta │ │ │ └── SampleScene.meta │ │ ├── Scenes.meta │ │ ├── Materials.meta │ │ ├── Plugins.meta │ │ ├── Scripts.meta │ │ ├── Scripts │ │ │ ├── CardanoBech32.meta │ │ │ ├── CardanoBech32 │ │ │ │ ├── CardanoBech32.csproj.meta │ │ │ │ ├── Helper.meta │ │ │ │ ├── Interface.meta │ │ │ │ ├── Bech32Engine.cs.meta │ │ │ │ ├── Helper │ │ │ │ │ ├── Helper.cs.meta │ │ │ │ │ └── Helper.cs │ │ │ │ ├── CardanoBech32Wrapper.cs.meta │ │ │ │ ├── Interface │ │ │ │ │ ├── ICardanoBech32Wrapper.cs.meta │ │ │ │ │ └── ICardanoBech32Wrapper.cs │ │ │ │ ├── CardanoBech32.csproj │ │ │ │ ├── CardanoBech32Wrapper.cs │ │ │ │ └── Bech32Engine.cs │ │ │ ├── Demo.cs.meta │ │ │ ├── Door.cs.meta │ │ │ ├── UI.cs.meta │ │ │ ├── Console.cs.meta │ │ │ ├── PlayerController.cs.meta │ │ │ ├── UI.cs │ │ │ ├── Console.cs │ │ │ ├── Door.cs │ │ │ ├── PlayerController.cs │ │ │ └── Demo.cs │ │ ├── Materials │ │ │ ├── Door.mat.meta │ │ │ ├── Ground.mat.meta │ │ │ ├── Wall.mat.meta │ │ │ ├── Foliage.mat.meta │ │ │ ├── BetterFoliage.mat.meta │ │ │ ├── Door.mat │ │ │ ├── Wall.mat │ │ │ ├── Foliage.mat │ │ │ ├── Ground.mat │ │ │ └── BetterFoliage.mat │ │ ├── Roboto-Regular.ttf.meta │ │ ├── RobotoMono-Regular.ttf.meta │ │ ├── Plugins │ │ │ ├── nami.jslib │ │ │ └── nami.jslib.meta │ │ └── qr_transparent.png.meta │ └── README.md ├── Generator │ ├── Microsoft │ │ └── OpenApi │ │ │ └── net46 │ │ │ ├── SharpYaml.dll │ │ │ ├── Microsoft.OpenApi.dll │ │ │ └── Microsoft.OpenApi.Readers.dll │ ├── Editor │ │ ├── BlockfrostGenerator.cs.meta │ │ ├── Models.cs │ │ ├── Endpoints.cs │ │ └── BlockfrostGenerator.cs │ └── README.md └── Blockfrost.io │ ├── package.json.meta │ ├── Editor.meta │ ├── Scripts.meta │ ├── Scripts │ ├── Blockfrost.asmdef.meta │ ├── Model.cs.meta │ ├── Cardano.cs.meta │ ├── Client.cs.meta │ ├── Filters.cs.meta │ ├── Milkomeda.cs.meta │ ├── OAInfo.cs.meta │ ├── Configuration.cs.meta │ ├── Blockfrost.asmdef │ ├── OAInfo.cs │ ├── Milkomeda.cs │ ├── Filters.cs │ ├── Configuration.cs │ ├── Client.cs │ └── Cardano.cs │ ├── Editor │ ├── Blockfrost.Editor.asmdef.meta │ ├── ConfigurationEditor.cs.meta │ ├── Blockfrost.Editor.asmdef │ └── ConfigurationEditor.cs │ ├── BlockfrostInfo.asset.meta │ ├── package.json │ └── BlockfrostInfo.asset ├── .github └── assets │ └── unity_cardano_network.png ├── README.md └── LICENSE /src/Examples/Demo/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/Examples/Demo/qr_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/qr_transparent.png -------------------------------------------------------------------------------- /.github/assets/unity_cardano_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/.github/assets/unity_cardano_network.png -------------------------------------------------------------------------------- /src/Examples/Demo/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /src/Generator/Microsoft/OpenApi/net46/SharpYaml.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Generator/Microsoft/OpenApi/net46/SharpYaml.dll -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/LightingData.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Scenes/SampleScene/LightingData.asset -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/ReflectionProbe-0.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Scenes/SampleScene/ReflectionProbe-0.exr -------------------------------------------------------------------------------- /src/Generator/Microsoft/OpenApi/net46/Microsoft.OpenApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Generator/Microsoft/OpenApi/net46/Microsoft.OpenApi.dll -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-0_comp_dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Scenes/SampleScene/Lightmap-0_comp_dir.png -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-0_comp_light.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Scenes/SampleScene/Lightmap-0_comp_light.exr -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-1_comp_dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Scenes/SampleScene/Lightmap-1_comp_dir.png -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-1_comp_light.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Examples/Demo/Scenes/SampleScene/Lightmap-1_comp_light.exr -------------------------------------------------------------------------------- /src/Generator/Microsoft/OpenApi/net46/Microsoft.OpenApi.Readers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivebinaries/cardano-unity/master/src/Generator/Microsoft/OpenApi/net46/Microsoft.OpenApi.Readers.dll -------------------------------------------------------------------------------- /src/Blockfrost.io/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 371efbe7be10b8d4aac7bc63fec27e5d 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 509383543aa759248b620afea7e1de6d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 131a6b21c8605f84396be9f6751fb6e3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7496f3967e1f5d42947297f15d09ab2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e034d9ba645672d4a829fdf91f8a0f9d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bcee253e24564d643b2ff4342a517e73 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cda990e2423bbf4892e6590ba056729 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a502204bba3aef408f08adb568fc2d4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Blockfrost.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be4fcdd22dd41994392923b08dd8863f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Editor/Blockfrost.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d502af6a7273cb4294fce4c3c6363be 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0afc941800ab77541ac18f692dcf5587 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c56d340d1b874474cb25c0b318d829d1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/CardanoBech32.csproj.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5315f573f7caaef4c9071e373fb24be4 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Helper.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cea5f3d417ec41741b9c16d7ece12327 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Interface.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 69ee8f51857721d40a338b512365bf83 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Door.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9c5fdfec18801d469b3c71aca8deab2 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Ground.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf935ec6c9402e04b8cd84dff9e7da53 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Wall.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed3dea6cec6f5c04b9d2072b3e542548 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Blockfrost.io/BlockfrostInfo.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74778d4252fe24912ab73b52e3dd5e8f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Foliage.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dca63e4f3c36b6548878aafa8978aa49 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/BetterFoliage.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1227ac39a82da034f9cdc555dcf2359f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/LightingData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8edbcdbeb2d5dc34ea1ffedd12cd6642 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 112000000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/OcclusionCullingData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c332c1deaf8d09b4e88fad5d11b86bd1 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 36300000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Model.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f358a7f5237f30945b84e369150f31f9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/Demo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79a3ec8a19253d441a119d97afbb4f53 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/Door.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ed817e517045a84db3db919f52bc860 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/UI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 03199f4038a13f24ba83158640a298cc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Cardano.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc925f3308be84ac3b7eff23608d032d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Client.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 090cc837faab71f4b9f906f12cfb01f5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Filters.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee296d841fd543447b388343926517dc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Milkomeda.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f0cc9be89ae340099f1e8243f7344ea 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/OAInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7653c2c134e8c476da620e6b23ecf1df 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/Console.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d079dcdfe5b82147ac832e69849dcdc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Configuration.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9939ab4e8bdef674f8d614eb5927fc8e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Generator/Editor/BlockfrostGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0d09c57307188434a991c4de847902fb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Editor/ConfigurationEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a55d6e0ef8e882a489602acae14136b9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/PlayerController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e10883299f44784ba348ba6f987c860 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Bech32Engine.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6b142ca80ac2194b918518fccaed406 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Helper/Helper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fe9150c7255b3f34fafc281815d02ac8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/CardanoBech32Wrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6cdf0a8c797579a4ab6ec8777d6a2d5f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Interface/ICardanoBech32Wrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c36b2006ceb7854d908f22ab2f77abc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /src/Examples/README.md: -------------------------------------------------------------------------------- 1 | ## Cardano Unity WebGL example 2 | 3 | Simple demo using Nami wallet + blockfrost.io API client. Checks for specific token in a wallet to open door. 4 | 5 | ### Demo 6 | 7 | Demo can be played [here](https://fivebinaries.github.io/cardano-unity/src/Examples/Demo/) 8 | 9 | ### Credits 10 | 11 | - https://github.com/tigrpoolcom/CardanoBech32Wrapper for address conversion -------------------------------------------------------------------------------- /src/Generator/README.md: -------------------------------------------------------------------------------- 1 | # Blockfrost.io API Generator for Unity 2 | 3 | Generator for Blockfrost.io Unity Assset. 4 | 5 | ### Usage 6 | 7 | 1. Open in unity 8 | 2. Load api specification, generate files 9 | 3. Prettify .cs files 10 | 4. Copy, commit, bump version 11 | 12 | ### Credits 13 | 14 | - Inspired by https://github.com/kolodi/UnityOpenApi 15 | - Built using https://github.com/microsoft/OpenAPI.NET 16 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Blockfrost.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Blockfrost", 3 | "rootNamespace": "", 4 | "references": [ 5 | "UniTask" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /src/Blockfrost.io/Editor/Blockfrost.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Blockfrost.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:be4fcdd22dd41994392923b08dd8863f" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /src/Blockfrost.io/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "io.blockfrost.api", 3 | "displayName": "Blockfrost.io API", 4 | "author": { "name": "Blockfrost Team", "email": "contact@blockfrost.io", "url": "https://blockfrost.io" }, 5 | "version": "0.0.1", 6 | "unity": "2018.4", 7 | "description": "API Client for interacting with Cardano blockchain using Blockfrost.io API", 8 | "keywords": [ "cardano", "api", "blockchain" ], 9 | "license": "MIT", 10 | "category": "API", 11 | "dependencies": {} 12 | } 13 | -------------------------------------------------------------------------------- /src/Examples/Demo/Roboto-Regular.ttf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f5100cca667b674aae3022af867ab51 3 | TrueTypeFontImporter: 4 | externalObjects: {} 5 | serializedVersion: 4 6 | fontSize: 16 7 | forceTextureCase: -2 8 | characterSpacing: 0 9 | characterPadding: 1 10 | includeFontData: 1 11 | fontNames: 12 | - Roboto 13 | fallbackFontReferences: [] 14 | customCharacters: 15 | fontRenderingMode: 0 16 | ascentCalculationMode: 1 17 | useLegacyBoundsCalculation: 0 18 | shouldRoundAdvanceValue: 1 19 | userData: 20 | assetBundleName: 21 | assetBundleVariant: 22 | -------------------------------------------------------------------------------- /src/Examples/Demo/RobotoMono-Regular.ttf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6cd943da2b22e52459a02b7bc2dc5731 3 | TrueTypeFontImporter: 4 | externalObjects: {} 5 | serializedVersion: 4 6 | fontSize: 16 7 | forceTextureCase: -2 8 | characterSpacing: 0 9 | characterPadding: 1 10 | includeFontData: 1 11 | fontNames: 12 | - Roboto Mono 13 | fallbackFontReferences: [] 14 | customCharacters: 15 | fontRenderingMode: 0 16 | ascentCalculationMode: 1 17 | useLegacyBoundsCalculation: 0 18 | shouldRoundAdvanceValue: 1 19 | userData: 20 | assetBundleName: 21 | assetBundleVariant: 22 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/UI.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | public class UI : MonoBehaviour 5 | { 6 | public Transform intro; 7 | public Transform error; 8 | 9 | void Start() { 10 | intro.gameObject.SetActive(true); 11 | } 12 | 13 | public void DisableIntro() { 14 | intro.gameObject.SetActive(false); 15 | } 16 | 17 | public void Error(string message) { 18 | var errorText = error.GetComponentInChildren(); 19 | errorText.text = $"ERROR {message}"; 20 | error.gameObject.SetActive(true); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/OAInfo.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using UnityEngine; 4 | 5 | namespace Blockfrost { 6 | 7 | [Serializable] 8 | public class OAInfo : ScriptableObject { 9 | public string Title; 10 | public string Description; 11 | public string Version; 12 | public string TermsOfService; 13 | public OAContact Contact; 14 | public OALicense License; 15 | } 16 | 17 | [Serializable] 18 | public class OAContact { 19 | public string Name; 20 | public string Url; 21 | public string Email; 22 | } 23 | 24 | [Serializable] 25 | public class OALicense { 26 | public string Name; 27 | public string Url; 28 | } 29 | } -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Interface/ICardanoBech32Wrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CardanoBech32 8 | { 9 | interface ICardanoBech32Wrapper 10 | { 11 | string ConvertToHexAddressFromBech32(string inBech32); 12 | bool TryConvertToHexAddressFromBech32(string inBech32, out string valueInHex); 13 | bool TryConvertToHexAddressFromBech32(string inBech32, out byte[] valueInHex); 14 | string ConvertToBech32AddressFromHex(string inHex, AddressType addressType); 15 | string GenerateAssetNameFingerprint(string policyId, string assetname); 16 | string GetStakeAddressFromAddress(string address); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Milkomeda.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Cysharp.Threading.Tasks; 4 | 5 | using UnityEngine.Networking; 6 | 7 | namespace Blockfrost { 8 | public class Milkomeda : Client { 9 | 10 | public Milkomeda() : base() { } 11 | public Milkomeda(Configuration config) : base(config) { } 12 | 13 | private string Url { get => configuration.CurrentServer.FullUrl(configuration.ProjectId); } 14 | 15 | public async UniTask RPC(string json) { 16 | if (json == null || json.Length == 0) { 17 | throw new ArgumentNullException("json"); 18 | } 19 | 20 | byte[] payload = new System.Text.UTF8Encoding().GetBytes(json); 21 | return await Post(Url, payload); 22 | } 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/CardanoBech32.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | README.md 6 | LICENSE.txt 7 | https://github.com/tigrpoolcom/CardanoBech32Wrapper 8 | https://github.com/tigrpoolcom/CardanoBech32Wrapper 9 | git 10 | https://github.com/tigrpoolcom 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Examples/Demo/Plugins/nami.jslib: -------------------------------------------------------------------------------- 1 | mergeInto(LibraryManager.library, { 2 | 3 | LoadBaseAddress: function () { 4 | window.cardano.nami.enable().then(function(api) { 5 | api.getUsedAddresses().then(function(addrs) { 6 | localStorage.setItem('NamiBaseAddress', addrs[0]); 7 | }) 8 | }) 9 | }, 10 | 11 | GetBaseAddress: function () { 12 | var addr = localStorage.getItem('NamiBaseAddress'); 13 | if (!addr) return ""; 14 | var bufferSize = lengthBytesUTF8(addr) + 1; 15 | var buffer = _malloc(bufferSize); 16 | stringToUTF8(addr, buffer, bufferSize); 17 | return buffer; 18 | }, 19 | 20 | ClearBaseAddress: function () { 21 | localStorage.removeItem('NamiBaseAddress'); 22 | } 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/Console.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | public class Console : MonoBehaviour { 7 | 8 | public Transform panel; 9 | public int keepLines; 10 | private Text console; 11 | 12 | private Queue lines; 13 | // Start is called before the first frame update 14 | void Start() { 15 | console = panel.GetComponentInChildren(); 16 | lines = new Queue(keepLines); 17 | } 18 | 19 | void Update() { 20 | if (Input.GetKeyDown(KeyCode.C)) { 21 | panel.gameObject.SetActive(!panel.gameObject.activeSelf); 22 | } 23 | } 24 | 25 | public void Log(string message, string data) { 26 | if (lines.Count >= keepLines) lines.Dequeue(); 27 | lines.Enqueue($"{message} {data}"); 28 | console.text = string.Join("\n", lines); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/Door.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using UnityEngine; 3 | 4 | public class Door : MonoBehaviour { 5 | public Vector3 open; 6 | public Vector3 closed; 7 | public float openingTime; 8 | public bool isOpen; 9 | public bool isOpening; 10 | 11 | private void Start() { 12 | closed = transform.position; 13 | } 14 | 15 | public void Open() { 16 | StartCoroutine(OpenClose(true)); 17 | StartCoroutine(OpenClose(false, initialDelay: openingTime * 6.0f)); ; 18 | } 19 | 20 | IEnumerator OpenClose(bool opening, float initialDelay = 0.0f) { 21 | yield return new WaitForSeconds(initialDelay); 22 | if (isOpening) yield break; 23 | isOpening = true; 24 | var target = opening ? open : closed; 25 | var origin = transform.position; 26 | float elapsed = 0.0f; 27 | while (elapsed < openingTime) { 28 | transform.position = Vector3.Lerp(origin, target, (elapsed / openingTime)); 29 | elapsed += Time.deltaTime; 30 | yield return null; 31 | } 32 | isOpen = !isOpen; 33 | isOpening = false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Editor/ConfigurationEditor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | [CustomEditor(typeof(Blockfrost.Configuration))] 8 | public class ConfigurationEditor : Editor { 9 | public override void OnInspectorGUI() { 10 | base.OnInspectorGUI(); 11 | 12 | var conf = target as Blockfrost.Configuration; 13 | var _apis = conf.servers.Select(s => s.Key).ToArray().ToArray(); 14 | GUILayout.Label("Current API"); 15 | int selectedApi = EditorGUILayout.Popup(Array.IndexOf(_apis, conf.CurrentApi), _apis); 16 | conf.ChangeApi(_apis[selectedApi]); 17 | 18 | var _servers = conf.servers[conf.CurrentApi].Select(s => s.Network).ToArray(); 19 | 20 | GUILayout.Label("Current Network"); 21 | int _currentNetworkIndex = conf.CurrentNetworkIndex; 22 | int selectedNetwork = EditorGUILayout.Popup(conf.CurrentNetworkIndex, _servers); 23 | conf.ChangeNetwork(selectedNetwork); 24 | 25 | EditorGUI.BeginDisabledGroup(true); 26 | EditorGUILayout.TextField("Url", conf.CurrentServer.Url); 27 | EditorGUILayout.Separator(); 28 | 29 | EditorGUI.EndDisabledGroup(); 30 | 31 | EditorUtility.SetDirty(target); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Examples/Demo/Plugins/nami.jslib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a67aaeb423e2a594ea84c55fb4fcb938 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 1 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Editor: 1 20 | Exclude Linux64: 1 21 | Exclude OSXUniversal: 1 22 | Exclude WebGL: 0 23 | Exclude Win: 1 24 | Exclude Win64: 1 25 | - first: 26 | Any: 27 | second: 28 | enabled: 0 29 | settings: {} 30 | - first: 31 | Editor: Editor 32 | second: 33 | enabled: 0 34 | settings: 35 | CPU: AnyCPU 36 | DefaultValueInitialized: true 37 | OS: AnyOS 38 | - first: 39 | Standalone: Linux64 40 | second: 41 | enabled: 0 42 | settings: 43 | CPU: None 44 | - first: 45 | Standalone: OSXUniversal 46 | second: 47 | enabled: 0 48 | settings: 49 | CPU: None 50 | - first: 51 | Standalone: Win 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: x86 56 | - first: 57 | Standalone: Win64 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: x86_64 62 | - first: 63 | WebGL: WebGL 64 | second: 65 | enabled: 1 66 | settings: {} 67 | userData: 68 | assetBundleName: 69 | assetBundleVariant: 70 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Filters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Blockfrost { 5 | public class Listing { 6 | /// 7 | /// The number of items per page. 8 | /// 9 | public int? count { get; set; } 10 | /// 11 | /// The page number for listing the results. 12 | /// 13 | public int? page { get; set; } 14 | 15 | public Dictionary AsDict() { 16 | return this.GetType().GetProperties() 17 | .Where(property => property.GetValue(this) != null) 18 | .ToDictionary(property => property.Name, property => property.GetValue(this).ToString()); 19 | } 20 | } 21 | 22 | public class OrderedListing : Listing { 23 | /// 24 | /// Ascending/Descending 25 | /// 26 | public enum Order { asc, desc } 27 | /// 28 | /// The ordering of items from the point of view of the blockchain, 29 | /// not the page listing itself. By default, we return oldest first, 30 | /// newest last. 31 | /// 32 | public Order? order { get; set; } 33 | } 34 | 35 | public class TargetableOrderedListing : OrderedListing { 36 | /// 37 | /// The block number and optionally also index from which (inclusive) to 38 | /// start search for results, concatenated using colon. 39 | /// Has to be lower than or equal to `to` parameter. 40 | /// 41 | /// 8929261 42 | public string from { get; set; } = null; 43 | /// 44 | /// The block number and optionally also index where (inclusive) to end 45 | /// the search for results, concatenated using colon. 46 | /// Has to be higher than or equal to `from` parameter. 47 | /// 48 | /// 9999269:10 49 | public string to { get; set; } = null; 50 | } 51 | } -------------------------------------------------------------------------------- /src/Generator/Editor/Models.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | using UnityEngine; 7 | 8 | namespace BlockfrostGen { 9 | 10 | class ResponseModel { 11 | public string ID; 12 | public List Properties; 13 | 14 | public string Serialize() { 15 | var sb = new StringBuilder(); 16 | sb.AppendLine(Header()); 17 | foreach (var property in Properties.Where(prop => prop.IsValid()).ToArray()) { 18 | sb.AppendLine(property.Serialize()); 19 | } 20 | sb.AppendLine("}"); 21 | 22 | return sb.ToString(); 23 | } 24 | 25 | public string Header() { 26 | return $"[Serializable]\npublic class {ID} {{"; 27 | } 28 | 29 | 30 | } 31 | 32 | class ResponseProperty { 33 | public string Type; 34 | public bool IsArray; 35 | public string Key; 36 | 37 | public string Description; 38 | 39 | public bool IsValid() { 40 | return Type != null && Key != null; 41 | } 42 | 43 | public string Serialize() { 44 | var sb = new StringBuilder(); 45 | Comment(sb); 46 | Definition(sb); 47 | 48 | return sb.ToString(); 49 | } 50 | 51 | private void Comment(StringBuilder sb) { 52 | if (Description == null) { 53 | return; 54 | } 55 | sb.AppendLine("/// "); 56 | var reader = new StringReader(Description); 57 | for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) { 58 | sb.AppendLine($"/// {line}"); 59 | } 60 | sb.AppendLine("/// "); 61 | } 62 | 63 | private void Definition(StringBuilder sb) { 64 | if (Key.Contains('_')) { 65 | sb.AppendLine($"public {TypeDefinition} {Name()} {{ get => {Key}; }}"); 66 | } 67 | sb.AppendLine($"public {TypeDefinition} {Key};"); 68 | } 69 | 70 | private string TypeDefinition { get => IsArray ? $"{Type}[]" : Type; } 71 | 72 | private string Name() { 73 | return BlockfrostGenerator.Camelize(Key, lowerCase: true); 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Door.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Door 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.509434, g: 0.2784423, b: 0.08891065, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Wall.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Wall 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.8679245, g: 0.75919694, b: 0.749199, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Foliage.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Foliage 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.13510145, g: 0.41509432, b: 0.1451083, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/Ground.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Ground 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.23829654, g: 0.5943396, b: 0.28593615, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /src/Examples/Demo/Materials/BetterFoliage.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: BetterFoliage 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.7529412, g: 0.1960784, b: 0.6619351, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /src/Examples/Demo/qr_transparent.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 52bdb1b7920b45f4ba0f77edec5262ec 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 1 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 1 41 | nPOTScale: 0 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 1 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 1 54 | spriteTessellationDetail: -1 55 | textureType: 8 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 5e97eb03825dee720800000000000000 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/ReflectionProbe-0.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b57482204e6c4e3428eac50b172d4a10 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 1 30 | seamlessCubemap: 1 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 2 36 | aniso: 0 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 1 41 | nPOTScale: 1 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 0 54 | spriteTessellationDetail: -1 55 | textureType: 0 56 | textureShape: 2 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 1 72 | compressionQuality: 100 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 5e97eb03825dee720800000000000000 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-0_comp_dir.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 243706278e9b0084a8d6171c93c2d47c 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 1 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 3 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 1 41 | nPOTScale: 1 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 0 54 | spriteTessellationDetail: -1 55 | textureType: 12 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 2 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 5e97eb03825dee720800000000000000 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-0_comp_light.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0a05230a7642ea49a72527996742af4 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 1 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 3 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 1 41 | nPOTScale: 1 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 0 53 | alphaIsTransparency: 0 54 | spriteTessellationDetail: -1 55 | textureType: 6 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 2 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 5e97eb03825dee720800000000000000 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-1_comp_dir.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a216541db881ada46ad19a2b3c3ef08c 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 1 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 3 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 1 41 | nPOTScale: 1 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 1 53 | alphaIsTransparency: 0 54 | spriteTessellationDetail: -1 55 | textureType: 12 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 2 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 5e97eb03825dee720800000000000000 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/Lightmap-1_comp_light.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 23871df7daba81b41b9cb879a5b8025d 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 1 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | grayScaleToAlpha: 0 28 | generateCubemap: 6 29 | cubemapConvolution: 0 30 | seamlessCubemap: 0 31 | textureFormat: 1 32 | maxTextureSize: 2048 33 | textureSettings: 34 | serializedVersion: 2 35 | filterMode: 1 36 | aniso: 3 37 | mipBias: 0 38 | wrapU: 1 39 | wrapV: 1 40 | wrapW: 1 41 | nPOTScale: 1 42 | lightmap: 0 43 | compressionQuality: 50 44 | spriteMode: 0 45 | spriteExtrude: 1 46 | spriteMeshType: 1 47 | alignment: 0 48 | spritePivot: {x: 0.5, y: 0.5} 49 | spritePixelsToUnits: 100 50 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 51 | spriteGenerateFallbackPhysicsShape: 1 52 | alphaUsage: 0 53 | alphaIsTransparency: 0 54 | spriteTessellationDetail: -1 55 | textureType: 6 56 | textureShape: 1 57 | singleChannelComponent: 0 58 | flipbookRows: 1 59 | flipbookColumns: 1 60 | maxTextureSizeSet: 0 61 | compressionQualitySet: 0 62 | textureFormatSet: 0 63 | ignorePngGamma: 0 64 | applyGammaDecoding: 0 65 | platformSettings: 66 | - serializedVersion: 3 67 | buildTarget: DefaultTexturePlatform 68 | maxTextureSize: 2048 69 | resizeAlgorithm: 0 70 | textureFormat: -1 71 | textureCompression: 2 72 | compressionQuality: 50 73 | crunchedCompression: 0 74 | allowsAlphaSplitting: 0 75 | overridden: 0 76 | androidETC2FallbackOverride: 0 77 | forceMaximumCompressionQuality_BC6H_BC7: 0 78 | spriteSheet: 79 | serializedVersion: 2 80 | sprites: [] 81 | outline: [] 82 | physicsShape: [] 83 | bones: [] 84 | spriteID: 5e97eb03825dee720800000000000000 85 | internalID: 0 86 | vertices: [] 87 | indices: 88 | edges: [] 89 | weights: [] 90 | secondaryTextures: [] 91 | spritePackingTag: 92 | pSDRemoveMatte: 0 93 | pSDShowRemoveMatteOption: 0 94 | userData: 95 | assetBundleName: 96 | assetBundleVariant: 97 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/PlayerController.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class PlayerController : MonoBehaviour { 4 | 5 | public Demo demo; 6 | CharacterController controller; 7 | public Camera cam; 8 | public float walkspeed; 9 | public float lookSpeed; 10 | public float jumpSpeed; 11 | public float gravity; 12 | 13 | float rotationX = 0; 14 | Vector3 moveDir; 15 | 16 | Vector3 startPosition; 17 | 18 | private void Start() { 19 | controller = GetComponent(); 20 | demo = FindObjectOfType(); 21 | startPosition = transform.position; 22 | 23 | Cursor.lockState = CursorLockMode.Locked; 24 | Cursor.visible = false; 25 | } 26 | 27 | private void Update() { 28 | if (!controller.enabled) controller.enabled = true; 29 | // move 30 | Vector3 forward = transform.TransformDirection(Vector3.forward); 31 | Vector3 right = transform.TransformDirection(Vector3.right); 32 | float curSpeedX = walkspeed * Input.GetAxis("Vertical"); 33 | float curSpeedY = walkspeed * Input.GetAxis("Horizontal"); 34 | float prevVertical = moveDir.y; 35 | moveDir = (forward * curSpeedX) + (right * curSpeedY); 36 | if (controller.isGrounded) { 37 | moveDir.y = Input.GetButton("Jump") ? jumpSpeed : 0.0f; 38 | } else { 39 | // up & down 40 | moveDir.y = prevVertical; 41 | } 42 | if (!controller.isGrounded) { 43 | moveDir.y -= gravity * Time.deltaTime; 44 | } 45 | 46 | controller.Move(moveDir * Time.deltaTime); 47 | 48 | // rotate 49 | transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0); 50 | 51 | // look 52 | rotationX += -Input.GetAxis("Mouse Y") * lookSpeed; 53 | rotationX = Mathf.Clamp(rotationX, -45f, 45f); 54 | cam.transform.localRotation = Quaternion.Euler(rotationX, 0, 0); 55 | } 56 | 57 | private void Respawn() { 58 | controller.enabled = false; 59 | Debug.Log($"Moving from {transform.position} to {startPosition}"); 60 | transform.position = startPosition; 61 | cam.transform.localRotation = Quaternion.identity; 62 | } 63 | private void OpenDoor() { 64 | demo.UnlockDoor(); 65 | } 66 | 67 | private void OnTriggerEnter(Collider other) { 68 | if (other.CompareTag("Respawn")) { 69 | Respawn(); 70 | } 71 | 72 | if (other.CompareTag("Finish")) { 73 | OpenDoor(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Configuration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace Blockfrost { 7 | 8 | [Serializable] 9 | public class Server { 10 | public string Network; 11 | public string Url; 12 | public string User; 13 | 14 | public string FullUrl() { 15 | return $"https://{Url}"; 16 | } 17 | 18 | public string FullUrl(string projectId) { 19 | return $"https://{User}:{projectId}@{Url}"; 20 | } 21 | } 22 | 23 | [CreateAssetMenu(menuName = "Blockfrost.io API/Configuration", fileName = "BlockfrostAPIConfiguration")] 24 | public class Configuration : ScriptableObject { 25 | [Tooltip("Authentication token (project_id)")] 26 | [SerializeField] 27 | public string ProjectId; 28 | 29 | public const string CardanoApi = "Cardano"; 30 | public const string MilkomedaApi = "Milkomeda"; 31 | 32 | [Tooltip("Client request timeout (0 = no timeout)")] 33 | [SerializeField] 34 | public int RequestTimeout; 35 | [Tooltip("Enable detailed debug logging")] 36 | [SerializeField] 37 | public bool DebugLogging; 38 | 39 | [SerializeField] 40 | [HideInInspector] 41 | private string _currentApi = CardanoApi; 42 | 43 | public string CurrentApi { get => _currentApi; protected set => _currentApi = value; } 44 | 45 | private int _currentNetworkIndex; 46 | public int CurrentNetworkIndex { get => _currentNetworkIndex; protected set => _currentNetworkIndex = value; } 47 | 48 | public Server CurrentServer { get => servers[CurrentApi][CurrentNetworkIndex]; } 49 | 50 | [SerializeField] 51 | [HideInInspector] 52 | public Dictionary> servers = new Dictionary> {{ 53 | CardanoApi, new List{ 54 | new Server{ 55 | Network = "Mainnet", 56 | Url = "cardano-mainnet.blockfrost.io/api/v0", 57 | }, 58 | new Server{ 59 | Network = "Testnet", 60 | Url = "cardano-testnet.blockfrost.io/api/v0", 61 | }, 62 | }}, { 63 | MilkomedaApi, new List{ 64 | new Server{ 65 | Network = "Mainnet", 66 | Url = "milkomeda-mainnet.blockfrost.io/api/v0/", 67 | User = "milkmainnet", 68 | }, 69 | new Server{ 70 | Network = "Testnet", 71 | Url = "milkomeda-testnet.blockfrost.io/api/v0/", 72 | User = "milktestnet", 73 | }, 74 | }}, 75 | }; 76 | 77 | public void ChangeApi(string api) { 78 | if (!servers.ContainsKey(api)) throw new KeyNotFoundException($"invalid API {api}"); 79 | CurrentApi = api; 80 | } 81 | 82 | public void ChangeNetwork(int index) { 83 | if (index >= servers.Count) { 84 | Debug.LogError($"Invalid network index {index}"); 85 | return; 86 | } 87 | CurrentNetworkIndex = index; 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | # Cardano games assets for Unity 7 | 8 | This repository contains the code and configuration files of Cardano game assets for Unity. 9 | 10 | It is a lighthweight Unity-specific client for interacting with blockfrost.io API. It's built on [UniTask](https://github.com/Cysharp/UniTask) for allocation-free async operations and uses Unity's native HTTP client (`UnityWebRequest`) and JSON parser (`JsonUtility`). 11 | 12 |

13 | Installation • 14 | Cardano • 15 | Milkomeda • 16 | Demo 17 |

18 |

19 | 20 | ## Installation 21 | 22 | ### Unity Asset Store 23 | 24 | We're going to publish this package to the Asset Story in the near future. 25 | 26 | ### Package Manager 27 | 28 | Client can be installed using Unity Package Manager using git. 29 | 30 | * Go to Package Manager, select *Add package from git URL...* 31 | * Enter `https://github.com/fivebinaries/cardano-unity.git?path=src/Blockfrost.io` 32 | 33 | NOTE: Dependancy has to be installed manually if they are missing, see [Installing UniTask](https://github.com/Cysharp/UniTask#install-via-git-url). 34 | 35 | ### Manual installation 36 | 37 | You can copy [Blockfrost.io](src/Blockfrost.io) folder into your project. Installing dependancy is required. 38 | 39 | ## Cardano API 40 | 41 | ### Getting started 42 | 43 | 1. Get your own `PROJECT_ID` from [blockfrost.io](https://blockfrost.dev/docs/overview/getting-started#creating-first-project) 44 | 2. Create configuration _Create_ → _Blockfrost.io API_ → _Configuration_ and fill in the `PROJECT_ID` 45 | 3. In your MonoBehaviour create new instance of _Blockfrost.Cardano_ by passing in reference to your configuration 46 | 4. You can now call the API and access the Cardano blockchain 47 | 48 | ### Example 49 | 50 | ```csharp 51 | var config = new Blockfrost.Configuration{ 52 | ProjectID = myProjectID; 53 | }; 54 | 55 | var client = Blockfrost.Cardano(config); 56 | var latestBlock = await client.GetLatestBlock(); 57 | 58 | Debug.Log(response.hash); 59 | ``` 60 | 61 | ### Listing 62 | 63 | Some endpoints allow certain listing operations (number of items in a list, order, .etc). There are three filters available 64 | `Blockfrost.Listing`, `Blockfrost.OrderedListing`, and `Blockfrost.TargetableOrderedListing` that can be passed to specific methods. 65 | 66 | ```csharp 67 | api.GetBlockTransactions(hash, new Listing{count = 10}) 68 | ``` 69 | 70 | ### Errors 71 | 72 | Handle original errors from `UnityWebRequest`. 73 | 74 | ## Milkomeda API 75 | 76 | To use [Milkomeda API](https://blockfrost.dev/docs/start-building/milkomeda#supported-json-rpc-api-calls) follow steps in Cardano section, but select Milkomeda in your Blockfrost API configuration. The client currently only supports raw json messages on both input and output. 77 | 78 | ```csharp 79 | var client = Blockfrost.Milkomeda(); 80 | 81 | var data = @"{""jsonrpc"": ""2.0"", ""method"": ""net_version"", ""params"": [], ""id"": 1}"; 82 | var response = await client.RPC(data); 83 | 84 | Debug.Log(response); 85 | ``` 86 | 87 | ## Demo 88 | 89 | Demo using [Nami wallet](https://namiwallet.io/) can be found [here](https://fivebinaries.github.io/cardano-unity/src/Examples/Demo/) and its sources [here](src/Examples). In this simple game, the door won't open until your wallet contains a specific NFT. 90 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/CardanoBech32Wrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace CardanoBech32 6 | { 7 | public class CardanoBech32Wrapper : ICardanoBech32Wrapper 8 | { 9 | public string ConvertToHexAddressFromBech32(string inBech32) 10 | { 11 | if (inBech32 == null) return null; 12 | 13 | inBech32 = inBech32.Trim(); 14 | 15 | string hrp; 16 | byte[] data; 17 | Bech32Engine.Decode(inBech32, out hrp, out data); 18 | 19 | if (data == null) return string.Empty; 20 | return BitConverter.ToString(data).Replace("-", string.Empty).ToLower(); 21 | } 22 | 23 | public string ConvertToBech32AddressFromHex(string inHex, AddressType addressType) 24 | { 25 | if (inHex == null) return null; 26 | 27 | inHex = inHex.Trim(); 28 | 29 | var asByte = Helper.ConvertHexStringToByte(inHex); 30 | 31 | var bech32Address = Bech32Engine.Encode(addressType.ToString(), asByte); 32 | 33 | return bech32Address; 34 | } 35 | 36 | /// 37 | /// 38 | /// 39 | /// Must be in Hex 40 | /// Can be in Hex Or UTF8 41 | /// 42 | public string GenerateAssetNameFingerprint(string policyId, string assetname) 43 | { 44 | throw new NotImplementedException(); 45 | } 46 | 47 | public string GetStakeAddressFromAddress(string address) 48 | { 49 | var addressInHex = ConvertToHexAddressFromBech32(address); 50 | if (addressInHex == null) return null; 51 | 52 | int stakeAddressLength = 56; 53 | var stakeAddressInHex = "e1"+ addressInHex.Substring(addressInHex.Length - stakeAddressLength, stakeAddressLength); 54 | 55 | if (address.StartsWith(AddressType.addr.ToString())) return ConvertToBech32AddressFromHex(stakeAddressInHex, AddressType.stake); 56 | 57 | if (address.StartsWith(AddressType.addr_test.ToString())) return ConvertToBech32AddressFromHex(stakeAddressInHex, AddressType.stake_test); 58 | 59 | return null; 60 | } 61 | 62 | public bool TryConvertToHexAddressFromBech32(string inBech32, out string valueInHex) 63 | { 64 | if(Helper.IsBech32ToHexConvertible(inBech32)) 65 | { 66 | valueInHex = ConvertToHexAddressFromBech32(inBech32); 67 | return true; 68 | } 69 | valueInHex = null; 70 | return false; 71 | } 72 | 73 | public bool TryConvertToHexAddressFromBech32(string inBech32, out byte[] valueInHex) 74 | { 75 | if (Helper.IsBech32ToHexConvertible(inBech32)) 76 | { 77 | var ret = ConvertToHexAddressFromBech32(inBech32); 78 | valueInHex = Helper.ConvertHexStringToByte(ret); 79 | return true; 80 | } 81 | valueInHex = null; 82 | return false; 83 | } 84 | } 85 | 86 | public enum AddressType 87 | { 88 | /// 89 | /// Mainnet Address 90 | /// 91 | addr, 92 | /// 93 | /// Mainnet Stake Address 94 | /// 95 | stake, 96 | /// 97 | /// Mainnet Pool Address 98 | /// 99 | pool, 100 | //asset, 101 | /// 102 | /// Testnet Address 103 | /// 104 | addr_test, 105 | /// 106 | /// Testnet Stake Address 107 | /// 108 | stake_test, 109 | /// 110 | /// Testnet Stake Address 111 | /// 112 | pool_test, 113 | //asset_test 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/Demo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Runtime.InteropServices; 3 | 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | using Blockfrost; 8 | using CardanoBech32; 9 | 10 | public class Demo : MonoBehaviour { 11 | 12 | [SerializeField] 13 | public Configuration myConfiguration; 14 | 15 | private Cardano client; 16 | private Console console; 17 | private UI ui; 18 | 19 | [DllImport("__Internal")] 20 | private static extern void LoadBaseAddress(); 21 | 22 | [DllImport("__Internal")] 23 | private static extern void ClearBaseAddress(); 24 | 25 | [DllImport("__Internal")] 26 | private static extern string GetBaseAddress(); 27 | 28 | public string Address { get; protected set; } 29 | public string defaultAddress; 30 | 31 | public PlayerController player; 32 | 33 | public float checkWalletDelay; 34 | private float lastCheck = 0.0f; 35 | 36 | readonly string TestCoin = "6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7"; 37 | 38 | public Door door; 39 | 40 | // UI 41 | public Text debug; 42 | public Button connect; 43 | 44 | void Start() { 45 | console = GetComponent(); 46 | ui = GetComponent(); 47 | door = FindObjectOfType(); 48 | 49 | client = new Blockfrost.Cardano(myConfiguration); 50 | 51 | connect.interactable = true; 52 | } 53 | 54 | public void Connect() { 55 | #if UNITY_WEBGL 56 | StartCoroutine(WaitForAddress()); 57 | #else 58 | StartCoroutine(WaitForAddressMock()); 59 | #endif 60 | } 61 | 62 | IEnumerator WaitForAddressMock() { 63 | console.Log("Setting address", "..."); 64 | Address = defaultAddress; 65 | StartGame(); 66 | yield return null; 67 | } 68 | 69 | IEnumerator WaitForAddress() { 70 | connect.interactable = false; 71 | console.Log("Connecting to wallet", "..."); 72 | LoadBaseAddress(); 73 | Address = GetBaseAddress(); 74 | for (int i = 0; i <= 10; i++) { 75 | Address = GetBaseAddress(); 76 | if (Address.Length > 0) break; 77 | console.Log($"Retrying in 1s", "..."); 78 | yield return new WaitForSeconds(1.0f); 79 | } 80 | 81 | if (Address.Length == 0) { 82 | console.Log($"Error:", "too many attempts"); 83 | ui.Error("Could not connect to Nami wallet, check your settings and reload page to try again"); 84 | yield break; 85 | } 86 | 87 | ClearBaseAddress(); 88 | console.Log("Found base hex address", Address); 89 | var converter = new CardanoBech32Wrapper(); 90 | Address = converter.ConvertToBech32AddressFromHex(Address, AddressType.addr_test); 91 | console.Log("Converted to bech32", Address); 92 | StartGame(); 93 | } 94 | 95 | public void StartGame() { 96 | connect.interactable = true; 97 | ui.DisableIntro(); 98 | player.enabled = true; 99 | } 100 | 101 | public async void UnlockDoor() { 102 | if (Time.time < lastCheck + checkWalletDelay) return; 103 | 104 | console.Log("Loading coins", Address); 105 | lastCheck = Time.time; 106 | var ac = await client.GetSpecificAddress(Address); 107 | console.Log("Loaded", $"{ac.amount.Length}"); 108 | 109 | foreach (var amount in ac.amount) { 110 | if (amount.unit == TestCoin) { 111 | console.Log("Found Testcoin", $"({amount.quantity})"); 112 | door.Open(); 113 | } 114 | } 115 | } 116 | 117 | } -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Client.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using System; 4 | 5 | using UnityEngine.Networking; 6 | using UnityEngine; 7 | 8 | using Cysharp.Threading.Tasks; 9 | 10 | namespace Blockfrost { 11 | [System.Serializable] 12 | public class ArrayWrapper { 13 | public T[] Items; 14 | } 15 | 16 | public enum Method { 17 | get 18 | } 19 | 20 | public class Client { 21 | 22 | protected const string authHeaderKey = "project_id"; 23 | 24 | [SerializeField] 25 | public Configuration configuration; 26 | 27 | public Client() : this(new Configuration()) { } 28 | 29 | public Client(Configuration config) { 30 | if (config == null) { 31 | throw new ArgumentNullException("config"); 32 | } 33 | configuration = config; 34 | LogDebug($"Initialized Blockfrost API client ({config.CurrentServer.Network})"); 35 | } 36 | 37 | public async UniTask Call(Method method, string path, Dictionary pathParams, Listing query = null) { 38 | var url = BuildPath(path, pathParams, query); 39 | LogDebug($"Requesting ({method}) {url}"); 40 | var req = UnityWebRequest.Get(url); 41 | req.SetRequestHeader(authHeaderKey, configuration.ProjectId); 42 | 43 | req.timeout = configuration.RequestTimeout; 44 | var op = await req.SendWebRequest(); 45 | var response = op.downloadHandler.text; 46 | 47 | LogDebug($"Received response:\n{response}"); 48 | 49 | return response; 50 | } 51 | 52 | public async UniTask Post(string url, byte[] data) { 53 | var request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST); 54 | request.timeout = configuration.RequestTimeout; 55 | request.uploadHandler = new UploadHandlerRaw(data); 56 | request.uploadHandler.contentType = "application/json"; 57 | request.downloadHandler = new DownloadHandlerBuffer(); 58 | 59 | LogDebug($"Sending {request.uploadHandler.data.Length} bytes"); 60 | await request.SendWebRequest(); 61 | 62 | var response = request.downloadHandler.text; 63 | LogDebug($"Received response:\n{response}"); 64 | 65 | request.uploadHandler.Dispose(); 66 | request.downloadHandler.Dispose(); 67 | 68 | return response; 69 | } 70 | 71 | public async UniTask Get(string path, Dictionary pathParams, Listing query = null) { 72 | var response = await Call(Method.get, path, pathParams, query); 73 | return JsonUtility.FromJson(response); 74 | } 75 | 76 | public async UniTask GetArray(string path, Dictionary pathParams, Listing query = null) { 77 | var response = await Call(Method.get, path, pathParams, query); 78 | // wrap array response into object for the unity parser 79 | response = $"{{\"Items\": {response}}}"; 80 | return JsonUtility.FromJson>(response).Items; 81 | } 82 | 83 | protected string BuildPath(string path, Dictionary paramteres = null, Listing query = null) { 84 | StringBuilder url = new StringBuilder(configuration.CurrentServer.FullUrl()); 85 | url.Append(path); 86 | if (paramteres != null) { 87 | foreach (var p in paramteres) { 88 | url.Replace("{" + p.Key + "}", p.Value as string); 89 | } 90 | } 91 | if (query != null) { 92 | var d = query.AsDict(); 93 | var parsedQuery = UnityWebRequest.SerializeSimpleForm(query.AsDict()); 94 | url.Append($"?{Encoding.UTF8.GetString(parsedQuery)}"); 95 | } 96 | 97 | return url.ToString(); 98 | } 99 | 100 | protected void LogDebug(object message) { 101 | if (!configuration.DebugLogging) return; 102 | Debug.Log(message); 103 | } 104 | 105 | } 106 | } -------------------------------------------------------------------------------- /src/Generator/Editor/Endpoints.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using System.Linq; 4 | using System.IO; 5 | 6 | using UnityEngine; 7 | 8 | 9 | namespace BlockfrostGen { 10 | 11 | class Endpoint { 12 | public static readonly Dictionary SupportedTypes = new Dictionary { 13 | { "array", true }, 14 | { "object", true }, 15 | { "string", true }, 16 | }; 17 | 18 | private const string pathParamsDict = "pathParams"; 19 | 20 | public string Method; // TODO enum 21 | public string Path; 22 | public string Description; 23 | public string Summary; 24 | public List Params; 25 | private List PathParams { get => Params.Where(p => p.In == "Path").ToList(); } 26 | private List QueryParams { get => Params.Where(p => p.In == "Query").ToList(); } 27 | 28 | public string ResponseType; 29 | public bool ReturnsArray; 30 | 31 | private bool IsSupported() { 32 | return Method == "Get" && Summary != null && ResponseType != null; 33 | } 34 | 35 | public string Serialize() { 36 | if (!IsSupported()) { 37 | Debug.Log($"Skipping endpoint {Method} {Path}"); 38 | return null; 39 | } 40 | var sb = new StringBuilder(); 41 | AddDocumentation(sb); 42 | sb.AppendLine($"public async UniTask<{ReturnType}> {Name}({Arguments()}) {{"); 43 | sb.AppendLine($"const string path = \"{Path}\";"); 44 | AddParamsDict(sb, PathParams, pathParamsDict); 45 | sb.AppendLine($"return await {ClientCall()}(path, {pathParamsDict}{queryParam});"); 46 | sb.AppendLine("}"); 47 | return sb.ToString(); 48 | } 49 | 50 | private void AddParamsDict(StringBuilder sb, List parameters, string target) { 51 | sb.Append($"var {target} = new Dictionary()"); 52 | if (parameters.Count == 0) { 53 | sb.AppendLine(";"); 54 | return; 55 | } 56 | sb.AppendLine("{"); 57 | foreach (Param p in parameters) { 58 | sb.AppendLine($"\t\t\t\t{{\"{p.Key}\", {p.Var}}},"); 59 | } 60 | sb.AppendLine("\t\t\t};"); 61 | } 62 | 63 | private string Name { get => $"{Method}{BlockfrostGenerator.Camelize(Summary)}"; } 64 | 65 | private string Arguments() { 66 | var pathParams = PathParams.Select(p => $"{BlockfrostGenerator.BasicTypes[p.Type]} {p.Var}"); 67 | pathParams = pathParams.Append(QueryParam()); 68 | return string.Join(", ", pathParams.Where(s => !string.IsNullOrEmpty(s))); 69 | } 70 | 71 | private static readonly Dictionary> querySets = new Dictionary>() { 72 | {"Listing",new HashSet() { "count", "page" }}, 73 | {"OrderedListing", new HashSet(){ "count", "page", "order" }}, 74 | {"TargetableOrderedListing", new HashSet(){ "count", "page", "order", "from", "to" }}, 75 | }; 76 | 77 | // TODO rewrite this to something sane 78 | private string QueryParam() { 79 | var qp = QueryParams.Select(qp => qp.Key).ToHashSet(); 80 | foreach (var set in querySets) { 81 | if (qp.SetEquals(set.Value)) { 82 | return $"{set.Key} query = null"; 83 | } 84 | } 85 | return null; 86 | } 87 | private string queryParam { get => QueryParam() != null ? ", query": ""; } 88 | 89 | private string ClientCall() { 90 | var method = ReturnsArray ? $"{Method}Array" : Method; 91 | return $"{method}<{ResponseType}>"; 92 | } 93 | 94 | private string ReturnType { get => ReturnsArray ? $"{ResponseType}[]" : ResponseType; } 95 | 96 | private void AddDocumentation(StringBuilder sb) { 97 | if (Description == null) { 98 | return; 99 | } 100 | sb.AppendLine("/// "); 101 | var reader = new StringReader(Description); 102 | for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) { 103 | sb.AppendLine($"/// {line}"); 104 | } 105 | sb.AppendLine("/// "); 106 | sb.AppendLine($"/// {Method.ToUpper()} {Path}"); 107 | foreach (Param pp in PathParams) { 108 | sb.AppendLine($"/// {pp.Description}"); 109 | } 110 | } 111 | } 112 | 113 | class Param { 114 | public string In; 115 | public string Type; 116 | public string Key; 117 | public string Description; 118 | public bool Required; 119 | public string Optional { get => Required ? "" : " (optional)"; } 120 | public string Var { get => BlockfrostGenerator.Camelize(Key, lowerCase: true); } 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Helper/Helper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace CardanoBech32 7 | { 8 | public static class Helper 9 | { 10 | public static byte[] ConvertHexStringToByte(string input) 11 | { 12 | input = input?.Trim(); 13 | if (!IsHex(input) || string.IsNullOrWhiteSpace(input)) return Array.Empty(); 14 | 15 | if (input.Length % 2 == 1) throw new Exception("The binary key cannot have an odd number of digits"); 16 | 17 | byte[] arr = new byte[input.Length >> 1]; 18 | 19 | for (int i = 0; i < input.Length >> 1; ++i) 20 | { 21 | arr[i] = (byte)((GetHexVal(input[i << 1]) << 4) + (GetHexVal(input[(i << 1) + 1]))); 22 | } 23 | 24 | return arr; 25 | 26 | } 27 | public static string ConvertHexStringToUTF8(string input) 28 | { 29 | var asByte = ConvertHexStringToByte(input); 30 | return System.Text.Encoding.UTF8.GetString(asByte); 31 | } 32 | 33 | /// 34 | /// Casts char to int value of encoding page (UTF16) 35 | /// 36 | private static int GetHexVal(char hex) 37 | { 38 | int val = (int)hex; 39 | //For uppercase A-F letters: 40 | //return val - (val < 58 ? 48 : 55); 41 | //For lowercase a-f letters: 42 | //return val - (val < 58 ? 48 : 87); 43 | //Or the two combined, but a bit slower: 44 | return val - (val < 58 ? 48 : (val < 97 ? 55 : 87)); 45 | } 46 | public static string ConvertByteToHexString(byte[] input) 47 | { 48 | if (input == null) return string.Empty; 49 | return BitConverter.ToString(input).Replace("-", string.Empty).ToLower(); 50 | 51 | } 52 | public static bool TryConvertByteToHexString(byte[] input, out string valueInHex) 53 | { 54 | var result = ConvertByteToHexString(input); 55 | if(!string.IsNullOrWhiteSpace(result) && IsHex(result)) 56 | { 57 | valueInHex = result; 58 | return true; 59 | } 60 | 61 | valueInHex = null; 62 | return false; 63 | } 64 | public static bool TryConvertHexStringToByte(string input, out byte[] valueInHex) 65 | { 66 | var result = ConvertHexStringToByte(input); 67 | 68 | if (result != null && result.Length > 0) 69 | { 70 | valueInHex = result; 71 | return true; 72 | } 73 | 74 | valueInHex = null; 75 | return false; 76 | } 77 | 78 | public static string ConvertByteToUTF8String(byte[] input) 79 | { 80 | if (input == null) return string.Empty; 81 | return Encoding.UTF8.GetString(input); 82 | } 83 | public static byte[] ConvertUTF8StringToByte(string input) 84 | { 85 | return Encoding.UTF8.GetBytes(input); 86 | } 87 | 88 | public static string ConvertByteToUTF32String(byte[] input) 89 | { 90 | if (input == null) 91 | return string.Empty; 92 | return Encoding.UTF8.GetString(input); 93 | } 94 | 95 | /// 96 | /// True for 0-9, A-F, a-f 97 | /// 98 | public static bool IsHex(IEnumerable chars) 99 | { 100 | if (chars == null) 101 | return false; 102 | bool doesApply; 103 | foreach (var c in chars) 104 | { 105 | doesApply = ((c >= '0' && c <= '9') || 106 | (c >= 'a' && c <= 'f') || 107 | (c >= 'A' && c <= 'F')); 108 | 109 | if (!doesApply) 110 | return false; 111 | } 112 | return true; 113 | } 114 | 115 | /// 116 | /// True for 0-9, A-Z, a-z 117 | /// 118 | public static bool IsDigitLetter(IEnumerable chars) 119 | { 120 | if (chars == null) 121 | return false; 122 | 123 | bool doesApply; 124 | foreach (var c in chars) 125 | { 126 | doesApply = 127 | ((c >= '0' && c <= '9') || 128 | (c >= 'a' && c <= 'z') || 129 | (c >= 'A' && c <= 'Z')); 130 | 131 | if (!doesApply) 132 | return false; 133 | } 134 | return true; 135 | } 136 | /// 137 | /// True for 0-9, A-Z, a-z, _ and " " 138 | /// 139 | public static bool IsDigitLetterUnderscoreWhitespace(IEnumerable chars) 140 | { 141 | if (chars == null) 142 | return false; 143 | 144 | bool doesApply; 145 | foreach (var c in chars) 146 | { 147 | doesApply = 148 | ((c >= '0' && c <= '9') || 149 | (c >= 'a' && c <= 'z') || 150 | (c >= 'A' && c <= 'Z') || 151 | (c == '_') || 152 | (c == ' ')); 153 | 154 | if (!doesApply) 155 | return false; 156 | } 157 | return true; 158 | } 159 | 160 | public static bool IsBech32ToHexConvertible(string addr) 161 | { 162 | if (string.IsNullOrWhiteSpace(addr)) return false; 163 | 164 | var lowAdr = addr.ToLower(); 165 | var highAdr = addr.ToUpper(); 166 | 167 | // if there's mixed case, that's not OK 168 | if (addr != lowAdr && addr != highAdr) 169 | { 170 | return false; 171 | } 172 | 173 | return addr.IndexOf("1") > -1; 174 | } 175 | 176 | 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/Blockfrost.io/BlockfrostInfo.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 7653c2c134e8c476da620e6b23ecf1df, type: 3} 13 | m_Name: BlockfrostInfo 14 | m_EditorClassIdentifier: 15 | Title: Blockfrost.io ~ API Documentation 16 | Description: "Blockfrost is an API as a service that allows users to interact with 17 | the Cardano blockchain and parts of its ecosystem.\n\n## Tokens\n\nAfter signing 18 | up on https://blockfrost.io, a `project_id` token is automatically generated 19 | for each project.\nHTTP header of your request MUST include this `project_id` 20 | in order to authenticate against Blockfrost servers.\n\n## Available networks\n\nAt 21 | the moment, you can use the following networks. Please, note that each network 22 | has its own `project_id`.\n\n\n \n 23 | \n 24 | \n 25 | \n 26 | \n 27 | \n
NetworkEndpoint
Cardano mainnethttps://cardano-mainnet.blockfrost.io/api/v0
Cardano testnethttps://cardano-testnet.blockfrost.io/api/v0
InterPlanetary File Systemhttps://ipfs.blockfrost.io/api/v0
Milkomeda mainnethttps://milkomeda-mainnet.blockfrost.io/api/v0
Milkomeda testnethttps://milkomeda-testnet.blockfrost.io/api/v0
\n\n## 28 | Milkomeda\n\nFor more information about how to use Milkomeda as well as the list 29 | of available endpoints, see the\nMilkomeda 30 | section on blockfrost.dev.\n\n## Concepts\n\n* All endpoints return either 31 | a JSON object or an array.\n* Data is returned in *ascending* (oldest first, 32 | newest last) order, if not stated otherwise.\n * You might use the `?order=desc` 33 | query parameter to reverse this order.\n* By default, we return 100 results at 34 | a time. You have to use `?page=2` to list through the results.\n* All time and 35 | timestamp related fields (except `server_time`) are in seconds of UNIX time.\n* 36 | All amounts are returned in Lovelaces, where 1 ADA = 1 000 000 Lovelaces.\n* 37 | Addresses, accounts and pool IDs are in Bech32 format.\n* All values are case 38 | sensitive.\n* All hex encoded values are lower case.\n* Examples are not based 39 | on real data. Any resemblance to actual events is purely coincidental.\n* We 40 | allow to upload files up to 100MB of size to IPFS. This might increase in the 41 | future.\n\n## Errors\n\n### HTTP Status codes\n\nThe following are HTTP status 42 | code your application might receive when reaching Blockfrost endpoints and\nit 43 | should handle all of these cases.\n\n* HTTP `400` return code is used when the 44 | request is not valid.\n* HTTP `402` return code is used when the projects exceed 45 | their daily request limit.\n* HTTP `403` return code is used when the request 46 | is not authenticated.\n* HTTP `404` return code is used when the resource doesn't 47 | exist.\n* HTTP `418` return code is used when the user has been auto-banned for 48 | flooding too much after previously receiving error code `402` or `429`.\n* HTTP 49 | `425` return code is used when the user has submitted a transaction when the 50 | mempool is already full, not accepting new txs straight away.\n* HTTP `429` return 51 | code is used when the user has sent too many requests in a given amount of time 52 | and therefore has been rate-limited.\n* HTTP `500` return code is used when our 53 | endpoints are having a problem.\n\n### Error codes\n\nAn internal error code 54 | number is used for better indication of the error in question. It is passed using 55 | the following payload.\n\n```json\n{\n \"status_code\": 403,\n \"error\": \"Forbidden\",\n 56 | \"message\": \"Invalid project token.\"\n}\n```\n## Limits\n\nThere are two types 57 | of limits we are enforcing:\n\nThe first depends on your plan and is the number 58 | of request we allow per day. We defined the day from midnight to midnight of 59 | UTC time.\n\nThe second is rate limiting. We limit an end user, distinguished 60 | by IP address, to 10 requests per second. On top of that, we allow\neach user 61 | to send burst of 500 requests, which cools off at rate of 10 requests per second. 62 | In essence, a user is allowed to make another\nwhole burst after (currently) 63 | 500/10 = 50 seconds. E.g. if a user attemtps to make a call 3 seconds after whole 64 | burst, 30 requests will be processed.\nWe believe this should be sufficient for 65 | most of the use cases. If it is not and you have a specific use case, please 66 | get in touch with us, and\nwe will make sure to take it into account as much 67 | as we can.\n\n## SDKs\n\nWe support a number of SDKs that will help you in developing 68 | your application on top of Blockfrost.\n\n\n \n 69 | \n 70 | \n 71 | \n 72 | \n 73 | \n 74 | \n 75 | \n 76 | \n 77 | \n 78 | \n 79 | \n 80 | \n 81 | \n
Programming languageSDK
JavaScriptblockfrost-js
Haskellblockfrost-haskell
Pythonblockfrost-python
Rustblockfrost-rust
Golangblockfrost-go
Rubyblockfrost-ruby
Javablockfrost-java
Scalablockfrost-scala
Swiftblockfrost-swift
Kotlinblockfrost-kotlin
Elixirblockfrost-elixir
.NETblockfrost-dotnet
Arduinoblockfrost-arduino
\n" 82 | Version: 0.1.39 83 | TermsOfService: https://blockfrost.io/terms 84 | Contact: 85 | Name: Blockfrost Team 86 | Url: https://blockfrost.io/ 87 | Email: contact@blockfrost.io 88 | License: 89 | Name: MIT 90 | Url: https://opensource.org/licenses/MIT 91 | -------------------------------------------------------------------------------- /src/Examples/Demo/Scenes/SampleScene/OcclusionCullingData.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!363 &36300000 4 | OcclusionCullingData: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: OcclusionCullingData 10 | m_PVSData: 120000d629057e32101300000000a04100000000000020c20000a0c1000020c2000020420000a04100002042200000005001000000000000010000006001000002000000f001000000000000000000002002000021000000a0010000020000000000000000000000000000000000000000000000000000000000000003000000b00100000000000090010000010000000100000001000000700100008001000030020000000000000000000000000000000000000000000000000000542032302e3020534f20352e3020534820302e323530204246203130302046203020435320302e30202d20332e332e3232204620302030204f4720300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000ffff7f7f00000000000000000000000001000000000000000000000000000000f52f4b40000000000000000000000000000000001700000000000000000000000e000000000000000000000000000000000000000000000000000000ffff0000ffffffff0000000000000000ff79ff2000dfff2000df007e0000000000000000ff81ff760089ffb600c90092000000000000f0c1000080bf0000f0c10000f041000000000000f041000040c0000000000000884100004040000040400000b8410100000000000000000000000000000040020000000000000000000000000000000020c20000a0c1000020c2000020420000a04100002042a63d0000f00e0000101000001f000000900f000001d010000000a03e170003005000000090030000000000000000000000000000000000000000000009000000000000000100000000000000000000000000000000c0000000200080090000000a00000000000000000000000000000000000000000000000040ff1f00e00060130000000800000000000000010000000000000000000000ff5f00000040ff1f004000801b0000000000000000000000020000000100000000000000ff79ff2000dfff2000df007e1b0000000700000000000000010000000000000000000000ff7f0000004000000040ffff220000000b000000000000000100000000000000000000000000ff3f00c0ff1f00e000782d0000000a00000000000000010000000000000000000000ff7fff3fffff00000040ffff370000000800000000000000010000000000000000000000ff5f00000030ff3f008000803f0000000600000000000000010000000000000000000000ff5fff2f0040ff3f00c00078450000000b00000000000000020000000000000000000000ff7f00000080ff3f00c0ffff5000000009000000000000000100000000000000000000000000ffbfffff000000400080590000000b00000000000000020000000000000000000000ff7fff7fffffff3f00c0ffff6400000008000000000000000100000000000000000000000000ffbfffffff3f008000806c0000000800000000000000010000000000000000000000ff5f00000030ff7f00c00080740000000000000000000000020000000200000000000000ff81ff760089ffb600c90092740000000800000000000000010000000000000000000000ff5f00000040ffbf00e000807c00000009000000000000000100000000000000000000000000000000c0ffdfffff0080850000000800000000000000010000000000000000000000ff7f00000040ffbfffffffff8d0000000900000000000000020000000000000000000000ff7fff3f00c0ffbfffff00c0960000000800000000000000000000000000000000000000ffbfff3fffffffbfffffffff9e00000008000000000000000100000000000000000000000000ffbfffffff7f00c00080a600000009000000000000000100000000000000000000000000ffbfffffffbfffff0080af0000000700000000000000010000000000000000000000ff7fffbfffffffbfffff00c000000000000000a0ff1f0100ff3f0000ff5f0000000000a0ff1f0200ff3f0000ff7fff5f00000060ff7f0400ff1f0000ff3f0000000000a0ff1f0500ffbfff3fff77000000000060ff7f0600ff1e0000ffbfff3f00000020ffbf0a00ff7f0000ff1f0000ffffff9300000000ffbf0000ff7f0000ffffff1300000000ff7f0000ff1f0000ffffff5300000000ff1f0000ffbf000000000080ff1f0000ff3f0000ff5f000000000060ff5f0200ff3fff1fff3f000000000020ff3f0500ff5f0000ffdfff1f00000060ff5f0700ff7fff3fff2f000000000060ff5f0800ffbfff3fff3fff2f00000060ff5f0d00ffbfff7fff2f0000000000a0ffdf1000ff3f0000ff5f000000000060ff5f0f00ffdfffbfff3f0000ffffff1300000000ff5f0000ffdfff1fffffff5300000000ffdfff1fff3f000000000040ff5f0100ff3fff1fff3f000000000080ff1f0000ff3f0000ff7fff5f00000060ff7f0400ff3fff1fff1e000000000020ff3f0500ff77ff5fff3fff1f000000a0ff3f0700ff1f0000ff7fff5f000000a0ff3f0700ff2fff1fff77ff5f000000a0ff3f0800ff3fff2fff77ff5fffffff1300000000ff7fff5fff3fff1f00000040ff7f0000ff1f0000ff3f000000000040ff7f0200ff3fff1fff1e000000000020ff3f0600ffffff7fff3f0000000000a0ff3f0900ff3f0000ffffff7fffffff9300000000ff3f0000ffffff7fffffff1300000000ffffff7fff3f0000ffffff73ffff0000ff3f0000ff3f000000000080ff1f0000ffbfff3fff77000000000000ff3f0100ff5f0000ffdfff1f00000000ff3f0200ff77ff5fff3fff1f00000000ff3f0800ff77ff5fffbfff3f00000020ffbf0a00ff770000ff3fff1f00000020ffbf0c00ff770000ff7fff3f000000a0ffdf1000ffbfff3fff77000000000000ff3f0f00ff77ff5fffdfffbf00000020ffbf1400ff770000ffbfff7f00000020ffbf1500ff770000ffdfffbfffffff5300000000ffdfff1fffbfff3f00000040ff7f0000ff1e0000ffbfff3f00000000ff3f0400ffffff7fff3f0000000000a0ff3f0900ff7fff3fffffff8100000040ff7f0a00ff1e0000ffdfffbf00000040ff7f0a00ff3f0000ffffffdf000000a0ff3f0b00ffdfff7fffffff81000000a0ff3f0b00ffffffdfffffff7fffffff9300000000ffffff3fffffff7fffffff33ffff0000ffffff7fff3f0000ffffff73ffff0000ff3f0000ffffff3f00000040ff5f0100ff7fff3fff2f000000000020ff2f0800ff77ff5fff7fff3f00000060ff7f0900ff7fff3fff1e000000000080ff3f0200ff1f0000ff7fff5f00000080ff3f0200ff2fff1fff77ff5f000000a0ff7f0d00ff1f0000ff7fff5f000000a0ff7f0d00ff2fff1fff77ff5fffffff1300000000ff7fff5fff7fff3f00000000ff2f0700ff77ff5fff7fff3f00000040ff5f0100ffbfff3fff3fff2f00000020ff3f0500ff77ff5fffbfff3f00000080ff3f0200ff3fff2fff77ff5f00000000ff2f0d00ff77ff5fffbfff7f000000a0ffbf0f00ff3fff2fff77ff5f00000040ff7f0700ff7fff3fff1e000000000080ff3f0400ff3f0000ffffff7f00000080ff3f0600ff7fff3fffffff8100000020ff7f0b00ffffff81ffbfff3f00000040ff7f0d00ffbfff7fff1e0000000000a0ffbf1100ff3f0000ffffff7f000000a0ffbf1200ff75ff3fff8fff81000000a0ffbf1200ff7fff3fffbfff8f000000a0ffbf1300ff7fff3fffffffbfffffff1300000000ffffff7fffbfff3fffffff73ffff0000ffbfff3fff7f000000000060ff7f0600ff1e0000ffdfffbf00000060ff7f0600ff3f0000ffffffdf00000000ffbf0000ff7f0000ff1f000000000000ffbf0500ff770000ff3fff1f000000a0ff3f0c00ffdfffbfff770000000000a0ff3f0c00ffffffdfff7f0000ffffff9300000000ffffffbfff7f0000ffffff33ffff0000ff7f0000ff3f0000ffffff5300000000ff3f0000ffffffbf00000040ff7f0c00ff7fff3fffffffe000000080ff3f0600ffdfff7fffffff8100000080ff3f0600ffffffdfffffff7f00000000ff7f0900ffffff81ffbfff3f00000040ff7f1400ffbfff7fffffffe0000000a0ffbf1200ffbfff89ff8fff81000000a0ffbf1200ffbfff7fffbfff8f000000a0ffbf1300ffffff7fffffffbf000000a0ffbf1600ffffffbfffbfff7fffffff33ffff0000ffffff7fffbfff3fffffff73ffff0000ffbfff3fffffff7f00000060ff7f0b00ff7fff3fffffffe000000000ffbf0500ff770000ff7fff3f00000080ff3f0a00ffdfffbfff77000000000080ff3f0a00ffffffdfff7f0000000000a0ff7f1400ffdfffbfff770000000000a0ff7f1400ffffffdfff7f0000ffffff33ffff0000ff7f0000ff7fff3fffffff5300000000ff7fff3fffffffbf00000040ff5f0100ffbfff7fff2f000000000020ff2f0800ff77ff5fffbfff7f00000060ff7f0900ffbfff7fff1e0000000000a0ffbf0f00ff1f0000ff7fff5f000000a0ffbf0f00ff2fff1fff77ff5f00000080ff7f0700ff1f0000ff7fff5f00000080ff7f0700ff2fff1fff77ff5fffffff1300000000ff7fff5fffbfff7f00000040ff5f0100ffdfffbfff3f0000000000a0ffdf1000ff3f0000ff7fff5f00000060ff7f1100ffdfffbfff1e000000000020ff3f0500ff77ff5fffdfffbf00000080ffbf0d00ff1f0000ff7fff5f00000080ffbf0d00ff2fff1fff77ff5f00000080ffbf0800ff3fff2fff77ff5fffffff1300000000ff7fff5fffdfffbf00000080ffdf0100ff3f0000ff5f000000000080ffdf0f00ff3f0000ff7fff5f00000060ff7f1100ffffffdfff3f000000000080ffdf0500ffbfff3fff77000000000060ff7f1200ffffffe0ffbfff3f00000020ffbf1500ff7f0000ffffffdfffffff1300000000ff7f0000ffffffdfffffffb3ffff0000ffbf0000ff7f0000ffffff5300000000ffffffdfffbf000000000040ff7f0f00ffdfffbfff1e000000000040ff7f1000ffffffdfff3f000000000020ff3f1200ffbfff7fffffffbf00000020ff3f1300ffffffbfffffffbf00000080ffbf0900ff3f0000ffffff7fffffff1300000000ffffff7fffffffbfffffffb3ffff0000ff3f0000ffffff7fffffff73ffff0000ffffffbfff3f000000000060ffbf1300ffffffbfffbfff3f00000040ff7f1000ffffffe0ffbfff3f00000000ff3f1100ffbfff7fffffffbf00000080ffbf0900ff75ff3fff8fff8100000080ffbf0900ff7fff3fffbfff8f00000020ffbf1600ffbfff7fffffffbf00000080ffbf0b00ffbfff89ff8fff8100000080ffbf0b00ffbfff7fffbfff8fffffffb3ffff0000ffbfff3fffbfff7f00000040ffbf1200ffffffbfffbfff3f00000000ff3f1100ffffffbfffffffbf00000080ffbf0900ff7fff3fffffffbf00000040ffbf1600ffffffbfffffffbf00000080ffbf0b00ffffff7fffffffbfffffffb3ffff0000ffffff3fffffffbfffffff33ffff0000ffffffbfffffffbfffffff73ffff0000ffffffbfffffff3f00000060ff7f0b00ffbfff7fffffffe000000000ffbf0500ff770000ffbfff7f000000a0ffbf1500ffdfffbfff770000000000a0ffbf1500ffffffdfff7f000000000080ff7f0c00ffdfffbfff77000000000080ff7f0c00ffffffdfff7f0000ffffff33ffff0000ff7f0000ffbfff7fffffff5300000000ffbfff7fffffffbf00000060ff7f1600ffffffe0ffdfffbf00000060ff7f1600ffffffbfffffffdf00000000ffbf0500ff770000ffdfffbf00000000ffbf1000ff7f0000ffffffdf00000080ffbf1400ffdfffbfff77000000000080ffbf1400ffffffdfff7f0000ffffffb3ffff0000ffffffbfff7f0000ffffff33ffff0000ff7f0000ffffffbfffffff5300000000ffffffbfffffffbf00000060ffbf1300ffffffbfffffffbf00000040ff7f1500ffffffe0ffdfffbf00000040ff7f1500ffffffbfffffffdf00000000ffbf1200ffbfff7fffffffbf00000080ffbf0b00ffffffbfffbfff7fffffffb3ffff0000ffffffbfffbfff7fffffff33ffff0000ffbfff7fffffffbf822a0040555555957bb77b77a75bb6d9ddddddcddd75fbddb4f7dfcddd5ccff11d1ff7f1cccd5ddfcdeddc9edf79dfd5dffdd5df5dffddf5dddffdfd1ddf33fff3fdffffefaffb5b5a1e511f51133333d1f030210f0d210b737008efe3dffffd3ebecb7ffff7bbcc1e336fcf3933b7fffdfff7ffdfff7f3333ffff038c000000102028343c444b535b636c747a8186020916212d3943474e535b6264680000000000000000000000000000000000a0c10000a0c10000a0410000a0410000a0c10000a0c10000a0410000a0410000a0c10000a0c10000a0410000a041000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084912486b12c49b4004050004ac10445024153b150d0545953500445a1144c50244121150b554855501c45a1144c53244121150b554895501443a11403530cc95348c5b050855409c57020c5a0304383244f31480b3514835409c33120833234033224cf202d523524d222398923398b232589242d8b24258993388993488ee44892232dcee22cceb2389223498e242549924892242dcbb2489224254ee22489233992233992b338cbe22c8ee4488e2425d222258ee4388b2301000000000000 11 | m_Scenes: 12 | - indexRenderers: 0 13 | sizeRenderers: 2 14 | indexPortals: 0 15 | sizePortals: 0 16 | scene: 2cda990e2423bbf4892e6590ba056729 17 | m_StaticRenderers: 18 | - targetObject: 814940025 19 | targetPrefab: 0 20 | - targetObject: 741489305 21 | targetPrefab: 0 22 | m_Portals: [] 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/Generator/Editor/BlockfrostGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Text; 4 | using System.IO; 5 | 6 | using Microsoft.OpenApi.Validations; 7 | using Microsoft.OpenApi.Readers; 8 | using Microsoft.OpenApi.Models; 9 | 10 | using UnityEngine; 11 | using UnityEditor; 12 | 13 | using Newtonsoft.Json; 14 | 15 | namespace BlockfrostGen { 16 | [CreateAssetMenu(menuName = "Blockfrost.io API/Generator", fileName = "BlockfrostGenerator")] 17 | public class BlockfrostGenerator : ScriptableObject { 18 | [SerializeField] 19 | [HideInInspector] 20 | private TextAsset OpenAPISpecification = null; 21 | 22 | [SerializeField] 23 | public string Path = "Assets"; 24 | 25 | // TODO output folder for generating with a default 26 | // + gitignore 27 | // + copy script 28 | 29 | private static string bfNamespace = "Blockfrost"; 30 | 31 | public void ParseFromAsset() { 32 | var doc = Parse(OpenAPISpecification.text); 33 | GenerateAssets(doc); 34 | } 35 | 36 | public OpenApiDocument Parse(string json) { 37 | var stream = CreateStream(json); 38 | var parsed = new OpenApiStreamReader(new OpenApiReaderSettings { 39 | ReferenceResolution = ReferenceResolutionSetting.ResolveLocalReferences, 40 | RuleSet = ValidationRuleSet.GetDefaultRuleSet() 41 | }).Read(stream, out var openApiDiagnostic); 42 | Debug.Log("Successfully parsed API Description: " + parsed.Info.Title); 43 | return parsed; 44 | } 45 | 46 | List Endpoints; 47 | Dictionary Models; 48 | 49 | public void GenerateAssets(OpenApiDocument doc) { 50 | Endpoints = new List(); 51 | Models = new Dictionary(); 52 | 53 | ParseDocument(doc); 54 | GenerateModels(); 55 | GenerateAPI(); 56 | CreateConfiguration(doc); 57 | } 58 | 59 | void GenerateModels() { 60 | var sb = new StringBuilder(); 61 | Imports(sb, new[] { "System" }); 62 | sb.AppendLine($"namespace {bfNamespace} {{"); 63 | foreach (var model in Models) { 64 | var m = model.Value.Serialize(); 65 | sb.AppendLine(m); 66 | } 67 | sb.AppendLine("}"); 68 | 69 | File.WriteAllText($"./CardanoModels.cs", sb.ToString()); 70 | } 71 | 72 | void CreateConfiguration(OpenApiDocument doc) { 73 | var config = ScriptableObject.CreateInstance(); 74 | 75 | var info = new Blockfrost.OAInfo{ 76 | Title = doc.Info.Title, 77 | Description = doc.Info.Description, 78 | Version = doc.Info.Version, 79 | TermsOfService = doc.Info.TermsOfService.ToString(), 80 | Contact = new Blockfrost.OAContact{ 81 | Name =doc.Info.Contact.Name, 82 | Url = doc.Info.Contact.Url.ToString(), 83 | Email = doc.Info.Contact.Email, 84 | }, 85 | License = new Blockfrost.OALicense{ 86 | Name = doc.Info.License.Name, 87 | Url = doc.Info.License.Url.ToString(), 88 | } 89 | }; 90 | 91 | AssetDatabase.CreateAsset(info, "Assets/Scripts/Blockfrost/BlockfrostInfo.asset"); 92 | } 93 | 94 | void GenerateAPI() { 95 | var sb = new StringBuilder(); 96 | Imports(sb, new[] { "System.Collections.Generic", "Cysharp.Threading.Tasks" }); 97 | sb.AppendLine($"namespace {bfNamespace} {{"); 98 | sb.AppendLine("public class Cardano : Client {"); 99 | sb.AppendLine("public Cardano() : base() { }"); 100 | sb.AppendLine("public Cardano(Configuration config) : base(config) { }"); 101 | 102 | foreach (var endpoint in Endpoints) { 103 | var e = endpoint.Serialize(); 104 | if (e != null) { 105 | sb.AppendLine(e); 106 | } 107 | } 108 | sb.AppendLine("}"); 109 | sb.AppendLine("}"); 110 | 111 | File.WriteAllText("./Cardano.cs", sb.ToString()); 112 | } 113 | 114 | void Imports(StringBuilder sb, string[] imports) { 115 | foreach (var import in imports) { 116 | sb.AppendLine($"using {import};"); 117 | } 118 | sb.AppendLine(); 119 | } 120 | 121 | private void ParseDocument(OpenApiDocument doc) { 122 | // Endpoints 123 | foreach (var path in doc.Paths) { 124 | // Methods 125 | foreach (var op in path.Value.Operations) { 126 | // Debug.Log($"Processing {op.Key} {path.Key}"); 127 | if (op.Key != OperationType.Get) { 128 | Debug.Log($"Skipping unsupported method {op.Key} {path.Key}"); 129 | } 130 | 131 | var endpoint = new Endpoint { 132 | Path = path.Key, 133 | Method = op.Key.ToString(), 134 | Description = op.Value.Description, 135 | Summary = op.Value.Summary, 136 | ReturnsArray = false, 137 | }; 138 | 139 | if (op.Value.Deprecated == true) { 140 | Debug.Log($"Skipping deprecated endpoint {path}"); 141 | continue; 142 | } 143 | 144 | // Parameters 145 | endpoint.Params = new List(); 146 | foreach (var param in op.Value.Parameters) { 147 | endpoint.Params.Add(new Param { 148 | In = param.In.ToString(), 149 | Type = param.Schema.Type, 150 | Key = param.Name, 151 | Description = param.Description, 152 | Required = param.Required, 153 | }); 154 | } 155 | 156 | // See if there's a valid response 157 | if (!op.Value.Responses.ContainsKey("200")) { 158 | Debug.LogError($"Missing 200 response for {endpoint.Method} {endpoint.Path}"); 159 | continue; 160 | } 161 | var content = op.Value.Responses["200"].Content; 162 | if (!content.ContainsKey("application/json")) { 163 | Debug.LogError($"Missing application/json content for {endpoint.Method} {endpoint.Path}"); 164 | continue; 165 | } 166 | var schema = content["application/json"].Schema; 167 | if (schema == null) { 168 | // TODO IPFS special case 169 | Debug.LogError($"Missing schema for {endpoint.Method} {endpoint.Path}"); 170 | continue; 171 | } 172 | 173 | var rt = PrepareModels(schema, Camelize(schema.Reference?.Id ?? endpoint.Summary)); 174 | 175 | if (rt.modelId == null) { 176 | Debug.LogError($"Invalid model id for {endpoint.Method} {endpoint.Path} ({Camelize(schema.Reference?.Id ?? endpoint.Summary)})"); 177 | continue; 178 | } 179 | 180 | endpoint.ReturnsArray = rt.isArray; 181 | endpoint.ResponseType = rt.modelId; 182 | 183 | Endpoints.Add(endpoint); 184 | } 185 | } 186 | } 187 | 188 | private (bool isArray, string modelId) PrepareModels(OpenApiSchema schema, string key) { 189 | switch (schema.Type) { 190 | case "string": 191 | case "integer": 192 | case "boolean": 193 | case "number": 194 | return (false, BasicTypes[schema.Type]); 195 | case "array": 196 | var rt = PrepareModels(schema.Items, GetModelId(schema, key)); 197 | return (true, rt.modelId); 198 | case "object": 199 | var modelId = GetModelId(schema, key); 200 | if (modelId == null) { 201 | Debug.Log($"Skipping model {modelId}|{key}"); 202 | return (false, null); 203 | } 204 | if (Models.ContainsKey(modelId)) { 205 | return (false, modelId); 206 | } 207 | // Debug.Log($"Preparing model for {modelId}|{key} of type {schema.Type}"); 208 | var model = new ResponseModel { 209 | ID = modelId, 210 | Properties = ParseObjectProperties(schema), 211 | }; 212 | Models[modelId] = model; 213 | return (false, modelId); 214 | default: 215 | // TODO support of oneof, etc... 216 | Debug.LogError($"Unknown or unsupported type {schema.Type}"); 217 | return (false, null); 218 | } 219 | } 220 | 221 | private List ParseObjectProperties(OpenApiSchema schema) { 222 | var properties = new List(); 223 | foreach ((var key, var prop) in schema.Properties) { 224 | var rt = PrepareModels(prop, key); 225 | properties.Add(new ResponseProperty { 226 | Key = key, 227 | Type = rt.modelId, 228 | IsArray = rt.isArray, 229 | Description = prop.Description, 230 | }); 231 | } 232 | 233 | return properties; 234 | } 235 | 236 | private string GetModelId(OpenApiSchema schema, string key) { 237 | return Camelize(schema.Reference?.Id ?? key); 238 | } 239 | 240 | private MemoryStream CreateStream(string text) { 241 | var stream = new MemoryStream(); 242 | var writer = new StreamWriter(stream); 243 | 244 | writer.Write(text); 245 | writer.Flush(); 246 | stream.Position = 0; 247 | 248 | return stream; 249 | } 250 | 251 | public static string Camelize(string name, bool lowerCase = false) { 252 | if (name == null) return null; 253 | var words = name.Split(new[] { '_', ' ' }); 254 | words = words 255 | .Select(word => char.ToUpper(word[0]) + word.Substring(1)) 256 | .ToArray(); 257 | 258 | if (lowerCase) { 259 | words[0] = words[0].ToLower(); 260 | } 261 | 262 | return string.Join(string.Empty, words); 263 | } 264 | 265 | public static readonly Dictionary BasicTypes = new Dictionary { 266 | { "integer", "int" }, 267 | { "string", "string" }, 268 | { "boolean", "bool" }, 269 | { "number", "float" }, 270 | }; 271 | } 272 | 273 | [CustomEditor(typeof(BlockfrostGenerator))] 274 | public class BlockfrostGeneratorEditor : Editor { 275 | public override void OnInspectorGUI() { 276 | base.OnInspectorGUI(); 277 | 278 | GUILayout.Space(10); 279 | 280 | var t = (BlockfrostGenerator)target; 281 | 282 | GUILayout.BeginVertical(); 283 | var a = serializedObject.FindProperty("OpenAPISpecification"); 284 | EditorGUILayout.ObjectField(a); 285 | serializedObject.ApplyModifiedProperties(); 286 | if (GUILayout.Button("Parse From Asset")) { 287 | t.ParseFromAsset(); 288 | } 289 | GUILayout.EndVertical(); 290 | 291 | EditorUtility.SetDirty(target); 292 | } 293 | } 294 | 295 | } -------------------------------------------------------------------------------- /src/Examples/Demo/Scripts/CardanoBech32/Bech32Engine.cs: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017 Guillaume Bonnot and Palekhov Ilia 2 | * Based on the work of Pieter Wuille 3 | * Special Thanks to adiabat 4 | * 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | using System; 26 | using System.Collections.Generic; 27 | using System.Diagnostics; 28 | using System.Linq; 29 | 30 | namespace CardanoBech32 31 | { 32 | public static class Bech32Engine 33 | { 34 | // used for polymod 35 | private static readonly uint[] generator = { 0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3 }; 36 | 37 | // charset is the sequence of ascii characters that make up the bech32 38 | // alphabet. Each character represents a 5-bit squashed byte. 39 | // q = 0b00000, p = 0b00001, z = 0b00010, and so on. 40 | 41 | private const string charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; 42 | 43 | // icharset is a mapping of 8-bit ascii characters to the charset 44 | // positions. Both uppercase and lowercase ascii are mapped to the 5-bit 45 | // position values. 46 | private static readonly short[] icharset = 47 | { 48 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 49 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51 | 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, 52 | -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 53 | 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, 54 | -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 55 | 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 56 | }; 57 | 58 | // PolyMod takes a byte slice and returns the 32-bit BCH checksum. 59 | // Note that the input bytes to PolyMod need to be squashed to 5-bits tall 60 | // before being used in this function. And this function will not error, 61 | // but instead return an unsuable checksum, if you give it full-height bytes. 62 | public static uint PolyMod(byte[] values) 63 | { 64 | uint chk = 1; 65 | foreach (byte value in values) 66 | { 67 | var top = chk >> 25; 68 | chk = (chk & 0x1ffffff) << 5 ^ value; 69 | for (var i = 0; i < 5; ++i) 70 | { 71 | if (((top >> i) & 1) == 1) 72 | { 73 | chk ^= generator[i]; 74 | } 75 | } 76 | } 77 | return chk; 78 | } 79 | 80 | 81 | // on error, data == null 82 | public static void Decode(string encoded, out string hrp, out byte[] data) 83 | { 84 | byte[] squashed; 85 | DecodeSquashed(encoded, out hrp, out squashed); 86 | if (squashed == null) 87 | { 88 | data = null; 89 | return; 90 | } 91 | data = Bytes5to8(squashed); 92 | } 93 | 94 | // on error, data == null 95 | private static void DecodeSquashed(string adr, out string hrp, out byte[] data) 96 | { 97 | adr = CheckAndFormat(adr); 98 | if (adr == null) 99 | { 100 | data = null; hrp = null; return; 101 | } 102 | 103 | // find the last "1" and split there 104 | var splitLoc = adr.LastIndexOf("1"); 105 | if (splitLoc == -1) { 106 | Debug.WriteLine("1 separator not present in address"); 107 | data = null; hrp = null; return; 108 | } 109 | 110 | // hrp comes before the split 111 | hrp = adr.Substring(0,splitLoc); 112 | 113 | // get squashed data 114 | var squashed = StringToSquashedBytes(adr.Substring(splitLoc + 1)); 115 | if (squashed == null) { 116 | data = null; return; 117 | } 118 | 119 | // make sure checksum works 120 | if(!VerifyChecksum(hrp, squashed)) { 121 | Debug.WriteLine("Checksum invalid"); 122 | data = null; return; 123 | } 124 | 125 | // chop off checksum to return only payload 126 | var length = squashed.Length - 6; 127 | data = new byte[length]; 128 | Array.Copy(squashed, 0, data, 0, length); 129 | } 130 | 131 | // on error, return null 132 | private static string CheckAndFormat(string adr) 133 | { 134 | // make an all lowercase and all uppercase version of the input string 135 | var lowAdr = adr.ToLower(); 136 | var highAdr = adr.ToUpper(); 137 | 138 | // if there's mixed case, that's not OK 139 | if (adr != lowAdr && adr != highAdr) 140 | { 141 | Debug.WriteLine("mixed case address"); 142 | return null; 143 | } 144 | 145 | // default to lowercase 146 | return lowAdr; 147 | } 148 | 149 | private static bool VerifyChecksum(string hrp, byte[] data) 150 | { 151 | var values = HRPExpand(hrp).Concat(data).ToArray(); 152 | var checksum = PolyMod(values); 153 | // make sure it's 1 (from the LSB flip in CreateChecksum 154 | return checksum == 1; 155 | } 156 | 157 | // on error, return null 158 | private static byte[] StringToSquashedBytes(string input) 159 | { 160 | byte[] squashed = new byte[input.Length]; 161 | 162 | for (int i = 0; i < input.Length; i++) 163 | { 164 | var c = input[i]; 165 | var buffer = icharset[c]; 166 | if (buffer == -1) 167 | { 168 | Debug.WriteLine("contains invalid character " + c); 169 | return null; 170 | } 171 | squashed[i] = (byte)buffer; 172 | } 173 | 174 | return squashed; 175 | } 176 | 177 | // we encode the data and the human readable prefix 178 | public static string Encode(string hrp, byte[] data) 179 | { 180 | var base5 = Bytes8to5(data); 181 | if (base5 == null) 182 | return string.Empty; 183 | return EncodeSquashed(hrp, base5); 184 | } 185 | 186 | // on error, return null 187 | private static string EncodeSquashed(string hrp, byte[] data) 188 | { 189 | var checksum = CreateChecksum(hrp, data); 190 | var combined = data.Concat(checksum).ToArray(); 191 | 192 | // Should be squashed, return empty string if it's not. 193 | var encoded = SquashedBytesToString(combined); 194 | if (encoded == null) 195 | return null; 196 | return hrp + "1" + encoded; 197 | } 198 | 199 | private static byte[] CreateChecksum(string hrp, byte[] data) 200 | { 201 | var values = HRPExpand(hrp).Concat(data).ToArray(); 202 | // put 6 zero bytes on at the end 203 | values = values.Concat(new byte[6]).ToArray(); 204 | //get checksum for whole slice 205 | 206 | // flip the LSB of the checksum data after creating it 207 | var checksum = PolyMod(values) ^ 1; 208 | 209 | byte[] ret = new byte[6]; 210 | for (var i = 0; i < 6; i++) 211 | { 212 | // note that this is NOT the same as converting 8 to 5 213 | // this is it's own expansion to 6 bytes from 4, chopping 214 | // off the MSBs. 215 | ret[i] = (byte) (checksum >> (5*(5 - i)) & 0x1f); 216 | } 217 | 218 | return ret; 219 | } 220 | 221 | // HRPExpand turns the human redable part into 5bit-bytes for later processing 222 | private static byte[] HRPExpand(string input) 223 | { 224 | var output = new byte[(input.Length*2) + 1]; 225 | 226 | // first half is the input string shifted down 5 bits. 227 | // not much is going on there in terms of data / entropy 228 | for (int i = 0; i < input.Length; i++) 229 | { 230 | var c = input[i]; 231 | output[i] = (byte) (c >> 5); 232 | } 233 | 234 | // then there's a 0 byte separator 235 | // don't need to set 0 byte in the middle, as it starts out that way 236 | 237 | // second half is the input string, with the top 3 bits zeroed. 238 | // most of the data / entropy will live here. 239 | for (int i = 0; i < input.Length; i++) 240 | { 241 | var c = input[i]; 242 | output[i + input.Length + 1] = (byte) (c & 0x1f); 243 | } 244 | return output; 245 | } 246 | 247 | private static string SquashedBytesToString(byte[] input) 248 | { 249 | string s = string.Empty; 250 | for (int i = 0; i < input.Length; i++) 251 | { 252 | var c = input[i]; 253 | if ((c & 0xe0) != 0) 254 | { 255 | Debug.WriteLine("high bits set at position {0}: {1}", i, c); 256 | return null; 257 | } 258 | s += charset[c]; 259 | } 260 | 261 | return s; 262 | } 263 | 264 | private static byte[] Bytes8to5(byte[] data) 265 | { 266 | return ByteSquasher(data, 8, 5); 267 | } 268 | 269 | private static byte[] Bytes5to8(byte[] data) 270 | { 271 | return ByteSquasher(data, 5, 8); 272 | } 273 | 274 | // ByteSquasher squashes full-width (8-bit) bytes into "squashed" 5-bit bytes, 275 | // and vice versa. It can operate on other widths but in this package only 276 | // goes 5 to 8 and back again. It can return null if the squashed input 277 | // you give it isn't actually squashed, or if there is padding (trailing q characters) 278 | // when going from 5 to 8 279 | private static byte[] ByteSquasher(byte[] input, int inputWidth, int outputWidth) 280 | { 281 | int bitstash = 0; 282 | int accumulator = 0; 283 | List output = new List(); 284 | var maxOutputValue = (1 << outputWidth) - 1; 285 | 286 | for (int i = 0; i < input.Length; i++) 287 | { 288 | var c = input[i]; 289 | if (c >> inputWidth != 0) 290 | { 291 | Debug.WriteLine("byte {0} ({1}) high bits set", i, c); 292 | return null; 293 | } 294 | accumulator = (accumulator << inputWidth) | c; 295 | bitstash += inputWidth; 296 | while (bitstash >= outputWidth) 297 | { 298 | bitstash -= outputWidth; 299 | output.Add((byte) ((accumulator >> bitstash) & maxOutputValue)); 300 | } 301 | } 302 | 303 | // pad if going from 8 to 5 304 | if (inputWidth == 8 && outputWidth == 5) 305 | { 306 | if (bitstash != 0) 307 | { 308 | output.Add((byte) (accumulator << (outputWidth - bitstash) & maxOutputValue)); 309 | } 310 | } 311 | else if (bitstash >= inputWidth || ((accumulator << (outputWidth - bitstash)) & maxOutputValue) != 0) 312 | { 313 | // no pad from 5 to 8 allowed 314 | Debug.WriteLine("invalid padding from {0} to {1} bits", inputWidth, outputWidth); 315 | return null; 316 | } 317 | return output.ToArray(); 318 | } 319 | } 320 | } -------------------------------------------------------------------------------- /src/Blockfrost.io/Scripts/Cardano.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Cysharp.Threading.Tasks; 3 | 4 | namespace Blockfrost { 5 | public class Cardano : Client { 6 | public Cardano() : base() { } 7 | public Cardano(Configuration config) : base(config) { } 8 | /// 9 | /// Root endpoint has no other function than to point end users to documentation. 10 | /// 11 | /// GET / 12 | public async UniTask GetRootEndpoint() { 13 | const string path = "/"; 14 | var pathParams = new Dictionary(); 15 | return await Get(path, pathParams); 16 | } 17 | 18 | /// 19 | /// Return backend status as a boolean. Your application should handle situations when backend for the given chain is unavailable. 20 | /// 21 | /// GET /health 22 | public async UniTask GetBackendHealthStatus() { 23 | const string path = "/health"; 24 | var pathParams = new Dictionary(); 25 | return await Get(path, pathParams); 26 | } 27 | 28 | /// 29 | /// This endpoint provides the current UNIX time. Your application might 30 | /// use this to verify if the client clock is not out of sync. 31 | /// 32 | /// GET /health/clock 33 | public async UniTask GetCurrentBackendTime() { 34 | const string path = "/health/clock"; 35 | var pathParams = new Dictionary(); 36 | return await Get(path, pathParams); 37 | } 38 | 39 | /// 40 | /// Return the latest block available to the backends, also known as the 41 | /// tip of the blockchain. 42 | /// 43 | /// GET /blocks/latest 44 | public async UniTask GetLatestBlock() { 45 | const string path = "/blocks/latest"; 46 | var pathParams = new Dictionary(); 47 | return await Get(path, pathParams); 48 | } 49 | 50 | /// 51 | /// Return the transactions within the latest block. 52 | /// 53 | /// GET /blocks/latest/txs 54 | public async UniTask GetLatestBlockTransactions(OrderedListing query = null) { 55 | const string path = "/blocks/latest/txs"; 56 | var pathParams = new Dictionary(); 57 | return await GetArray(path, pathParams, query); 58 | } 59 | 60 | /// 61 | /// Return the content of a requested block. 62 | /// 63 | /// GET /blocks/{hash_or_number} 64 | /// Hash or number of the requested block. 65 | public async UniTask GetSpecificBlock(string hashOrNumber) { 66 | const string path = "/blocks/{hash_or_number}"; 67 | var pathParams = new Dictionary(){ 68 | {"hash_or_number", hashOrNumber}, 69 | }; 70 | return await Get(path, pathParams); 71 | } 72 | 73 | /// 74 | /// Return the list of blocks following a specific block. 75 | /// 76 | /// GET /blocks/{hash_or_number}/next 77 | /// Hash of the requested block. 78 | public async UniTask GetListingOfNextBlocks(string hashOrNumber, Listing query = null) { 79 | const string path = "/blocks/{hash_or_number}/next"; 80 | var pathParams = new Dictionary(){ 81 | {"hash_or_number", hashOrNumber}, 82 | }; 83 | return await GetArray(path, pathParams, query); 84 | } 85 | 86 | /// 87 | /// Return the list of blocks preceding a specific block. 88 | /// 89 | /// GET /blocks/{hash_or_number}/previous 90 | /// Hash of the requested block 91 | public async UniTask GetListingOfPreviousBlocks(string hashOrNumber, Listing query = null) { 92 | const string path = "/blocks/{hash_or_number}/previous"; 93 | var pathParams = new Dictionary(){ 94 | {"hash_or_number", hashOrNumber}, 95 | }; 96 | return await GetArray(path, pathParams, query); 97 | } 98 | 99 | /// 100 | /// Return the content of a requested block for a specific slot. 101 | /// 102 | /// GET /blocks/slot/{slot_number} 103 | /// Slot position for requested block. 104 | public async UniTask GetSpecificBlockInASlot(int slotNumber) { 105 | const string path = "/blocks/slot/{slot_number}"; 106 | var pathParams = new Dictionary(){ 107 | {"slot_number", slotNumber}, 108 | }; 109 | return await Get(path, pathParams); 110 | } 111 | 112 | /// 113 | /// Return the content of a requested block for a specific slot in an epoch. 114 | /// 115 | /// GET /blocks/epoch/{epoch_number}/slot/{slot_number} 116 | /// Epoch for specific epoch slot. 117 | /// Slot position for requested block. 118 | public async UniTask GetSpecificBlockInASlotInAnEpoch(int epochNumber, int slotNumber) { 119 | const string path = "/blocks/epoch/{epoch_number}/slot/{slot_number}"; 120 | var pathParams = new Dictionary(){ 121 | {"epoch_number", epochNumber}, 122 | {"slot_number", slotNumber}, 123 | }; 124 | return await Get(path, pathParams); 125 | } 126 | 127 | /// 128 | /// Return the transactions within the block. 129 | /// 130 | /// GET /blocks/{hash_or_number}/txs 131 | /// Hash of the requested block. 132 | public async UniTask GetBlockTransactions(string hashOrNumber, OrderedListing query = null) { 133 | const string path = "/blocks/{hash_or_number}/txs"; 134 | var pathParams = new Dictionary(){ 135 | {"hash_or_number", hashOrNumber}, 136 | }; 137 | return await GetArray(path, pathParams, query); 138 | } 139 | 140 | /// 141 | /// Return list of addresses affected in the specified block with additional information, sorted by the bech32 address, ascending. 142 | /// 143 | /// GET /blocks/{hash_or_number}/addresses 144 | /// Hash of the requested block. 145 | public async UniTask GetAddressesAffectedInASpecificBlock(string hashOrNumber, Listing query = null) { 146 | const string path = "/blocks/{hash_or_number}/addresses"; 147 | var pathParams = new Dictionary(){ 148 | {"hash_or_number", hashOrNumber}, 149 | }; 150 | return await GetArray(path, pathParams, query); 151 | } 152 | 153 | /// 154 | /// Return the information about blockchain genesis. 155 | /// 156 | /// GET /genesis 157 | public async UniTask GetBlockchainGenesis() { 158 | const string path = "/genesis"; 159 | var pathParams = new Dictionary(); 160 | return await Get(path, pathParams); 161 | } 162 | 163 | /// 164 | /// Return the information about the latest, therefore current, epoch. 165 | /// 166 | /// GET /epochs/latest 167 | public async UniTask GetLatestEpoch() { 168 | const string path = "/epochs/latest"; 169 | var pathParams = new Dictionary(); 170 | return await Get(path, pathParams); 171 | } 172 | 173 | /// 174 | /// Return the protocol parameters for the latest epoch. 175 | /// 176 | /// GET /epochs/latest/parameters 177 | public async UniTask GetLatestEpochProtocolParameters() { 178 | const string path = "/epochs/latest/parameters"; 179 | var pathParams = new Dictionary(); 180 | return await Get(path, pathParams); 181 | } 182 | 183 | /// 184 | /// Return the content of the requested epoch. 185 | /// 186 | /// GET /epochs/{number} 187 | /// Number of the epoch 188 | public async UniTask GetSpecificEpoch(int number) { 189 | const string path = "/epochs/{number}"; 190 | var pathParams = new Dictionary(){ 191 | {"number", number}, 192 | }; 193 | return await Get(path, pathParams); 194 | } 195 | 196 | /// 197 | /// Return the list of epochs following a specific epoch. 198 | /// 199 | /// GET /epochs/{number}/next 200 | /// Number of the requested epoch. 201 | public async UniTask GetListingOfNextEpochs(int number, Listing query = null) { 202 | const string path = "/epochs/{number}/next"; 203 | var pathParams = new Dictionary(){ 204 | {"number", number}, 205 | }; 206 | return await GetArray(path, pathParams, query); 207 | } 208 | 209 | /// 210 | /// Return the list of epochs preceding a specific epoch. 211 | /// 212 | /// GET /epochs/{number}/previous 213 | /// Number of the epoch 214 | public async UniTask GetListingOfPreviousEpochs(int number, Listing query = null) { 215 | const string path = "/epochs/{number}/previous"; 216 | var pathParams = new Dictionary(){ 217 | {"number", number}, 218 | }; 219 | return await GetArray(path, pathParams, query); 220 | } 221 | 222 | /// 223 | /// Return the blocks minted for the epoch specified. 224 | /// 225 | /// GET /epochs/{number}/blocks 226 | /// Number of the epoch 227 | public async UniTask GetBlockDistribution(int number, OrderedListing query = null) { 228 | const string path = "/epochs/{number}/blocks"; 229 | var pathParams = new Dictionary(){ 230 | {"number", number}, 231 | }; 232 | return await GetArray(path, pathParams, query); 233 | } 234 | 235 | /// 236 | /// Return the block minted for the epoch specified by stake pool. 237 | /// 238 | /// GET /epochs/{number}/blocks/{pool_id} 239 | /// Number of the epoch 240 | /// Stake pool ID to filter 241 | public async UniTask GetBlockDistributionByPool(int number, string poolId, OrderedListing query = null) { 242 | const string path = "/epochs/{number}/blocks/{pool_id}"; 243 | var pathParams = new Dictionary(){ 244 | {"number", number}, 245 | {"pool_id", poolId}, 246 | }; 247 | return await GetArray(path, pathParams, query); 248 | } 249 | 250 | /// 251 | /// Return the protocol parameters for the epoch specified. 252 | /// 253 | /// GET /epochs/{number}/parameters 254 | /// Number of the epoch 255 | public async UniTask GetProtocolParameters(int number) { 256 | const string path = "/epochs/{number}/parameters"; 257 | var pathParams = new Dictionary(){ 258 | {"number", number}, 259 | }; 260 | return await Get(path, pathParams); 261 | } 262 | 263 | /// 264 | /// Return content of the requested transaction. 265 | /// 266 | /// GET /txs/{hash} 267 | /// Hash of the requested transaction 268 | public async UniTask GetSpecificTransaction(string hash) { 269 | const string path = "/txs/{hash}"; 270 | var pathParams = new Dictionary(){ 271 | {"hash", hash}, 272 | }; 273 | return await Get(path, pathParams); 274 | } 275 | 276 | /// 277 | /// Return the inputs and UTXOs of the specific transaction. 278 | /// 279 | /// GET /txs/{hash}/utxos 280 | /// Hash of the requested transaction 281 | public async UniTask GetTransactionUTXOs(string hash) { 282 | const string path = "/txs/{hash}/utxos"; 283 | var pathParams = new Dictionary(){ 284 | {"hash", hash}, 285 | }; 286 | return await Get(path, pathParams); 287 | } 288 | 289 | /// 290 | /// Obtain information about (de)registration of stake addresses within a transaction. 291 | /// 292 | /// GET /txs/{hash}/stakes 293 | /// Hash of the requested transaction. 294 | public async UniTask GetTransactionStakeAddressesCertificates(string hash) { 295 | const string path = "/txs/{hash}/stakes"; 296 | var pathParams = new Dictionary(){ 297 | {"hash", hash}, 298 | }; 299 | return await GetArray(path, pathParams); 300 | } 301 | 302 | /// 303 | /// Obtain information about delegation certificates of a specific transaction. 304 | /// 305 | /// GET /txs/{hash}/delegations 306 | /// Hash of the requested transaction. 307 | public async UniTask GetTransactionDelegationCertificates(string hash) { 308 | const string path = "/txs/{hash}/delegations"; 309 | var pathParams = new Dictionary(){ 310 | {"hash", hash}, 311 | }; 312 | return await GetArray(path, pathParams); 313 | } 314 | 315 | /// 316 | /// Obtain information about withdrawals of a specific transaction. 317 | /// 318 | /// GET /txs/{hash}/withdrawals 319 | /// Hash of the requested transaction. 320 | public async UniTask GetTransactionWithdrawal(string hash) { 321 | const string path = "/txs/{hash}/withdrawals"; 322 | var pathParams = new Dictionary(){ 323 | {"hash", hash}, 324 | }; 325 | return await GetArray(path, pathParams); 326 | } 327 | 328 | /// 329 | /// Obtain information about Move Instantaneous Rewards (MIRs) of a specific transaction. 330 | /// 331 | /// GET /txs/{hash}/mirs 332 | /// Hash of the requested transaction. 333 | public async UniTask GetTransactionMIRs(string hash) { 334 | const string path = "/txs/{hash}/mirs"; 335 | var pathParams = new Dictionary(){ 336 | {"hash", hash}, 337 | }; 338 | return await GetArray(path, pathParams); 339 | } 340 | 341 | /// 342 | /// Obtain information about stake pool registration and update certificates of a specific transaction. 343 | /// 344 | /// GET /txs/{hash}/pool_updates 345 | /// Hash of the requested transaction 346 | public async UniTask GetTransactionStakePoolRegistrationAndUpdateCertificates(string hash) { 347 | const string path = "/txs/{hash}/pool_updates"; 348 | var pathParams = new Dictionary(){ 349 | {"hash", hash}, 350 | }; 351 | return await GetArray(path, pathParams); 352 | } 353 | 354 | /// 355 | /// Obtain information about stake pool retirements within a specific transaction. 356 | /// 357 | /// GET /txs/{hash}/pool_retires 358 | /// Hash of the requested transaction 359 | public async UniTask GetTransactionStakePoolRetirementCertificates(string hash) { 360 | const string path = "/txs/{hash}/pool_retires"; 361 | var pathParams = new Dictionary(){ 362 | {"hash", hash}, 363 | }; 364 | return await GetArray(path, pathParams); 365 | } 366 | 367 | /// 368 | /// Obtain the transaction metadata. 369 | /// 370 | /// GET /txs/{hash}/metadata 371 | /// Hash of the requested transaction 372 | public async UniTask GetTransactionMetadata(string hash) { 373 | const string path = "/txs/{hash}/metadata"; 374 | var pathParams = new Dictionary(){ 375 | {"hash", hash}, 376 | }; 377 | return await GetArray(path, pathParams); 378 | } 379 | 380 | /// 381 | /// Obtain the transaction metadata in CBOR. 382 | /// 383 | /// GET /txs/{hash}/metadata/cbor 384 | /// Hash of the requested transaction 385 | public async UniTask GetTransactionMetadataInCBOR(string hash) { 386 | const string path = "/txs/{hash}/metadata/cbor"; 387 | var pathParams = new Dictionary(){ 388 | {"hash", hash}, 389 | }; 390 | return await GetArray(path, pathParams); 391 | } 392 | 393 | /// 394 | /// Obtain the transaction redeemers. 395 | /// 396 | /// GET /txs/{hash}/redeemers 397 | /// Hash of the requested transaction 398 | public async UniTask GetTransactionRedeemers(string hash) { 399 | const string path = "/txs/{hash}/redeemers"; 400 | var pathParams = new Dictionary(){ 401 | {"hash", hash}, 402 | }; 403 | return await GetArray(path, pathParams); 404 | } 405 | 406 | /// 407 | /// Obtain information about a specific stake account. 408 | /// 409 | /// GET /accounts/{stake_address} 410 | /// Bech32 stake address. 411 | public async UniTask GetSpecificAccountAddress(string stakeAddress) { 412 | const string path = "/accounts/{stake_address}"; 413 | var pathParams = new Dictionary(){ 414 | {"stake_address", stakeAddress}, 415 | }; 416 | return await Get(path, pathParams); 417 | } 418 | 419 | /// 420 | /// Obtain information about the reward history of a specific account. 421 | /// 422 | /// GET /accounts/{stake_address}/rewards 423 | /// Bech32 stake address. 424 | public async UniTask GetAccountRewardHistory(string stakeAddress, OrderedListing query = null) { 425 | const string path = "/accounts/{stake_address}/rewards"; 426 | var pathParams = new Dictionary(){ 427 | {"stake_address", stakeAddress}, 428 | }; 429 | return await GetArray(path, pathParams, query); 430 | } 431 | 432 | /// 433 | /// Obtain information about the history of a specific account. 434 | /// 435 | /// GET /accounts/{stake_address}/history 436 | /// Bech32 stake address. 437 | public async UniTask GetAccountHistory(string stakeAddress, OrderedListing query = null) { 438 | const string path = "/accounts/{stake_address}/history"; 439 | var pathParams = new Dictionary(){ 440 | {"stake_address", stakeAddress}, 441 | }; 442 | return await GetArray(path, pathParams, query); 443 | } 444 | 445 | /// 446 | /// Obtain information about the delegation of a specific account. 447 | /// 448 | /// GET /accounts/{stake_address}/delegations 449 | /// Bech32 stake address. 450 | public async UniTask GetAccountDelegationHistory(string stakeAddress, OrderedListing query = null) { 451 | const string path = "/accounts/{stake_address}/delegations"; 452 | var pathParams = new Dictionary(){ 453 | {"stake_address", stakeAddress}, 454 | }; 455 | return await GetArray(path, pathParams, query); 456 | } 457 | 458 | /// 459 | /// Obtain information about the registrations and deregistrations of a specific account. 460 | /// 461 | /// GET /accounts/{stake_address}/registrations 462 | /// Bech32 stake address. 463 | public async UniTask GetAccountRegistrationHistory(string stakeAddress, OrderedListing query = null) { 464 | const string path = "/accounts/{stake_address}/registrations"; 465 | var pathParams = new Dictionary(){ 466 | {"stake_address", stakeAddress}, 467 | }; 468 | return await GetArray(path, pathParams, query); 469 | } 470 | 471 | /// 472 | /// Obtain information about the withdrawals of a specific account. 473 | /// 474 | /// GET /accounts/{stake_address}/withdrawals 475 | /// Bech32 stake address. 476 | public async UniTask GetAccountWithdrawalHistory(string stakeAddress, OrderedListing query = null) { 477 | const string path = "/accounts/{stake_address}/withdrawals"; 478 | var pathParams = new Dictionary(){ 479 | {"stake_address", stakeAddress}, 480 | }; 481 | return await GetArray(path, pathParams, query); 482 | } 483 | 484 | /// 485 | /// Obtain information about the MIRs of a specific account. 486 | /// 487 | /// GET /accounts/{stake_address}/mirs 488 | /// Bech32 stake address. 489 | public async UniTask GetAccountMIRHistory(string stakeAddress, OrderedListing query = null) { 490 | const string path = "/accounts/{stake_address}/mirs"; 491 | var pathParams = new Dictionary(){ 492 | {"stake_address", stakeAddress}, 493 | }; 494 | return await GetArray(path, pathParams, query); 495 | } 496 | 497 | /// 498 | /// Obtain information about the addresses of a specific account. 499 | /// 500 | /// GET /accounts/{stake_address}/addresses 501 | /// Bech32 stake address. 502 | public async UniTask GetAccountAssociatedAddresses(string stakeAddress, OrderedListing query = null) { 503 | const string path = "/accounts/{stake_address}/addresses"; 504 | var pathParams = new Dictionary(){ 505 | {"stake_address", stakeAddress}, 506 | }; 507 | return await GetArray(path, pathParams, query); 508 | } 509 | 510 | /// 511 | /// Obtain information about assets associated with addresses of a specific account. 512 | /// Be careful, as an account could be part of a mangled address and does not necessarily mean the addresses are owned by user as the account. 513 | /// 514 | /// GET /accounts/{stake_address}/addresses/assets 515 | /// Bech32 stake address. 516 | public async UniTask GetAssetsAssociatedWithTheAccountAddresses(string stakeAddress, OrderedListing query = null) { 517 | const string path = "/accounts/{stake_address}/addresses/assets"; 518 | var pathParams = new Dictionary(){ 519 | {"stake_address", stakeAddress}, 520 | }; 521 | return await GetArray(path, pathParams, query); 522 | } 523 | 524 | /// 525 | /// Obtain summed details about all addresses associated with a given account. 526 | /// Be careful, as an account could be part of a mangled address and does not necessarily mean the addresses are owned by user as the account. 527 | /// 528 | /// GET /accounts/{stake_address}/addresses/total 529 | /// Bech32 address. 530 | public async UniTask GetDetailedInformationAboutAccountAssociatedAddresses(string stakeAddress) { 531 | const string path = "/accounts/{stake_address}/addresses/total"; 532 | var pathParams = new Dictionary(){ 533 | {"stake_address", stakeAddress}, 534 | }; 535 | return await Get(path, pathParams); 536 | } 537 | 538 | /// 539 | /// List of all used transaction metadata labels. 540 | /// 541 | /// GET /metadata/txs/labels 542 | public async UniTask GetTransactionMetadataLabels(OrderedListing query = null) { 543 | const string path = "/metadata/txs/labels"; 544 | var pathParams = new Dictionary(); 545 | return await GetArray(path, pathParams, query); 546 | } 547 | 548 | /// 549 | /// Transaction metadata per label. 550 | /// 551 | /// GET /metadata/txs/labels/{label} 552 | /// Metadata label 553 | public async UniTask GetTransactionMetadataContentInJSON(string label, OrderedListing query = null) { 554 | const string path = "/metadata/txs/labels/{label}"; 555 | var pathParams = new Dictionary(){ 556 | {"label", label}, 557 | }; 558 | return await GetArray(path, pathParams, query); 559 | } 560 | 561 | /// 562 | /// Transaction metadata per label. 563 | /// 564 | /// GET /metadata/txs/labels/{label}/cbor 565 | /// Metadata label 566 | public async UniTask GetTransactionMetadataContentInCBOR(string label, OrderedListing query = null) { 567 | const string path = "/metadata/txs/labels/{label}/cbor"; 568 | var pathParams = new Dictionary(){ 569 | {"label", label}, 570 | }; 571 | return await GetArray(path, pathParams, query); 572 | } 573 | 574 | /// 575 | /// Obtain information about a specific address. 576 | /// 577 | /// GET /addresses/{address} 578 | /// Bech32 address. 579 | public async UniTask GetSpecificAddress(string address) { 580 | const string path = "/addresses/{address}"; 581 | var pathParams = new Dictionary(){ 582 | {"address", address}, 583 | }; 584 | return await Get(path, pathParams); 585 | } 586 | 587 | /// 588 | /// Obtain extended information about a specific address. 589 | /// 590 | /// GET /addresses/{address}/extended 591 | /// Bech32 address. 592 | public async UniTask GetExtendedInformationOfASpecificAddress(string address) { 593 | const string path = "/addresses/{address}/extended"; 594 | var pathParams = new Dictionary(){ 595 | {"address", address}, 596 | }; 597 | return await Get(path, pathParams); 598 | } 599 | 600 | /// 601 | /// Obtain details about an address. 602 | /// 603 | /// GET /addresses/{address}/total 604 | /// Bech32 address. 605 | public async UniTask GetAddressDetails(string address) { 606 | const string path = "/addresses/{address}/total"; 607 | var pathParams = new Dictionary(){ 608 | {"address", address}, 609 | }; 610 | return await Get(path, pathParams); 611 | } 612 | 613 | /// 614 | /// UTXOs of the address. 615 | /// 616 | /// GET /addresses/{address}/utxos 617 | /// Bech32 address. 618 | public async UniTask GetAddressUTXOs(string address, OrderedListing query = null) { 619 | const string path = "/addresses/{address}/utxos"; 620 | var pathParams = new Dictionary(){ 621 | {"address", address}, 622 | }; 623 | return await GetArray(path, pathParams, query); 624 | } 625 | 626 | /// 627 | /// UTXOs of the address. 628 | /// 629 | /// GET /addresses/{address}/utxos/{asset} 630 | /// Bech32 address. 631 | /// Concatenation of the policy_id and hex-encoded asset_name 632 | public async UniTask GetAddressUTXOsOfAGivenAsset(string address, string asset, OrderedListing query = null) { 633 | const string path = "/addresses/{address}/utxos/{asset}"; 634 | var pathParams = new Dictionary(){ 635 | {"address", address}, 636 | {"asset", asset}, 637 | }; 638 | return await GetArray(path, pathParams, query); 639 | } 640 | 641 | /// 642 | /// Transactions on the address. 643 | /// 644 | /// GET /addresses/{address}/transactions 645 | /// Bech32 address. 646 | public async UniTask GetAddressTransactions(string address, TargetableOrderedListing query = null) { 647 | const string path = "/addresses/{address}/transactions"; 648 | var pathParams = new Dictionary(){ 649 | {"address", address}, 650 | }; 651 | return await GetArray(path, pathParams, query); 652 | } 653 | 654 | /// 655 | /// List of registered stake pools. 656 | /// 657 | /// GET /pools 658 | public async UniTask GetListOfStakePools(OrderedListing query = null) { 659 | const string path = "/pools"; 660 | var pathParams = new Dictionary(); 661 | return await GetArray(path, pathParams, query); 662 | } 663 | 664 | /// 665 | /// List of registered stake pools with additional information. 666 | /// 667 | /// GET /pools/extended 668 | public async UniTask GetListOfStakePoolsWithAdditionalInformation(OrderedListing query = null) { 669 | const string path = "/pools/extended"; 670 | var pathParams = new Dictionary(); 671 | return await GetArray(path, pathParams, query); 672 | } 673 | 674 | /// 675 | /// List of already retired pools. 676 | /// 677 | /// GET /pools/retired 678 | public async UniTask GetListOfRetiredStakePools(OrderedListing query = null) { 679 | const string path = "/pools/retired"; 680 | var pathParams = new Dictionary(); 681 | return await GetArray(path, pathParams, query); 682 | } 683 | 684 | /// 685 | /// List of stake pools retiring in the upcoming epochs 686 | /// 687 | /// GET /pools/retiring 688 | public async UniTask GetListOfRetiringStakePools(OrderedListing query = null) { 689 | const string path = "/pools/retiring"; 690 | var pathParams = new Dictionary(); 691 | return await GetArray(path, pathParams, query); 692 | } 693 | 694 | /// 695 | /// Pool information. 696 | /// 697 | /// GET /pools/{pool_id} 698 | /// Bech32 or hexadecimal pool ID. 699 | public async UniTask GetSpecificStakePool(string poolId) { 700 | const string path = "/pools/{pool_id}"; 701 | var pathParams = new Dictionary(){ 702 | {"pool_id", poolId}, 703 | }; 704 | return await Get(path, pathParams); 705 | } 706 | 707 | /// 708 | /// History of stake pool parameters over epochs. 709 | /// 710 | /// GET /pools/{pool_id}/history 711 | /// Bech32 or hexadecimal pool ID. 712 | public async UniTask GetStakePoolHistory(string poolId, OrderedListing query = null) { 713 | const string path = "/pools/{pool_id}/history"; 714 | var pathParams = new Dictionary(){ 715 | {"pool_id", poolId}, 716 | }; 717 | return await GetArray(path, pathParams, query); 718 | } 719 | 720 | /// 721 | /// Relays of a stake pool. 722 | /// 723 | /// GET /pools/{pool_id}/relays 724 | /// Bech32 or hexadecimal pool ID. 725 | public async UniTask GetStakePoolRelays(string poolId) { 726 | const string path = "/pools/{pool_id}/relays"; 727 | var pathParams = new Dictionary(){ 728 | {"pool_id", poolId}, 729 | }; 730 | return await GetArray(path, pathParams); 731 | } 732 | 733 | /// 734 | /// List of current stake pools delegators. 735 | /// 736 | /// GET /pools/{pool_id}/delegators 737 | /// Bech32 or hexadecimal pool ID. 738 | public async UniTask GetStakePoolDelegators(string poolId, OrderedListing query = null) { 739 | const string path = "/pools/{pool_id}/delegators"; 740 | var pathParams = new Dictionary(){ 741 | {"pool_id", poolId}, 742 | }; 743 | return await GetArray(path, pathParams, query); 744 | } 745 | 746 | /// 747 | /// List of stake pools blocks. 748 | /// 749 | /// GET /pools/{pool_id}/blocks 750 | /// Bech32 or hexadecimal pool ID. 751 | public async UniTask GetStakePoolBlocks(string poolId, OrderedListing query = null) { 752 | const string path = "/pools/{pool_id}/blocks"; 753 | var pathParams = new Dictionary(){ 754 | {"pool_id", poolId}, 755 | }; 756 | return await GetArray(path, pathParams, query); 757 | } 758 | 759 | /// 760 | /// List of certificate updates to the stake pool. 761 | /// 762 | /// GET /pools/{pool_id}/updates 763 | /// Bech32 or hexadecimal pool ID. 764 | public async UniTask GetStakePoolUpdates(string poolId, OrderedListing query = null) { 765 | const string path = "/pools/{pool_id}/updates"; 766 | var pathParams = new Dictionary(){ 767 | {"pool_id", poolId}, 768 | }; 769 | return await GetArray(path, pathParams, query); 770 | } 771 | 772 | /// 773 | /// List of assets. 774 | /// 775 | /// GET /assets 776 | public async UniTask GetAssets(OrderedListing query = null) { 777 | const string path = "/assets"; 778 | var pathParams = new Dictionary(); 779 | return await GetArray(path, pathParams, query); 780 | } 781 | 782 | /// 783 | /// Information about a specific asset 784 | /// 785 | /// GET /assets/{asset} 786 | /// Concatenation of the policy_id and hex-encoded asset_name 787 | public async UniTask GetSpecificAsset(string asset) { 788 | const string path = "/assets/{asset}"; 789 | var pathParams = new Dictionary(){ 790 | {"asset", asset}, 791 | }; 792 | return await Get(path, pathParams); 793 | } 794 | 795 | /// 796 | /// History of a specific asset 797 | /// 798 | /// GET /assets/{asset}/history 799 | /// Concatenation of the policy_id and hex-encoded asset_name 800 | public async UniTask GetAssetHistory(string asset, OrderedListing query = null) { 801 | const string path = "/assets/{asset}/history"; 802 | var pathParams = new Dictionary(){ 803 | {"asset", asset}, 804 | }; 805 | return await GetArray(path, pathParams, query); 806 | } 807 | 808 | /// 809 | /// List of a specific asset transactions 810 | /// 811 | /// GET /assets/{asset}/transactions 812 | /// Concatenation of the policy_id and hex-encoded asset_name 813 | public async UniTask GetAssetTransactions(string asset, OrderedListing query = null) { 814 | const string path = "/assets/{asset}/transactions"; 815 | var pathParams = new Dictionary(){ 816 | {"asset", asset}, 817 | }; 818 | return await GetArray(path, pathParams, query); 819 | } 820 | 821 | /// 822 | /// List of a addresses containing a specific asset 823 | /// 824 | /// GET /assets/{asset}/addresses 825 | /// Concatenation of the policy_id and hex-encoded asset_name 826 | public async UniTask GetAssetAddresses(string asset, OrderedListing query = null) { 827 | const string path = "/assets/{asset}/addresses"; 828 | var pathParams = new Dictionary(){ 829 | {"asset", asset}, 830 | }; 831 | return await GetArray(path, pathParams, query); 832 | } 833 | 834 | /// 835 | /// List of asset minted under a specific policy 836 | /// 837 | /// GET /assets/policy/{policy_id} 838 | /// Specific policy_id 839 | public async UniTask GetAssetsOfASpecificPolicy(string policyId, OrderedListing query = null) { 840 | const string path = "/assets/policy/{policy_id}"; 841 | var pathParams = new Dictionary(){ 842 | {"policy_id", policyId}, 843 | }; 844 | return await GetArray(path, pathParams, query); 845 | } 846 | 847 | /// 848 | /// List of scripts. 849 | /// 850 | /// GET /scripts 851 | public async UniTask GetScripts(OrderedListing query = null) { 852 | const string path = "/scripts"; 853 | var pathParams = new Dictionary(); 854 | return await GetArray(path, pathParams, query); 855 | } 856 | 857 | /// 858 | /// Information about a specific script 859 | /// 860 | /// GET /scripts/{script_hash} 861 | /// Hash of the script 862 | public async UniTask