This is unreleased documentation for Spawn Next version.
For up-to-date documentation, see the latest version (v0.50.x).
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..ca972efe --- /dev/null +++ b/404.html @@ -0,0 +1,20 @@ + + +
+ + +"+e(t)+"
"}}(t.templates,this.displayFn),this.css=o.mixin({},c,t.appendTo?c.appendTo:{}),this.cssClasses=t.cssClasses=o.mixin({},c.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||o.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix);var n=o.className(this.cssClasses.prefix,this.cssClasses.dataset);this.$el=t.$menu&&t.$menu.find(n+"-"+this.name).length>0?a.element(t.$menu.find(n+"-"+this.name)[0]):a.element(u.dataset.replace("%CLASS%",this.name).replace("%PREFIX%",this.cssClasses.prefix).replace("%DATASET%",this.cssClasses.dataset)),this.$menu=t.$menu,this.clearCachedSuggestions()}h.extractDatasetName=function(t){return a.element(t).data(i)},h.extractValue=function(t){return a.element(t).data(s)},h.extractDatum=function(t){var e=a.element(t).data(r);return"string"==typeof e&&(e=JSON.parse(e)),e},o.mixin(h.prototype,l,{_render:function(t,e){if(this.$el){var n,c=this,l=[].slice.call(arguments,2);if(this.$el.empty(),n=e&&e.length,this._isEmpty=!n,!n&&this.templates.empty)this.$el.html(function(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!0}].concat(e),c.templates.empty.apply(this,e)}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(n)this.$el.html(function(){var t,n,l=[].slice.call(arguments,0),h=this,p=u.suggestions.replace("%PREFIX%",this.cssClasses.prefix).replace("%SUGGESTIONS%",this.cssClasses.suggestions);return t=a.element(p).css(this.css.suggestions),n=o.map(e,f),t.append.apply(t,n),t;function f(t){var e,n=u.suggestion.replace("%PREFIX%",h.cssClasses.prefix).replace("%SUGGESTION%",h.cssClasses.suggestion);return(e=a.element(n).attr({role:"option",id:["option",Math.floor(1e8*Math.random())].join("-")}).append(c.templates.suggestion.apply(this,[t].concat(l)))).data(i,c.name),e.data(s,c.displayFn(t)||void 0),e.data(r,JSON.stringify(t)),e.children().each((function(){a.element(this).css(h.css.suggestionChild)})),e}}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(e&&!Array.isArray(e))throw new TypeError("suggestions must be an array");this.$menu&&this.$menu.addClass(this.cssClasses.prefix+(n?"with":"without")+"-"+this.name).removeClass(this.cssClasses.prefix+(n?"without":"with")+"-"+this.name),this.trigger("rendered",t)}function h(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.header.apply(this,e)}function p(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.footer.apply(this,e)}},getRoot:function(){return this.$el},update:function(t){function e(e){if(!this.canceled&&t===this.query){var n=[].slice.call(arguments,1);this.cacheSuggestions(t,e,n),this._render.apply(this,[t,e].concat(n))}}if(this.query=t,this.canceled=!1,this.shouldFetchFromCache(t))e.apply(this,[this.cachedSuggestions].concat(this.cachedRenderExtraArgs));else{var n=this,i=function(){n.canceled||n.source(t,e.bind(n))};if(this.debounce){clearTimeout(this.debounceTimeout),this.debounceTimeout=setTimeout((function(){n.debounceTimeout=null,i()}),this.debounce)}else i()}},cacheSuggestions:function(t,e,n){this.cachedQuery=t,this.cachedSuggestions=e,this.cachedRenderExtraArgs=n},shouldFetchFromCache:function(t){return this.cache&&this.cachedQuery===t&&this.cachedSuggestions&&this.cachedSuggestions.length},clearCachedSuggestions:function(){delete this.cachedQuery,delete this.cachedSuggestions,delete this.cachedRenderExtraArgs},cancel:function(){this.canceled=!0},clear:function(){this.$el&&(this.cancel(),this.$el.empty(),this.trigger("rendered",""))},isEmpty:function(){return this._isEmpty},destroy:function(){this.clearCachedSuggestions(),this.$el=null}}),t.exports=h},3354:(t,e,n)=>{"use strict";var i=n(2856),s=n(4910),r=n(3109),o=n(9050),a=n(1228);function u(t){var e,n,r,o=this;(t=t||{}).menu||i.error("menu is required"),i.isArray(t.datasets)||i.isObject(t.datasets)||i.error("1 or more datasets required"),t.datasets||i.error("datasets is required"),this.isOpen=!1,this.isEmpty=!0,this.minLength=t.minLength||0,this.templates={},this.appendTo=t.appendTo||!1,this.css=i.mixin({},a,t.appendTo?a.appendTo:{}),this.cssClasses=t.cssClasses=i.mixin({},a.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||i.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),e=i.bind(this._onSuggestionClick,this),n=i.bind(this._onSuggestionMouseEnter,this),r=i.bind(this._onSuggestionMouseLeave,this);var c=i.className(this.cssClasses.prefix,this.cssClasses.suggestion);this.$menu=s.element(t.menu).on("mouseenter.aa",c,n).on("mouseleave.aa",c,r).on("click.aa",c,e),this.$container=t.appendTo?t.wrapper:this.$menu,t.templates&&t.templates.header&&(this.templates.header=i.templatify(t.templates.header),this.$menu.prepend(this.templates.header())),t.templates&&t.templates.empty&&(this.templates.empty=i.templatify(t.templates.empty),this.$empty=s.element(''),this.$menu.append(this.$empty),this.$empty.hide()),this.datasets=i.map(t.datasets,(function(e){return function(t,e,n){return new u.Dataset(i.mixin({$menu:t,cssClasses:n},e))}(o.$menu,e,t.cssClasses)})),i.each(this.datasets,(function(t){var e=t.getRoot();e&&0===e.parent().length&&o.$menu.append(e),t.onSync("rendered",o._onRendered,o)})),t.templates&&t.templates.footer&&(this.templates.footer=i.templatify(t.templates.footer),this.$menu.append(this.templates.footer()));var l=this;s.element(window).resize((function(){l._redraw()}))}i.mixin(u.prototype,r,{_onSuggestionClick:function(t){this.trigger("suggestionClicked",s.element(t.currentTarget))},_onSuggestionMouseEnter:function(t){var e=s.element(t.currentTarget);if(!e.hasClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0))){this._removeCursor();var n=this;setTimeout((function(){n._setCursor(e,!1)}),0)}},_onSuggestionMouseLeave:function(t){if(t.relatedTarget&&s.element(t.relatedTarget).closest("."+i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).length>0)return;this._removeCursor(),this.trigger("cursorRemoved")},_onRendered:function(t,e){if(this.isEmpty=i.every(this.datasets,(function(t){return t.isEmpty()})),this.isEmpty)if(e.length>=this.minLength&&this.trigger("empty"),this.$empty)if(e.length126){if(d>=55296&&d<=56319&&h
{"use strict";var i,s,r,o=[n(5525),n(4785),n(8291),n(2709),n(2506),n(9176)],a=-1,u=[],c=!1;function l(){i&&s&&(i=!1,s.length?u=s.concat(u):a=-1,u.length&&h())}function h(){if(!i){c=!1,i=!0;for(var t=u.length,e=setTimeout(l);t;){for(s=u,u=[];s&&++a Your Docusaurus site did not load properly. A very common reason is a wrong site baseUrl configuration. Current configured baseUrl = ${e} ${"/"===e?" (default value)":""} We suggest trying baseUrl = You now need to set the data structure in the keeper to store the wallet to name pair. Keeper's are where the data is stored for future use. Update the msg_server logic to set the name upon request from a user. and also for the query_server to retrieve the name. It seems the nameservice will let you set any name length you want. Add a validation check in The If a user attempts to submit a name longer than 32 characters, it will return an error that is not allowed. Currently the nameservice only allows you to resolve a name given a wallet. If someone has a name they should be able to resolve the wallet address. Add a new query to the This challenge is signinicantly harder and will some previous Go programming knowledge with iterators. You can also just copy the solutions. Create a new query.proto for ResolveWallet that takes in a name string Iterate through the This is not the most efficient way to do this. If you would like, create a new WalletMapping collection that maps name->sender when Add the AutoCLI method to Then Using the Cosmos-SDKs AutoCLI, you will easily set up the CLI client for transactions and queries. Update the autocli to allow someone to get the name of a wallet account. Also add interaction in You will build a new IBC contract with CosmWasm, enabling the same features we just built out in the IBC module. While this is a part 3 of the series, it can be done standalone as it requires a new chain. It is a similar concept to the previous parts 1 and 2, but with a smart contract focus instead of a chain. Build a new blockchain with CosmWasm enabled. CosmWasm has a template repository that is used to generate new contracts. A minimal contract will be built with the Open the contract in your code editor now to begin adding the application logic. It is useful to install code rust extensions like rust-analyzer and even better toml for an increased editing experience. This version of the CosmWasm template has some outdated versions. Update these in the Update your local environment with the dependencies. This Rust code defines the structure for a name service in a CosmWasm smart contract. It saves a map of all channels (outside chain connections) to a list of wallet address and their associated names. Now that the state is setup, focus on modeling the users interaction with the contract. Users should be able to set a name. This also requires an input for a "channel" since a contract could connect to multiple chains. It could be written in a way that a user could set it to all channels, but for simplicity, we will require a channel to be specified. Just as is set, a user should get the name with the same format: a channel and a wallet address. Then a new message type is added specifically for IBCExecution messages. This is the packet transfered over the network, between chains, and gives the ability to set a name elsewhere on its contract. The contract will call the IBCExecuteMsg when a user runs the ExecuteMsg.SendName function. This indirectly generates the packet and submits it for the user. Here are all the imports used in this. Replace your files top. Instantiate creates a new version of this contract that you control. Rather than being unimplemented, return a basic response saying it was Ok (successful) and add some extra logging metadata. The ExecuteMsg::SetName method is allowed to be interacted from anyone. Just like instantiate we return a new Ok response. This time an add_message function is added. This will generate the packet as the user interacts, performing a new action from a previous action. This uses the IbcMsg::SendPacket built in type to create it for the user. Notice the data field includes the IbcExecuteMsg::SetName we defined before. This is transferred to the other version of this contract on another chain and processed. If the packet is not picked up by a relayer service provider within a few minutes, the packet will become void and stop attempting execution on the other chain's contract. The users name is not set, but it is only useful if you can also get said data. Read from the The contract will receive a packet and must run logic to process it. This is called the Create a new file, Rust has a lib.rs file that is the entry point for the Rust library. All files that are used must be mentioned here to have access to them. Add the ack logic to the lib.rs so the application can use it. If a relayer or contract try to connect to an unlike protocol, the InvalidVersion error will be returned to the attempted actor. This contract only supports 1 protocol version across networks because it must speak the same "language". If you speak english while another person speaks spanish, your interactions are incompatible. Contracts are like this too. They verify their protocol version in a format like "ics-20" or "ns-1" first to make sure they can communicate. OrderedChannel is a type of flow control for network packets, or interactions. This tutorial uses unordered paths so any packet that times out or fails does not block future packets from going through. If a relayer tries to make this an ordered path, the contract returns this error to stop them from doing so. Create a new file Place the following in the ibc.rs file. Import all the types needed, set the IBC version to "ns-1" to stand for "nameservice-1", and add the basic validation logic for the contract. You must ensure contracts that try to talk together are verified to work together. This is that logic. The contract verifies data on an attempted open of a new connection. Ensure the contracts talk the same protocol language, and that all the validation basic logic is connect. Then when a channel is closed, clear the data from storage for it. It is very rare you would want to close a channel. When a successful connection is made, the contract saves a new blank wallet mapping to the channel's unique id. 'channel-0' is the first. All future connections are channel-1, channel-2, etc. This is the first step in the IBC process. The contract is now ready to receive packets once the handler logic is put in place on receive. ibc_packet_receive handles incoming packets from already connected networks. The packet is forwarded to this contract and processed in Sometimes after a failed acknowledgement the contract may want to rollback some data or make note of it for future reference. This contract is simple enough so no rollback or refunds are required. We just return a basic response to the user for both the ack or a timeout. Think of this similarly as a NoOp (no operation). The contract can now be compiled from its source into the .wasm file. This is the binary executable that will be uploaded to the chain. Make sure you are in the Get the RPC interaction addresses for each network from the local-interchain testnet API. Upload the contract source to both chains using the different RPC addresses. You can now create your contract from the source on each chain. The relayer must now connect the contracts together and create an IBC connection, link, between them. Use the Local-Interchain helper methods to connect the contracts across the chains. This command will take a second then show a bunch of logs. Verify the channels were created. Query either with the application binary of the relayer itself. If you see both a channel-0 and channel-1 in your logs, it was a success. If you only see channel-0 re-run the above relayer exec tx link command. Using the ExecuteMsg::SetName method, set a name. This will be transferred to chain 2 behind the scenes. Flushing the relayer will force it to auto pick up pending IBC packets and transfer them across. Not running this may take up to 30 seconds for the relayer to automatically pick it up. After the packet is sent over the network, processed, and acknowledged (something that can be done in less than 30 seconds), you can query the data on chain 2. You can also dump all the contract data out to get HEX and BASE64 encoded data for what the contract state storage looks like. You just build an IBC protocol using cosmwasm! It allowed you to set a name on another network entirely and securely with IBC. In this section, you will build on top of the Name Service tutorial to add cross chain functionality. This will allow you to sent a name from another network. You should already have a network, Make sure you do not have the previous testnet still running by stopping it with: You now use the nameservice module you built previously within this new IBC module. This will allow you to save the name mapping on the name service, making it available for both IBC and native chain interactions. You must now give the IBC module access to nameservice keeper. It needs this reference so that the logic and connections can be shared. This is done in the You can find the Now that the IBC module has access to the nameservice, you can add the logic to set a name received from another chain (called the counterparty). To implement, the Once found, remove the lines within and replace with the following return. This sets the name mapping from the sender to some data (the name) in the original nameservice module. This is for example to show cross module interaction / extension with IBC.
+You could just as easily write the NameMapping in the ibc keeper store as well. Pasting the following lines in your terminal will import helper functions to interact with the testnet.
+The source is publicly available on GitHub to review. It gives you the ability to interact with the testnet easily using special You are ready to connect the two chains with your IBC module protocol. The cosmos/relayer is already running between the 2 networks now. A Channel is a connection between two chains, like a highway. A port is a specific protocol (or logic) that can connect with itself on another chain.
+For example; transfer to transfer, nsibc to nsibc, but transfer to nsibc can not be done. The version is just extra information (metadata) about the connection. These values are found in the keys.go file as the module name. By default version is just the module name + "-1". Execute the command on the testnet to connect the two chains with the IBC module with the relayer. You just build an IBC module that interacts with your other nameservice module! It allowed you to set your name from a different network entirely and securely with IBC. Extend the template module and add how to store and interact with data. Specifically, you need to set and retrieve a name. Open the proto/nameservice/v1/tx.proto file
+ Find proto/nameservice/v1/query.proto
+ These .proto file templates will be converted into Golang source code for you to use. Build the Go source code using the command: make proto-gen expected output
+ You just crafted your first blockchain, module, and custom logic with Spawn. You have a fully functioning name service that allows users to set and retrieve their account names. Extend the NameService to include IBC support with the ibc-module tutorial. Congrats!! You built your first network already. You are ready to run a local testnet environment to verify it works. Use the The chain will begin to create (mint) new blocks. You can see the logs of the network running in the terminal. Using the newly built binary (rolld from the --bin flag when the chain was created), you are going to execute the Then, resolve this name with the nameservice lookup. Now you are going to get the name of a wallet. A nested command The expected result should be: When you are ready to stop the testnet, you can use Your network is now running and you have successfully set and resolved a name! 🎉 Building your first Cosmos-SDK blockchain with Spawn. This tutorial focuses on a 'nameservice' where you set your account to a name you choose. Let's create a new chain called 'rollchain'. You are going to set defining characteristics such as 🎉 Your new blockchain 'rollchain' is now generated! Now it is time to build the nameservice module structure. Move into the 'rollchain' directory and generate the new module with the following commands: This creates a new template module with the name You will build a new chain with CosmWasm, enabling support for smart contracts on a new Cosmos-SDK application. You will download a pre-built contract, upload it, and interact with it to transfer the ownership of some data. If you do not know what an NFT is, you can read about them here: investopedia.com/non-fungible-tokens-nft. Some parts of this tutorial will not have the added context about spawn's inner workings or how commands work. Run through Build Your Application for this context. Some machines like Windows will not work with running the testnet. This is a limitation of the operating system hardware with wasm and required C language libraries / DLLs. For the best experience, try Build a new chain that has CosmWasm configured. If you remove the If You will use the CW721 contract for your NFT journey. CW721 stands for CosmWasm 721. 721 corresponds to the Ethereum specification for NFTs. Understanding this is out of scope for this tutorial. Just know you can create, transfer, and query data. Download the contract code from the CosmWasm NFTs repository, then upload it to the network with the application binary. With the source now uploaded, anyone can create a new NFT collection with this base contract code now on the chain. This will be a new contract that only you control. Now, instantiate the contract to create the new NFT collection. You can find the instantiate, execute, and query messages (json) formats in the contract source code. Notice the MESSAGE= below has no spaces in the JSON. This is required for the command line to parse it correctly. Failure to do so will result in the error A contract address is where all the collection and information is stored. It never changes and is the unique identifier for interaction. Think of this similar to a website, google.com always brings you to google search. The acc0 account now must create the first NFT in the collection since it is the minter. Specify the unique ID (1), the owner (acc0), and some data to be associated with this NFT. Set the url of a sunflower image as the metadata for this tutorial. The There is now an NFT with the ID of 1 owned by Now move the token from the originally minted account (acc0) to another account (acc1). This is a simple transfer of ownership to move who owns the data. In this tutorial, you built a new chain with CosmWasm enabled, launched a testnet for it, and launched an NFT collection! You uploaded a contract, created an NFT, and transferred it to another account. This is the foundation for building a new unique marketplace or game on the Interchain. You will build a new chain with CosmWasm, enabling a proof-of-stake validator review system. You will write a contract to collect and manage validator reviews, integrate it with the chain, and update validator data automatically through a Cosmos-SDK endblocker module. There are easy ways to get validators in a cosmwasm smart contract. The goal of this tutorial is to teach how to pass data from the SDK to a contract.["'])(?
panic: reflect: New(nil)
",id:"running-the-binary-gives-me-panic-reflect-newnil",level:3}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"This section will contain common setup problems and how to resolve them."}),"\n",(0,i.jsx)(n.h2,{id:"golang",children:"Golang"}),"\n",(0,i.jsx)(n.h3,{id:"binsh-1-go-not-found",children:"/bin/sh: 1: go: not found"}),"\n",(0,i.jsxs)(n.p,{children:["Just add the following lines to ",(0,i.jsx)(n.code,{children:"~/.bashrc"})," (or ",(0,i.jsx)(n.code,{children:"~/.zshrc"})," if MacOs) and this will persist. ",(0,i.jsx)(n.a,{href:"https://stackoverflow.com/a/21012349",children:"Source"}),"\nIf you run the above in your terminal, it will apply to the current session but not on new terminal sessions."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"export GOPATH=$HOME/go\nexport PATH=$PATH:$GOROOT/bin:$GOPATH/bin\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then apply it with ",(0,i.jsx)(n.code,{children:"source ~/.bashrc"})," or ",(0,i.jsx)(n.code,{children:"source ~/.zshrc"})]}),"\n",(0,i.jsx)(n.h3,{id:"build-constraints-excluded-all-go-files-in-usrlocalgo-",children:"build constraints excluded all Go files in /usr/local/go/ ..."}),"\n",(0,i.jsxs)(n.p,{children:["Your Go install is not properly setup. Follow the install instructions above or install directly from source with ",(0,i.jsx)(n.a,{href:"https://go.dev/doc/install",children:"go.dev"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"make-heighliner-permission-denied",children:"make: heighliner: Permission denied"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"make get-heighliner\nchmod +x $(which heighliner)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the above does not work, your user or directory permissions may not be setup. Or your ",(0,i.jsx)(n.code,{children:"ls -la $(go env GOPATH)/bin"})," path is to a bad."]}),"\n",(0,i.jsxs)(n.p,{children:["If using WSL, try ",(0,i.jsx)(n.a,{href:"https://superuser.com/questions/1352207/windows-wsl-ubuntu-sees-wrong-permissions-on-files-in-mounted-disk",children:"https://superuser.com/questions/1352207/windows-wsl-ubuntu-sees-wrong-permissions-on-files-in-mounted-disk"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"windows--wsl",children:"Windows / WSL"}),"\n",(0,i.jsx)(n.h3,{id:"make-mntcprogram-no-such-file-or-directory",children:"make: /mnt/c/Program: No such file or directory"}),"\n",(0,i.jsxs)(n.p,{children:["Delete your GOMODCACHE directory: ",(0,i.jsx)(n.code,{children:"go clean -modcache"})," or run the direct command ",(0,i.jsx)(n.code,{children:"rm -rf $(go env GOMODCACHE)"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"docker",children:"Docker"}),"\n",(0,i.jsx)(n.h3,{id:"cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running",children:"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?."}),"\n",(0,i.jsxs)(n.p,{children:["Start the docker daemon. Run ",(0,i.jsx)(n.a,{href:"https://docs.docker.com/engine/",children:"docker engine"})," or ",(0,i.jsx)(n.code,{children:"systemctl start docker && systemctl enable docker"})," for Linux."]}),"\n",(0,i.jsx)(n.h3,{id:"docker-got-permission-denied-while-trying-to-connect-to-the-docker-daemon-socket-at-unixvarrundockersock",children:"docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock"}),"\n",(0,i.jsx)(n.p,{children:"You don't have permissions to interact with the Docker daemon."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Install properly with ",(0,i.jsx)(n.a,{href:"https://docs.docker.com/get-started/get-docker/",children:"https://docs.docker.com/get-started/get-docker/"})]}),"\n"]}),"\n",(0,i.jsx)(n.li,{}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo groupadd docker\nsudo usermod -aG docker $USER\nnewgrp docker\n\nreboot # if you still get the error\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Technically you can also ",(0,i.jsx)(n.code,{children:"sudo chmod 666 /var/run/docker.sock"})," but this is NOT advised. --\x3e"]}),"\n",(0,i.jsx)(n.h2,{id:"generation",children:"Generation"}),"\n",(0,i.jsx)(n.h3,{id:"remote-repository-not-found-fatal-reposity-not-found",children:"remote: Repository not found. fatal: reposity not found"}),"\n",(0,i.jsxs)(n.p,{children:["This error is due to not having properly ",(0,i.jsx)(n.code,{children:"make proto-gen"}),"ed the project. View the ",(0,i.jsx)(n.a,{href:"#running-the-binary-gives-me-panic-reflect-newnil",children:"Application"})," section for the solution."]}),"\n",(0,i.jsx)(n.h2,{id:"application",children:"Application"}),"\n",(0,i.jsxs)(n.h3,{id:"running-the-binary-gives-me-panic-reflect-newnil",children:["Running the binary gives me ",(0,i.jsx)(n.code,{children:"panic: reflect: New(nil)"})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"make proto-gen"})," command was either not run, or is causing issues. This could be due to your users permissions or the filesystem. By default, the protoc docker image uses your current users id and group. Try switching as a super user (i.e. ",(0,i.jsx)(n.code,{children:"su -"}),") or fixing your permissions. A very ugly hack is to run ",(0,i.jsx)(n.code,{children:"chmod a+rwx -R ./rollchain"})," where ",(0,i.jsx)(n.code,{children:"./rollchain"})," is the project you generated. This will cause git to change all files, but it does fix it. Unsure of the long term side effects that may come up from this."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>c,a:()=>t});var i=o(7294);const r={},s=i.createContext(r);function t(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/cf8bc188.f2af40ce.js b/assets/js/cf8bc188.f2af40ce.js
new file mode 100644
index 00000000..f7869e5c
--- /dev/null
+++ b/assets/js/cf8bc188.f2af40ce.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[308],{4273:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var s=n(5893),a=n(1151);const o={title:"CW NFTs",sidebar_label:"CosmWasm NFTs",slug:"/demo/cw-nft"},r="Non-fungible Token Demo",i={id:"demos/cw-nft-demo",title:"CW NFTs",description:"You will build a new chain with CosmWasm, enabling support for smart contracts on a new Cosmos-SDK application. You will download a pre-built contract, upload it, and interact with it to transfer the ownership of some data.",source:"@site/versioned_docs/version-v0.50.x/03-demos/02-cw-nft-demo.md",sourceDirName:"03-demos",slug:"/demo/cw-nft",permalink:"/spawn/v0.50/demo/cw-nft",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:2,frontMatter:{title:"CW NFTs",sidebar_label:"CosmWasm NFTs",slug:"/demo/cw-nft"},sidebar:"defaultSidebar",previous:{title:"IBC Transfers",permalink:"/spawn/v0.50/demo/ibc"},next:{title:"Token Factory",permalink:"/spawn/v0.50/demo/tokenfactory"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Create your chain",id:"create-your-chain",level:2},{value:"Start the testnet",id:"start-the-testnet",level:2},{value:"Verify CosmWasm is enabled",id:"verify-cosmwasm-is-enabled",level:2},{value:"Upload the contract to the network",id:"upload-the-contract-to-the-network",level:2},{value:"Verify the code was uploaded",id:"verify-the-code-was-uploaded",level:2},{value:"Create a new NFT collection",id:"create-a-new-nft-collection",level:2},{value:"Contract address",id:"contract-address",level:2},{value:"Create an NFT in the collection",id:"create-an-nft-in-the-collection",level:2},{value:"Grab this NFT data",id:"grab-this-nft-data",level:2},{value:"Transfer the NFT to another account",id:"transfer-the-nft-to-another-account",level:2},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components},{Details:n}=t;return n||function(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"non-fungible-token-demo",children:"Non-fungible Token Demo"}),"\n",(0,s.jsxs)(t.p,{children:["You will build a new chain with ",(0,s.jsx)(t.a,{href:"https://cosmwasm.com/",children:"CosmWasm"}),", enabling support for smart contracts on a new Cosmos-SDK application. You will download a pre-built contract, upload it, and interact with it to transfer the ownership of some data."]}),"\n",(0,s.jsxs)(t.p,{children:["If you do not know what an NFT is, you can read about them here: ",(0,s.jsx)(t.a,{href:"https://www.investopedia.com/non-fungible-tokens-nft-5115211",children:"investopedia.com/non-fungible-tokens-nft"}),"."]}),"\n",(0,s.jsx)(t.admonition,{title:"Warning",type:"note",children:(0,s.jsxs)(t.p,{children:["Some parts of this tutorial will not have the added context about spawn's inner workings or how commands work. Run through ",(0,s.jsx)(t.a,{href:"/spawn/v0.50/build/name-service",children:"Build Your Application"})," for this context."]})}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/spawn/v0.50/install/system-setup",children:"System Setup"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/spawn/v0.50/install/install-spawn",children:"Install Spawn"})}),"\n"]}),"\n",(0,s.jsxs)(t.admonition,{title:"Danger",type:"note",children:[(0,s.jsx)(t.p,{children:"Some machines like Windows will not work with running the testnet. This is a limitation of the operating system hardware with wasm and required C language libraries / DLLs."}),(0,s.jsxs)(t.p,{children:["For the best experience, try ",(0,s.jsx)(t.code,{children:"make testnet"})," or use a Linux machine or a cloud-based linux instance from ",(0,s.jsx)(t.a,{href:"https://www.hetzner.com/cloud/",children:"Hetzner"})," or ",(0,s.jsx)(t.a,{href:"https://www.digitalocean.com/pricing/droplets",children:"Digital Ocean"})," for $6 per month."]})]}),"\n",(0,s.jsx)(t.h2,{id:"create-your-chain",children:"Create your chain"}),"\n",(0,s.jsx)(t.p,{children:"Build a new chain that has CosmWasm configured."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"GITHUB_USERNAME=rollchains\n\nspawn new rollchain \\\n--consensus=proof-of-stake \\\n--bech32=roll \\\n--denom=uroll \\\n--bin=rolld \\\n--disabled=block-explorer \\\n--org=${GITHUB_USERNAME}\n"})}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"View UI Selector"}),(0,s.jsxs)(t.p,{children:["If you remove the ",(0,s.jsx)(t.code,{children:"--disabled"})," flag; a more intuitive UI selection approach will be taken. Make sure CosmWasm is selected with the green arrow, then press ",(0,s.jsx)(t.code,{children:"done"}),"."]}),(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{src:"https://github.com/user-attachments/assets/16698f3f-143b-4258-9ff2-fc429764b58c",alt:"Image"})})]}),"\n",(0,s.jsx)(t.h2,{id:"start-the-testnet",children:"Start the testnet"}),"\n",(0,s.jsx)(t.admonition,{title:"Note",type:"note",children:(0,s.jsxs)(t.p,{children:["If ",(0,s.jsx)(t.code,{children:"make sh-testnet"})," does not start due to a port bind error, you can kill your previously running testnet with ",(0,s.jsx)(t.code,{children:"killall -9 rolld"}),", then try again."]})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# move into the chain directory\ncd rollchain\n\n# - Installs the binary\n# - Setups the default keys with funds\n# - Starts the chain in your shell\nmake sh-testnet\n"})}),"\n",(0,s.jsx)(t.h2,{id:"verify-cosmwasm-is-enabled",children:"Verify CosmWasm is enabled"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"rolld q wasm params\n"})}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Expected Output"}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"code_upload_access:\n addresses: []\n permission: Everybody\n instantiate_default_permission: Everybody\n"})})]}),"\n",(0,s.jsx)(t.h2,{id:"upload-the-contract-to-the-network",children:"Upload the contract to the network"}),"\n",(0,s.jsxs)(t.p,{children:["You will use the ",(0,s.jsx)(t.a,{href:"https://github.com/public-awesome/cw-nfts",children:"CW721"})," contract for your NFT journey. CW721 stands for CosmWasm 721. ",(0,s.jsx)(t.a,{href:"https://www.coinbase.com/learn/crypto-glossary/what-is-erc-721",children:"721 corresponds to the Ethereum specification for NFTs"}),". Understanding this is out of scope for this tutorial. Just know you can create, transfer, and query data."]}),"\n",(0,s.jsx)(t.p,{children:"Download the contract code from the CosmWasm NFTs repository, then upload it to the network with the application binary."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# Download the the NFT contract to your machine\ncurl -LO https://github.com/public-awesome/cw-nfts/releases/download/v0.19.0/cw721_base.wasm\n\n# Upload the source code to the chain\n# - gas is is amount of compute resources to allocate.\nrolld tx wasm store ./cw721_base.wasm --from=acc0 \\\n --gas=auto --gas-adjustment=2.0 --yes\n"})}),"\n",(0,s.jsx)(t.h2,{id:"verify-the-code-was-uploaded",children:"Verify the code was uploaded"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'# Code id: "1" is available\nrolld q wasm list-code\n\n# See the details (A lot of spam)\nrolld q tx 4601FBACBDF93E4309D92E968F8B4E7F9177BCB132B65AA363AFDC26FE6B5CB6\n'})}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Expected Code Info"}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'(main) -> $ rolld q wasm list-code\ncode_infos:\n- code_id: "1"\n creator: roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87\n data_hash: E13AA30E0D70EA895B294AD1BC809950E60FE081B322B1657F75B67BE6021B1C\n instantiate_permission:\n addresses: []\n permission: Everybody\npagination:\n next_key: null\n total: "0"\n'})})]}),"\n",(0,s.jsx)(t.h2,{id:"create-a-new-nft-collection",children:"Create a new NFT collection"}),"\n",(0,s.jsx)(t.p,{children:"With the source now uploaded, anyone can create a new NFT collection with this base contract code now on the chain. This will be a new contract that only you control. Now, instantiate the contract to create the new NFT collection."}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Instantiate Format Source"}),(0,s.jsx)(t.p,{children:"You can find the instantiate, execute, and query messages (json) formats in the contract source code."}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",metastring:'reference title="packages/cw721/src/msg.rs"',children:"https://github.com/public-awesome/cw-nfts/blob/v0.19.0/packages/cw721/src/msg.rs#L126-L143\n"})})]}),"\n",(0,s.jsxs)(t.admonition,{title:"Warning",type:"note",children:[(0,s.jsx)(t.p,{children:"Notice the MESSAGE= below has no spaces in the JSON. This is required for the command line to parse it correctly. Failure to do so will result in the error"}),(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:'ERR failure when running app err="accepts 2 arg(s), received 3"'})})]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'# Get our account address for the acc0 wallet / key.\nrolld keys show acc0 -a # roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87\n\n# Create the NFT collection with our account\n# as the authorized minter / creator for new NFTs.\nMESSAGE=\'{"name":"Roll","symbol":"ROLL","minter":"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87"}\'\n\n# Create the NFT collection\nrolld tx wasm instantiate 1 $MESSAGE --no-admin --from=acc0 --label="my-nft" \\\n --gas=auto --gas-adjustment=2.0 --yes\n'})}),"\n",(0,s.jsx)(t.h2,{id:"contract-address",children:"Contract address"}),"\n",(0,s.jsxs)(t.p,{children:["A contract address is where all the collection and information is stored. It never changes and is the unique identifier for interaction. Think of this similar to a website, google.com always brings you to google search. ",(0,s.jsx)(t.code,{children:"NFT_CONTRACT"})," is always the RollNFTs collection."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# View all contract addresses a wallet has created\nrolld q wasm list-contracts-by-creator roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87\n\n# The contract address for the NFT collection just created\nNFT_CONTRACT=roll14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjczpjh\n"})}),"\n",(0,s.jsx)(t.h2,{id:"create-an-nft-in-the-collection",children:"Create an NFT in the collection"}),"\n",(0,s.jsx)(t.p,{children:"The acc0 account now must create the first NFT in the collection since it is the minter. Specify the unique ID (1), the owner (acc0), and some data to be associated with this NFT. Set the url of a sunflower image as the metadata for this tutorial."}),"\n",(0,s.jsx)(t.admonition,{title:"Note",type:"note",children:(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"token_uri"})," is a URL that points to the metadata of the NFT. This can be a ",(0,s.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-721#specification",children:"JSON object"})," or a URL to a JSON object.\nThis URL can be a link to an external service like ",(0,s.jsx)(t.a,{href:"https://ipfs.tech/",children:"IPFS"}),", or the raw text directly. The contract does not care, it is up to you to manage the data and build the services around it."]})}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Execute Format Source"}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",metastring:'reference title="packages/cw721/src/msg.rs"',children:"https://github.com/public-awesome/cw-nfts/blob/v0.19.0/packages/cw721/src/msg.rs#L80-L91\n"})})]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'MESSAGE=\'{"mint":{"token_id":"1","owner":"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87","token_uri":"https://onlinejpgtools.com/images/examples-onlinejpgtools/sunflower.jpg"}}\'\n\nrolld tx wasm execute $NFT_CONTRACT $MESSAGE --from=acc0 \\\n --gas=auto --gas-adjustment=2.0 --yes\n'})}),"\n",(0,s.jsx)(t.h2,{id:"grab-this-nft-data",children:"Grab this NFT data"}),"\n",(0,s.jsxs)(t.p,{children:["There is now an NFT with the ID of 1 owned by ",(0,s.jsx)(t.code,{children:"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87"}),". Now query the contract to see the data and verify it is correct."]}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Query Format Source"}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",metastring:'reference title="packages/cw721/src/msg.rs"',children:"https://github.com/public-awesome/cw-nfts/blob/v0.19.0/packages/cw721/src/msg.rs#L157-L161\n"})}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",metastring:'reference title="packages/cw721/src/msg.rs"',children:"https://github.com/public-awesome/cw-nfts/blob/v0.19.0/packages/cw721/src/msg.rs#L236-L240\n"})})]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'# Get who is the owner of ID 1\nrolld q wasm state smart $NFT_CONTRACT \'{"owner_of":{"token_id":"1"}}\'\n\n# Retrieve the NFT info\nrolld q wasm state smart $NFT_CONTRACT \'{"nft_info":{"token_id":"1"}}\'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"transfer-the-nft-to-another-account",children:"Transfer the NFT to another account"}),"\n",(0,s.jsx)(t.p,{children:"Now move the token from the originally minted account (acc0) to another account (acc1). This is a simple transfer of ownership to move who owns the data."}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Execute Format Source"}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",metastring:'reference title="packages/cw721/src/msg.rs"',children:"https://github.com/public-awesome/cw-nfts/blob/v0.19.0/packages/cw721/src/msg.rs#L44-L48\n"})})]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'# Recipient account\nrolld keys show acc1 -a # roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh\n\nMESSAGE=\'{"transfer_nft":{"recipient":"roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh","token_id":"1"}}\'\nrolld tx wasm execute $NFT_CONTRACT $MESSAGE --from=acc0 --gas=auto --gas-adjustment=2.0 --yes\n\n# Get who is the owner of 1\n# Moved to: roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh\nrolld q wasm state smart $NFT_CONTRACT \'{"owner_of":{"token_id":"1"}}\'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,s.jsx)(t.p,{children:"In this tutorial, you built a new chain with CosmWasm enabled, launched a testnet for it, and launched an NFT collection! You uploaded a contract, created an NFT, and transferred it to another account. This is the foundation for building a new unique marketplace or game on the Interchain."})]})}function h(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>r});var s=n(7294);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/def0e9a3.c113600b.js b/assets/js/def0e9a3.c113600b.js
new file mode 100644
index 00000000..561bc480
--- /dev/null
+++ b/assets/js/def0e9a3.c113600b.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[104],{2776:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var s=t(5893),i=t(1151);const r={title:"Name Service",sidebar_label:"Testnet",sidebar_position:5,slug:"/build/name-service-testnet"},a="Running your Application",o={id:"build-your-application/testnet",title:"Name Service",description:"Congrats!! You built your first network already. You are ready to run a local testnet environment to verify it works.",source:"@site/versioned_docs/version-v0.50.x/02-build-your-application/05-testnet.md",sourceDirName:"02-build-your-application",slug:"/build/name-service-testnet",permalink:"/spawn/v0.50/build/name-service-testnet",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:5,frontMatter:{title:"Name Service",sidebar_label:"Testnet",sidebar_position:5,slug:"/build/name-service-testnet"},sidebar:"defaultSidebar",previous:{title:"Configure Client",permalink:"/spawn/v0.50/build/name-service-client"},next:{title:"Bonus",permalink:"/spawn/v0.50/build/name-service-bonus"}},l={},c=[{value:"Launch The Network",id:"launch-the-network",level:3},{value:"Interact Set Name",id:"interact-set-name",level:3},{value:"Interaction Get Name",id:"interaction-get-name",level:2}];function d(e){const n={admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"running-your-application",children:"Running your Application"}),"\n",(0,s.jsxs)(n.admonition,{title:"Synopsis",type:"note",children:[(0,s.jsx)(n.p,{children:"Congrats!! You built your first network already. You are ready to run a local testnet environment to verify it works."}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Building your application executable"}),"\n",(0,s.jsx)(n.li,{children:"Running a local testnet"}),"\n",(0,s.jsx)(n.li,{children:"Interacting with the network"}),"\n"]})]}),"\n",(0,s.jsx)(n.h3,{id:"launch-the-network",children:"Launch The Network"}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"sh-testnet"})," command ",(0,s.jsx)(n.em,{children:"(short for shell testnet)"})," to quickly build your application, generate example wallet accounts, and start the local network on your machine."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Run a quick shell testnet\nmake sh-testnet\n"})}),"\n",(0,s.jsx)(n.p,{children:"The chain will begin to create (mint) new blocks. You can see the logs of the network running in the terminal."}),"\n",(0,s.jsx)(n.h3,{id:"interact-set-name",children:"Interact Set Name"}),"\n",(0,s.jsxs)(n.p,{children:["Using the newly built binary ",(0,s.jsx)(n.em,{children:"(rolld from the --bin flag when the chain was created)"}),", you are going to execute the ",(0,s.jsx)(n.code,{children:"set"}),' transaction to your name. In this example, use "alice". This links account ',(0,s.jsx)(n.code,{children:"acc1"})," address to the desired name in the keeper."]}),"\n",(0,s.jsxs)(n.p,{children:["Then, resolve this name with the nameservice lookup. ",(0,s.jsx)(n.code,{children:"$(rolld keys show acc1 -a)"})," is a substitute for the acc1's address. You can also use just ",(0,s.jsx)(n.code,{children:"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87"})," here."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rolld tx nameservice set alice --from=acc1 --yes\n\n# You can verify this transaction was successful\n# By querying it's unique ID.\nrolld q tx 565CE77057ACBF6FB5D174231455E61E65009CD628971937C19201328E0A1FFD\n"})}),"\n",(0,s.jsx)(n.h2,{id:"interaction-get-name",children:"Interaction Get Name"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are going to get the name of a wallet. A nested command ",(0,s.jsx)(n.code,{children:"$(rolld keys show acc1 -a)"})," gets the unique address of the acc1 account added when you started the testnet."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rolld q nameservice resolve roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh --output=json\n\nrolld q nameservice resolve $(rolld keys show acc1 -a) --output=json\n"})}),"\n",(0,s.jsx)(n.p,{children:"The expected result should be:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "name": "alice"\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["When you are ready to stop the testnet, you can use ",(0,s.jsx)(n.code,{children:"ctrl + c"})," or ",(0,s.jsx)(n.code,{children:"killall -9 rolld"}),"."]})}),"\n",(0,s.jsx)(n.p,{children:"Your network is now running and you have successfully set and resolved a name! \ud83c\udf89"})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>a});var s=t(7294);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/e3e7a55f.f0fb7f96.js b/assets/js/e3e7a55f.f0fb7f96.js
new file mode 100644
index 00000000..1c085472
--- /dev/null
+++ b/assets/js/e3e7a55f.f0fb7f96.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[838],{8839:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var s=t(5893),l=t(1151);const i={title:"Setup Development Environment",sidebar_label:"System Setup",sidebar_position:1,slug:"/install/system-setup"},o="Overview",a={id:"setup/system-setup",title:"Setup Development Environment",description:"Setup your development environment with the essentials to get started building the blockchain.",source:"@site/versioned_docs/version-v0.50.x/01-setup/01-system-setup.md",sourceDirName:"01-setup",slug:"/install/system-setup",permalink:"/spawn/v0.50/install/system-setup",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:1,frontMatter:{title:"Setup Development Environment",sidebar_label:"System Setup",sidebar_position:1,slug:"/install/system-setup"},sidebar:"defaultSidebar",previous:{title:"Spawn Documentation",permalink:"/spawn/v0.50/"},next:{title:"Install Spawn",permalink:"/spawn/v0.50/install/install-spawn"}},r={},c=[{value:"System Requirements",id:"system-requirements",level:2},{value:"Windows",id:"windows",level:2},{value:"MacOS",id:"macos",level:2},{value:"Linux (Ubuntu)",id:"linux-ubuntu",level:2},{value:"CosmWasm",id:"cosmwasm",level:2}];function u(n){const e={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.a)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.h1,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(e.admonition,{title:"Synopsis",type:"note",children:(0,s.jsx)(e.p,{children:"Setup your development environment with the essentials to get started building the blockchain."})}),"\n",(0,s.jsx)(e.h2,{id:"system-requirements",children:"System Requirements"}),"\n",(0,s.jsx)(e.p,{children:"Before you can install and interact with spawn, you must have the following core tools installed:"}),"\n",(0,s.jsxs)(e.ul,{children:["\n",(0,s.jsx)(e.li,{children:(0,s.jsx)(e.a,{href:"https://go.dev/doc/install",children:(0,s.jsx)(e.code,{children:"Go 1.22+"})})}),"\n",(0,s.jsx)(e.li,{children:(0,s.jsx)(e.a,{href:"https://docs.docker.com/get-docker/",children:(0,s.jsx)(e.code,{children:"Docker"})})}),"\n",(0,s.jsx)(e.li,{children:(0,s.jsx)(e.a,{href:"https://git-scm.com/",children:(0,s.jsx)(e.code,{children:"Git"})})}),"\n"]}),"\n",(0,s.jsx)(e.p,{children:"If you do not have these components installed, follow the instructions below to install them."}),"\n",(0,s.jsx)(e.h2,{id:"windows",children:"Windows"}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-bash",children:'# Install WSL in powershell\nwsl --install\nRestart-Computer\n\n# Setup WSL Ubuntu Image\nwsl.exe --install Ubuntu-24.04\n\n# Open wsl instance\nwsl\n\n# update and add snap if not already installed\nsudo apt update && sudo apt install snapd\n\n# Install Go (Snap)\nsudo snap install go --channel=1.23/stable --classic\n\n# Install Base\nsudo apt install make gcc git jq wget\n\n# Install github-cli\nsudo snap install gh\n\n# Install docker\nhttps://docs.docker.com/desktop/wsl/#turn-on-docker-desktop-wsl-2\n# or snap:\nsudo snap install docker\n\n# Fix versioning for interaction of commands\nsudo chmod 666 /var/run/docker.sock\n\n# Setup base git config\ngit config --global user.email "yourEmail@gmail.com"\ngit config --global user.name "Your Name"\n'})}),"\n",(0,s.jsx)(e.h2,{id:"macos",children:"MacOS"}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-bash",children:'# Base\nbrew install make\nbrew install gcc\nbrew install wget\nbrew install jq\n\n# Github CLI - https://github.com/cli/cli\nbrew install gh\ngh auth login\n\n# Golang\nbrew install go\n\n# Docker\nbrew install --cask docker\nopen -a Docker # start docker desktop\n# settings -> General -> Start Docker Desktop when you sign in to your computer\n# Apply & Restart\n\n# Setup base git config\ngit config --global user.email "yourEmail@gmail.com"\ngit config --global user.name "Your Name"\n'})}),"\n",(0,s.jsx)(e.h2,{id:"linux-ubuntu",children:"Linux (Ubuntu)"}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-bash",children:'# Base\nsudo apt install make gcc git jq wget\n\n# (optional) Github CLI - https://github.com/cli/cli\ncurl -sS https://webi.sh/gh | sh\ngh auth login\n\n# Golang\nGO_VERSION=1.23.0\nwget https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz\nsudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go$GO_VERSION.linux-amd64.tar.gz\n\n# Docker\nsudo apt -y install docker.io\n\n# Setup base git config\ngit config --global user.email "yourEmail@gmail.com"\ngit config --global user.name "Your Name"\n'})}),"\n",(0,s.jsx)(e.h2,{id:"cosmwasm",children:"CosmWasm"}),"\n",(0,s.jsxs)(e.p,{children:["Some tutorials require CosmWasm (Rust smart contracts) setup. This section is option, unless a tutorial is CosmWasm focused.\nCosmWasm requires ",(0,s.jsx)(e.a,{href:"https://www.rust-lang.org/",children:"Rust"}),". You must have this installed as the contract will be built locally."]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-bash",children:"# Install rust - https://www.rust-lang.org/tools/install\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n\n# or Update if you have it\nrustup update\n\n# Install other dependencies\nrustup target add wasm32-unknown-unknown\n\ncargo install cargo-generate --features vendored-openssl\ncargo install cargo-run-script\n"})})]})}function d(n={}){const{wrapper:e}={...(0,l.a)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(u,{...n})}):u(n)}},1151:(n,e,t)=>{t.d(e,{Z:()=>a,a:()=>o});var s=t(7294);const l={},i=s.createContext(l);function o(n){const e=s.useContext(i);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function a(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(l):n.components||l:o(n.components),s.createElement(i.Provider,{value:e},n.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/ecd46386.28d9a771.js b/assets/js/ecd46386.28d9a771.js
new file mode 100644
index 00000000..08dec192
--- /dev/null
+++ b/assets/js/ecd46386.28d9a771.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[602],{5294:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var s=n(5893),r=n(1151);const o={title:"Name Service",sidebar_label:"Set Structure",sidebar_position:2,slug:"/build/name-service-structure"},a="Set Data Structure",i={id:"build-your-application/proto-logic",title:"Name Service",description:"Extend the template module and add how to store and interact with data. Specifically, you need to set and retrieve a name.",source:"@site/versioned_docs/version-v0.50.x/02-build-your-application/02-proto-logic.md",sourceDirName:"02-build-your-application",slug:"/build/name-service-structure",permalink:"/spawn/v0.50/build/name-service-structure",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:2,frontMatter:{title:"Name Service",sidebar_label:"Set Structure",sidebar_position:2,slug:"/build/name-service-structure"},sidebar:"defaultSidebar",previous:{title:"Build a Name Service",permalink:"/spawn/v0.50/build/name-service"},next:{title:"Application Logic",permalink:"/spawn/v0.50/build/name-service-application"}},c={},l=[{value:"Set Name",id:"set-name",level:3},{value:"Get Name",id:"get-name",level:3},{value:"Generate Code",id:"generate-code",level:2}];function d(e){const t={code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,r.a)(),...e.components},{Details:n}=t;return n||function(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"set-data-structure",children:"Set Data Structure"}),"\n",(0,s.jsx)(t.p,{children:"Extend the template module and add how to store and interact with data. Specifically, you need to set and retrieve a name."}),"\n",(0,s.jsx)(t.h3,{id:"set-name",children:"Set Name"}),"\n",(0,s.jsxs)(t.p,{children:["Open the ",(0,s.jsx)(t.code,{children:"proto/nameservice/v1"})," directory. Edit ",(0,s.jsx)(t.code,{children:"tx.proto"})," to add the transaction setter message."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-protobuf",metastring:'title="proto/nameservice/v1/tx.proto"',children:'\n // SetServiceName allows a user to set their accounts name.\n rpc SetServiceName(MsgSetServiceName) returns (MsgSetServiceNameResponse);\n}\n\n// MsgSetServiceName defines the structure for setting a name.\nmessage MsgSetServiceName {\n option (cosmos.msg.v1.signer) = "sender";\n\n string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];\n\n string name = 2;\n}\n\n// MsgSetServiceNameResponse is an empty reply.\nmessage MsgSetServiceNameResponse {}\n'})}),"\n",(0,s.jsx)(n,{children:(0,s.jsxs)(t.p,{children:["proto/nameservice/v1/tx.proto file\n",(0,s.jsx)(t.img,{src:"https://github.com/rollchains/spawn/assets/31943163/73a583e2-9edd-471f-ada6-1010d0dbf072",alt:"proto/nameservice/v1/tx.proto file"})]})}),"\n",(0,s.jsx)(t.h3,{id:"get-name",children:"Get Name"}),"\n",(0,s.jsxs)(t.p,{children:["Find ",(0,s.jsx)(t.code,{children:"query.proto"})," and add the following"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-protobuf",metastring:'title="proto/nameservice/v1/query.proto"',children:'\n // ResolveName allows a user to resolve the name of an account.\n rpc ResolveName(QueryResolveNameRequest) returns (QueryResolveNameResponse) {\n option (google.api.http).get = "/nameservice/v1/name/{wallet}";\n }\n}\n\n// QueryResolveNameRequest grabs the name of a wallet.\nmessage QueryResolveNameRequest {\n string wallet = 1;\n}\n\n// QueryResolveNameResponse grabs the wallet linked to a name.\nmessage QueryResolveNameResponse {\n string name = 1;\n}\n'})}),"\n",(0,s.jsx)(n,{children:(0,s.jsxs)(t.p,{children:["proto/nameservice/v1/query.proto\n",(0,s.jsx)(t.img,{src:"https://github.com/rollchains/spawn/assets/31943163/234a13d7-be62-492d-961c-63e92d7543d9",alt:"proto/nameservice/v1/query.proto file"})]})}),"\n",(0,s.jsx)(t.h2,{id:"generate-code",children:"Generate Code"}),"\n",(0,s.jsx)(t.p,{children:"These .proto file templates will be converted into Golang source code for you to use. Build the Go source code using the command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make proto-gen\n"})}),"\n",(0,s.jsx)(n,{children:(0,s.jsxs)(t.p,{children:["make proto-gen expected output\n",(0,s.jsx)(t.img,{src:"https://github.com/rollchains/spawn/assets/31943163/c51bf57c-e83a-4004-8041-9b1f3d3a24f4",alt:"make proto-gen"})]})})]})}function u(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>a});var s=n(7294);const r={},o=s.createContext(r);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/f5a87c92.e92da417.js b/assets/js/f5a87c92.e92da417.js
new file mode 100644
index 00000000..f2abeade
--- /dev/null
+++ b/assets/js/f5a87c92.e92da417.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[273],{6384:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var a=t(5893),o=t(1151);const s={title:"Token Factory",sidebar_label:"Token Factory",slug:"/demo/tokenfactory"},r="Tokenfactory",i={id:"demos/tokenfactory",title:"Token Factory",description:"You will build a new chain with TokenFactory, enabling any account to create, transfer, and interact with fractionalized native tokens.",source:"@site/versioned_docs/version-v0.50.x/03-demos/03-tokenfactory.md",sourceDirName:"03-demos",slug:"/demo/tokenfactory",permalink:"/spawn/v0.50/demo/tokenfactory",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:3,frontMatter:{title:"Token Factory",sidebar_label:"Token Factory",slug:"/demo/tokenfactory"},sidebar:"defaultSidebar",previous:{title:"CosmWasm NFTs",permalink:"/spawn/v0.50/demo/cw-nft"},next:{title:"CosmWasm Validator Reviews",permalink:"/spawn/v0.50/demo/cw-validator-reviews"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Create your chain",id:"create-your-chain",level:2},{value:"Start the testnet",id:"start-the-testnet",level:2},{value:"Confirm tokenfactory is enabled",id:"confirm-tokenfactory-is-enabled",level:2},{value:"Create a token",id:"create-a-token",level:2},{value:"Verify the token was created",id:"verify-the-token-was-created",level:2},{value:"Modify token metadata",id:"modify-token-metadata",level:2},{value:"Verify the token metadata",id:"verify-the-token-metadata",level:2},{value:"Create new tokens to transfer",id:"create-new-tokens-to-transfer",level:2},{value:"Create new tokens for another account",id:"create-new-tokens-for-another-account",level:2},{value:"Transfer tokens",id:"transfer-tokens",level:2},{value:"Burn tokens",id:"burn-tokens",level:2},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"tokenfactory",children:"Tokenfactory"}),"\n",(0,a.jsxs)(n.p,{children:["You will build a new chain with ",(0,a.jsx)(n.a,{href:"https://github.com/strangelove-ventures/tokenfactory",children:"TokenFactory"}),", enabling any account to create, transfer, and interact with fractionalized native tokens."]}),"\n",(0,a.jsx)(n.admonition,{title:"Warning",type:"note",children:(0,a.jsxs)(n.p,{children:["Some parts of this tutorial will not have the added context about spawn's inner workings or how commands work. Run through ",(0,a.jsx)(n.a,{href:"/spawn/v0.50/build/name-service",children:"Build Your Application"})," for this context."]})}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/spawn/v0.50/install/system-setup",children:"System Setup"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/spawn/v0.50/install/install-spawn",children:"Install Spawn"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"create-your-chain",children:"Create your chain"}),"\n",(0,a.jsx)(n.p,{children:"Build a new chain that has TokenFactory configured. By default, it is enabled."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"GITHUB_USERNAME=rollchains\n\nspawn new rollchain \\\n--consensus=proof-of-stake \\\n--bech32=roll \\\n--denom=uroll \\\n--bin=rolld \\\n--disabled=cosmwasm,block-explorer \\\n--org=${GITHUB_USERNAME}\n"})}),"\n",(0,a.jsx)(n.h2,{id:"start-the-testnet",children:"Start the testnet"}),"\n",(0,a.jsx)(n.admonition,{title:"Note",type:"note",children:(0,a.jsxs)(n.p,{children:["If ",(0,a.jsx)(n.code,{children:"make sh-testnet"})," does not start due to a port bind error, you can kill your previously running testnet with ",(0,a.jsx)(n.code,{children:"killall -9 rolld"}),", then try again."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# move into the chain directory\ncd rollchain\n\n# - Installs the binary\n# - Setups the default keys with funds\n# - Starts the chain in your shell\nmake sh-testnet\n"})}),"\n",(0,a.jsx)(n.h2,{id:"confirm-tokenfactory-is-enabled",children:"Confirm tokenfactory is enabled"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rolld q tokenfactory params\n"})}),"\n",(0,a.jsxs)(t,{children:[(0,a.jsx)("summary",{children:"params output"}),(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"denom_creation_fee"})," is a cost the application can set for creating new tokens by default, there is no cost."]}),(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"denom_creation_gas_consume"})," is the amount of indirect resource cost to consume for creating a new token.\nIt is a more indirect approach to charging and is a better experience overall for developers on a network."]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'params:\n denom_creation_fee: []\n denom_creation_gas_consume: "100000"\n'})})]}),"\n",(0,a.jsx)(n.h2,{id:"create-a-token",children:"Create a token"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Create a denom (native token)\n# - gas is is amount of compute resources to allocate.\nrolld tx tokenfactory create-denom mytoken --from=acc0 --chain-id=localchain-1 --yes\n"})}),"\n",(0,a.jsx)(n.h2,{id:"verify-the-token-was-created",children:"Verify the token was created"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Get our account address for the acc0 wallet / key.\n# acc0 is roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87\nrolld q tokenfactory denoms-from-creator $(rolld keys show acc0 -a)\n"})}),"\n",(0,a.jsxs)(t,{children:[(0,a.jsx)("summary",{children:"denoms-from-creator output"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"denoms:\n- factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n"})})]}),"\n",(0,a.jsxs)(n.p,{children:["The output shows a denom with the named ",(0,a.jsx)(n.code,{children:"factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken"})]}),"\n",(0,a.jsxs)(n.admonition,{title:"Note",type:"note",children:[(0,a.jsx)(n.p,{children:"Why did it add extra data to the token?"}),(0,a.jsxs)(n.p,{children:["Imagine there are 2 people, both named John. If only the name John is used, which John is it talking about? More information must be added to the name to make it unique. This is the same concept, but with tokens. The extra data is added to ensure the token is unique while it can still contain the same base name. With tokenfactory, the creators name is placed in the token. Read more about ",(0,a.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Naming_collision",children:"naming collisions"}),"."]})]}),"\n",(0,a.jsx)(n.h2,{id:"modify-token-metadata",children:"Modify token metadata"}),"\n",(0,a.jsx)(n.p,{children:"Clients (websites, frontends, users) may wish to see more information about the token. This is where metadata comes in. You can add a ticker symbol, description, and decimal places to the token."}),"\n",(0,a.jsxs)(n.p,{children:["The Interchain uses 6 decimal places as the default standard. This process of expressing fractions of a value in whole numbers is called ",(0,a.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Fixed-point_arithmetic",children:"fixed-point arithmetic"})," and is used for financial precision. This means that 1 token is really 1,000,000 (10^6) of these micro base tokens. If I want to send you 0.5 of a token, I really send you 500,000 of these micro base tokens on the backend."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# \'Denom\' is short for denomination.\nDENOM=factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\nDESCRIPTION="My token description"\n\nrolld tx tokenfactory modify-metadata $DENOM MYTOKEN "$DESCRIPTION" 6 --from acc0 --yes\n'})}),"\n",(0,a.jsx)(n.h2,{id:"verify-the-token-metadata",children:"Verify the token metadata"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rolld q bank denom-metadata $DENOM\n"})}),"\n",(0,a.jsxs)(t,{children:[(0,a.jsx)("summary",{children:"bank denom-metadata output"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"metadata:\n base: factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n denom_units:\n - aliases:\n - MYTOKEN\n denom: factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n - aliases:\n - factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n denom: MYTOKEN\n exponent: 6\n description: My token description\n display: MYTOKEN\n name: factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n symbol: MYTOKEN\n"})})]}),"\n",(0,a.jsx)(n.h2,{id:"create-new-tokens-to-transfer",children:"Create new tokens to transfer"}),"\n",(0,a.jsx)(n.p,{children:"The base token structure is created, but no tokens actually exists yet. Mint new tokens to then be able to transfer them between accounts."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Mint 5,000,000 micro mytoken. By default this goes to the token creator.\nrolld tx tokenfactory mint 5000000$DENOM --from acc0 --yes\n\n# Verify token creator balance: roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87\nrolld q bank balances $(rolld keys show acc0 -a)\n"})}),"\n",(0,a.jsxs)(t,{children:[(0,a.jsx)("summary",{children:"bank balances output"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'balances:\n- amount: "5000000"\n denom: factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n- amount: "900"\n denom: test\n- amount: "9000000"\n denom: uroll\npagination:\n total: "3"\n'})})]}),"\n",(0,a.jsx)(n.h2,{id:"create-new-tokens-for-another-account",children:"Create new tokens for another account"}),"\n",(0,a.jsxs)(n.p,{children:["While you could mint tokens followed by a manual ",(0,a.jsx)(n.code,{children:"tx bank send"})," transfer, you can also mint-to another account directly."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Mint 1,000,000 to another account\nrolld tx tokenfactory mint-to $(rolld keys show acc1 -a) 1000000$DENOM --from acc0 --yes\n\nrolld q bank balances $(rolld keys show acc1 -a)\n"})}),"\n",(0,a.jsxs)(t,{children:[(0,a.jsx)("summary",{children:"mint-to output"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'balances:\n- amount: "1000000"\n denom: factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n- amount: "800"\n denom: test\n- amount: "10000000"\n denom: uroll\npagination:\n total: "3"\n'})}),(0,a.jsx)(n.p,{children:"note, you can check for just a specific token balance with"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rolld q bank balance $(rolld keys show acc0 -a) $DENOM\n"})}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'balance:\n amount: "5000000"\n denom: factory/roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87/mytoken\n'})})]}),"\n",(0,a.jsx)(n.h2,{id:"transfer-tokens",children:"Transfer tokens"}),"\n",(0,a.jsx)(n.p,{children:"Now with tokens minted, either user can transfer them as they please between any accounts. Even ones that do not yet have any tokens."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Send 7 base micro tokens from acc0 to acc1\nrolld tx bank send acc0 $(rolld keys show acc1 -a) 7$DENOM --from acc0 --yes\n\n# Verify the 7 base tokens sent and has increased to 1000007, or 1.000007\nrolld q bank balances $(rolld keys show acc1 -a)\n"})}),"\n",(0,a.jsx)(n.h2,{id:"burn-tokens",children:"Burn tokens"}),"\n",(0,a.jsx)(n.p,{children:"If you wish to remove tokens from the system, you can burn them from the admin account."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Burn micro tokens from account\nrolld tx tokenfactory burn 123$DENOM --from acc0 --yes\n\n# Verify the tokens have been reduced\nrolld q bank balances $(rolld keys show acc0 -a)\n"})}),"\n",(0,a.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial, you built a new chain with the TokenFactory feature, launched a testnet for it, and created a new native token. You minted tokens, transferred them between accounts, and burned them. These tokens could be kept internally for some personal or application based accounting, or transferred to other chains via IBC. This is showcased in the ",(0,a.jsx)(n.a,{href:"/spawn/v0.50/demo/ibc",children:"IBC Transfer Demo"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>r});var a=t(7294);const o={},s=a.createContext(o);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/f873aaa2.e3b9fb4d.js b/assets/js/f873aaa2.e3b9fb4d.js
new file mode 100644
index 00000000..b116fc11
--- /dev/null
+++ b/assets/js/f873aaa2.e3b9fb4d.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[447],{7834:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var t=i(5893),s=i(1151);const a={title:"Name Service",sidebar_label:"Summary",sidebar_position:7,slug:"/build/name-service-summary"},r="Conclusion",o={id:"build-your-application/conclusion",title:"Name Service",description:"You just crafted your first blockchain, module, and custom logic with Spawn. You have a fully functioning name service that allows users to set and retrieve their account names.",source:"@site/versioned_docs/version-v0.50.x/02-build-your-application/07-conclusion.md",sourceDirName:"02-build-your-application",slug:"/build/name-service-summary",permalink:"/spawn/v0.50/build/name-service-summary",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:7,frontMatter:{title:"Name Service",sidebar_label:"Summary",sidebar_position:7,slug:"/build/name-service-summary"},sidebar:"defaultSidebar",previous:{title:"Bonus",permalink:"/spawn/v0.50/build/name-service-bonus"},next:{title:"IBC NameService (Part 2)",permalink:"/spawn/v0.50/build/name-service-ibc-module"}},l={},c=[{value:"What you Learned",id:"what-you-learned",level:2},{value:"What's Next?",id:"whats-next",level:2}];function u(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"conclusion",children:"Conclusion"}),"\n",(0,t.jsx)(n.p,{children:"You just crafted your first blockchain, module, and custom logic with Spawn. You have a fully functioning name service that allows users to set and retrieve their account names."}),"\n",(0,t.jsx)(n.h2,{id:"what-you-learned",children:"What you Learned"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generating a new chain with your desired characteristics"}),"\n",(0,t.jsx)(n.li,{children:"Scaffolding a module"}),"\n",(0,t.jsx)(n.li,{children:"Setting the protobuf structure for transactions, queries, and Storage"}),"\n",(0,t.jsx)(n.li,{children:"Adding custom business logic to a module's server handlers"}),"\n",(0,t.jsx)(n.li,{children:"Configuring the command line client"}),"\n",(0,t.jsx)(n.li,{children:"Running a local testnet"}),"\n",(0,t.jsx)(n.li,{children:"Interacting with the network"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.p,{children:["Extend the NameService to include IBC support with the ",(0,t.jsx)(n.a,{href:"/spawn/v0.50/build/name-service-ibc-module",children:"ibc-module"})," tutorial."]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>o,a:()=>r});var t=i(7294);const s={},a=t.createContext(s);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/f8891bd3.ae69a959.js b/assets/js/f8891bd3.ae69a959.js
new file mode 100644
index 00000000..283d516e
--- /dev/null
+++ b/assets/js/f8891bd3.ae69a959.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[294],{6859:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>t,contentTitle:()=>l,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=i(5893),o=i(1151);const s={title:"Name Service",sidebar_label:"Build a Name Service",sidebar_position:1,slug:"/build/name-service"},l="Overview",a={id:"build-your-application/nameservice",title:"Name Service",description:"Building your first Cosmos-SDK blockchain with Spawn. This tutorial focuses on a 'nameservice' where you set your account to a name you choose.",source:"@site/versioned_docs/version-v0.50.x/02-build-your-application/01-nameservice.md",sourceDirName:"02-build-your-application",slug:"/build/name-service",permalink:"/spawn/v0.50/build/name-service",draft:!1,unlisted:!1,tags:[],version:"v0.50.x",sidebarPosition:1,frontMatter:{title:"Name Service",sidebar_label:"Build a Name Service",sidebar_position:1,slug:"/build/name-service"},sidebar:"defaultSidebar",previous:{title:"Debugging",permalink:"/spawn/v0.50/install/debugging"},next:{title:"Set Structure",permalink:"/spawn/v0.50/build/name-service-structure"}},t={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Generate a New Chain",id:"generate-a-new-chain",level:2},{value:"Scaffold the Module",id:"scaffold-the-module",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.admonition,{title:"Synopsis",type:"note",children:[(0,r.jsx)(n.p,{children:"Building your first Cosmos-SDK blockchain with Spawn. This tutorial focuses on a 'nameservice' where you set your account to a name you choose."}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Generating a new chain"}),"\n",(0,r.jsx)(n.li,{children:"Creating a new module"}),"\n",(0,r.jsx)(n.li,{children:"Adding custom logic"}),"\n",(0,r.jsx)(n.li,{children:"Run locally"}),"\n",(0,r.jsx)(n.li,{children:"Interacting with the network"}),"\n"]})]}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/spawn/v0.50/install/system-setup",children:"System Setup"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/spawn/v0.50/install/install-spawn",children:"Install Spawn"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,r.jsx)("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/4gFSuLUlP4I?si=A_VqEwhOh2ZPxNsb",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen",referrerpolicy:"strict-origin-when-cross-origin",allowfullscreen:!0}),"\n",(0,r.jsx)(n.h2,{id:"generate-a-new-chain",children:"Generate a New Chain"}),"\n",(0,r.jsx)(n.p,{children:"Let's create a new chain called 'rollchain'. You are going to set defining characteristics such as"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Which modules to disable from the template ",(0,r.jsx)(n.em,{children:"if any"})]}),"\n",(0,r.jsx)(n.li,{children:"Proof of Stake consensus"}),"\n",(0,r.jsx)(n.li,{children:"Wallet prefix (bech32)"}),"\n",(0,r.jsx)(n.li,{children:"Token name (denom)"}),"\n",(0,r.jsx)(n.li,{children:"Binary executable (bin)"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"spawn new rollchain --consensus=pos --disable=cosmwasm --bech32=roll --denom=uroll --bin=rolld\n"})}),"\n",(0,r.jsx)(n.p,{children:"\ud83c\udf89 Your new blockchain 'rollchain' is now generated!"}),"\n",(0,r.jsx)(n.h2,{id:"scaffold-the-module",children:"Scaffold the Module"}),"\n",(0,r.jsx)(n.p,{children:"Now it is time to build the nameservice module structure."}),"\n",(0,r.jsx)(n.p,{children:"Move into the 'rollchain' directory and generate the new module with the following commands:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# moves into the rollchain directory you just generated\ncd rollchain\n\n# scaffolds your new nameservice module\nspawn module new nameservice\n\n# proto-gen proto files to go\n#\n# If you get a /.cache permission error, run:\n# sudo chmod -R 777 $(pwd)/.cache\n# sudo chown -R $USER $(pwd)/.cache\n#\n# If you get a cannot find module error\n# go clean -modcache\n#\n\nmake proto-gen\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This creates a new template module with the name ",(0,r.jsx)(n.code,{children:"nameservice"})," in the ",(0,r.jsx)(n.code,{children:"x"})," and ",(0,r.jsx)(n.code,{children:"proto"})," directories. It also automatically connected to your application and is ready for use."]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>a,a:()=>l});var r=i(7294);const o={},s=r.createContext(o);function l(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:l(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/main.698d1b94.js b/assets/js/main.698d1b94.js
new file mode 100644
index 00000000..978ccfb8
--- /dev/null
+++ b/assets/js/main.698d1b94.js
@@ -0,0 +1,2 @@
+/*! For license information please see main.698d1b94.js.LICENSE.txt */
+(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[179],{1728:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t\n \n`}(e)).replace(/{let{route:t}=e;return!0===t.exact})))return N.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return N.set(e.pathname,t),{...e,pathname:t}}((0,d.TH)());return(0,p.jsx)(F,{location:e,children:W})}function G(){return(0,p.jsx)(Q.Z,{children:(0,p.jsx)(P.M,{children:(0,p.jsxs)(L.t,{children:[(0,p.jsxs)(h,{children:[(0,p.jsx)(H,{}),(0,p.jsx)(T,{}),(0,p.jsx)(U,{}),(0,p.jsx)(q,{})]}),(0,p.jsx)(V,{})]})})})}var Y=n(6887);const K=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var X=n(9670);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,f.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(Y).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,X.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),R(e))},re=Object.freeze(ne);function ae(e){let{children:t}=e;return"hash"===s.default.future.experimental_router?(0,p.jsx)(i.UT,{children:t}):(0,p.jsx)(i.VK,{children:t})}const oe=Boolean(!0);if(l.Z.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(o.B6,{children:(0,p.jsx)(ae,{children:(0,p.jsx)(G,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(oe)window.docusaurusRoot=a.hydrateRoot(e,t,{onRecoverableError:n});else{const r=a.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};R(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>f});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/spawn/","versions":[{"name":"current","label":"Next","isLast":false,"path":"/spawn/main","mainDocId":"intro","docs":[{"id":"intro","path":"/spawn/main/","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/spawn/main/","label":"intro"}}}},{"name":"v0.50.x","label":"v0.50.x","isLast":true,"path":"/spawn/v0.50","mainDocId":"meet-spawn","docs":[{"id":"build-your-application/application-logic","path":"/spawn/v0.50/build/name-service-application","sidebar":"defaultSidebar"},{"id":"build-your-application/cli","path":"/spawn/v0.50/build/name-service-client","sidebar":"defaultSidebar"},{"id":"build-your-application/conclusion","path":"/spawn/v0.50/build/name-service-summary","sidebar":"defaultSidebar"},{"id":"build-your-application/extra-challenge","path":"/spawn/v0.50/build/name-service-bonus","sidebar":"defaultSidebar"},{"id":"build-your-application/ibc-cosmwasm","path":"/spawn/v0.50/build/name-service-ibc-contract","sidebar":"defaultSidebar"},{"id":"build-your-application/ibc-module","path":"/spawn/v0.50/build/name-service-ibc-module","sidebar":"defaultSidebar"},{"id":"build-your-application/nameservice","path":"/spawn/v0.50/build/name-service","sidebar":"defaultSidebar"},{"id":"build-your-application/proto-logic","path":"/spawn/v0.50/build/name-service-structure","sidebar":"defaultSidebar"},{"id":"build-your-application/testnet","path":"/spawn/v0.50/build/name-service-testnet","sidebar":"defaultSidebar"},{"id":"demos/cw-nft-demo","path":"/spawn/v0.50/demo/cw-nft","sidebar":"defaultSidebar"},{"id":"demos/cw-validator-reviews","path":"/spawn/v0.50/demo/cw-validator-reviews","sidebar":"defaultSidebar"},{"id":"demos/ibc-transfer-demo","path":"/spawn/v0.50/demo/ibc","sidebar":"defaultSidebar"},{"id":"demos/tokenfactory","path":"/spawn/v0.50/demo/tokenfactory","sidebar":"defaultSidebar"},{"id":"learn/consensus-algos","path":"/spawn/v0.50/learn/consensus-security","sidebar":"defaultSidebar"},{"id":"meet-spawn","path":"/spawn/v0.50/","sidebar":"defaultSidebar"},{"id":"setup/debugging","path":"/spawn/v0.50/install/debugging","sidebar":"defaultSidebar"},{"id":"setup/install-spawn","path":"/spawn/v0.50/install/install-spawn","sidebar":"defaultSidebar"},{"id":"setup/system-setup","path":"/spawn/v0.50/install/system-setup","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/spawn/v0.50/","label":"Spawn Documentation"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"3.4.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.4.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.4.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.4.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.4.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.4.0"},"docusaurus-feedback-plugin":{"type":"package","name":"docusaurus-pushfeedback","version":"1.0.0"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.4.0"},"@gracefullight/docusaurus-plugin-microsoft-clarity":{"type":"package","name":"@gracefullight/docusaurus-plugin-microsoft-clarity","version":"1.0.0"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.40.1"},"docusaurus-tailwindcss":{"type":"local"},"docusaurus-theme-github-codeblock":{"type":"package"}}}');var u=n(5893);const c={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=r.createContext(c);function f(e){let{children:t}=e;return(0,u.jsx)(d.Provider,{value:c,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(7294),a=n(412),o=n(5742),i=n(8780),s=n(8862),l=n(226),u=n(5893);function c(e){let{error:t,tryAgain:n}=e;return(0,u.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,u.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,u.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,u.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function f(e){let{children:t}=e;return(0,u.jsx)(l.z,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function p(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)(f,{children:(0,u.jsxs)(g,{fallback:()=>(0,u.jsx)(c,{error:t,tryAgain:n}),children:[(0,u.jsx)(o.Z,{children:(0,u.jsx)("title",{children:"Page Error"})}),(0,u.jsx)(s.Z,{children:(0,u.jsx)(c,{error:t,tryAgain:n})})]})})}const h=e=>(0,u.jsx)(p,{...e});class g extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??h)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);var r=n(405),a=n(5893);function o(e){return(0,a.jsx)(r.ql,{...e})}},3692:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(3727),o=n(8780),i=n(2263),s=n(3919),l=n(412),u=n(8138),c=n(4996),d=n(5893);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:h,isActive:g,"data-noBrokenLinkCheck":m,autoAddBaseUrl:y=!0,...v}=e;const{siteConfig:b}=(0,i.default)(),{trailingSlash:w,baseUrl:x}=b,k=b.future.experimental_router,{withBaseUrl:S}=(0,c.Cg)(),E=(0,u.Z)(),_=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>_.current));const C=f||p;const T=(0,s.Z)(C),N=C?.replace("pathname://","");let L=void 0!==N?(P=N,y&&(e=>e.startsWith("/"))(P)?S(P):P):void 0;var P;"hash"===k&&L?.startsWith("./")&&(L=L?.slice(1)),L&&T&&(L=(0,o.applyTrailingSlash)(L,{trailingSlash:w,baseUrl:x}));const O=(0,r.useRef)(!1),A=n?a.OL:a.rU,I=l.Z.canUseIntersectionObserver,R=(0,r.useRef)(),j=()=>{O.current||null==L||(window.docusaurus.preload(L),O.current=!0)};(0,r.useEffect)((()=>(!I&&T&&null!=L&&window.docusaurus.prefetch(L),()=>{I&&R.current&&R.current.disconnect()})),[R,L,I,T]);const F=L?.startsWith("#")??!1,D=!v.target||"_self"===v.target,M=!L||!T||!D;return m||!F&&M||E.collectLink(L),v.id&&E.collectAnchor(v.id),M?(0,d.jsx)("a",{ref:_,href:L,...C&&!T&&{target:"_blank",rel:"noopener noreferrer"},...v}):(0,d.jsx)(A,{...v,onMouseEnter:j,onTouchStart:j,innerRef:e=>{_.current=e,I&&e&&T&&(R.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(R.current.unobserve(e),R.current.disconnect(),null!=L&&window.docusaurus.prefetch(L))}))})),R.current.observe(e))},to:L,...n&&{isActive:g,activeClassName:h}})}const p=r.forwardRef(f)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u,I:()=>l});var r=n(7294),a=n(5893);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(7529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(s({message:n,id:r}),t)}function u(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal '};function a(e,t,n){return e/g,(function(){return n})).replace(/*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/
+
+
+
\ No newline at end of file
diff --git a/main/search-index.json b/main/search-index.json
new file mode 100644
index 00000000..419c0a6a
--- /dev/null
+++ b/main/search-index.json
@@ -0,0 +1 @@
+[{"documents":[{"i":1,"t":"Unreleased Docs Here","u":"/spawn/main/","b":[]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,0.288,1,0.288,2,0.288]]],"invertedIndex":[["doc",{"_index":1,"t":{"1":{"position":[[11,4]]}}}],["here",{"_index":2,"t":{"1":{"position":[[16,4]]}}}],["unreleas",{"_index":0,"t":{"1":{"position":[[0,10]]}}}]],"pipeline":["stemmer"]}},{"documents":[],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[],"invertedIndex":[],"pipeline":["stemmer"]}},{"documents":[],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[],"invertedIndex":[],"pipeline":["stemmer"]}}]
\ No newline at end of file
diff --git a/search-index.json b/search-index.json
new file mode 100644
index 00000000..2fc0bf7f
--- /dev/null
+++ b/search-index.json
@@ -0,0 +1 @@
+[{"documents":[{"i":2,"t":"Command Line Client","u":"/spawn/v0.50/build/name-service-client/","b":["Build Your Application"]},{"i":8,"t":"Meet Spawn","u":"/spawn/v0.50/","b":[]},{"i":48,"t":"Save Storage Structure","u":"/spawn/v0.50/build/name-service-application/","b":["Build Your Application"]},{"i":52,"t":"Extra Challenges","u":"/spawn/v0.50/build/name-service-bonus/","b":["Build Your Application"]},{"i":57,"t":"Running your Application","u":"/spawn/v0.50/build/name-service-testnet/","b":["Build Your Application"]},{"i":65,"t":"IBC Name Service Module","u":"/spawn/v0.50/build/name-service-ibc-module/","b":["Build Your Application"]},{"i":91,"t":"Conclusion","u":"/spawn/v0.50/build/name-service-summary/","b":["Build Your Application"]},{"i":97,"t":"Overview","u":"/spawn/v0.50/build/name-service/","b":["Build Your Application"]},{"i":106,"t":"Set Data Structure","u":"/spawn/v0.50/build/name-service-structure/","b":["Build Your Application"]},{"i":114,"t":"IBC Demo","u":"/spawn/v0.50/demo/ibc/","b":["Application Demos"]},{"i":130,"t":"Tokenfactory","u":"/spawn/v0.50/demo/tokenfactory/","b":["Application Demos"]},{"i":158,"t":"Non-fungible Token Demo","u":"/spawn/v0.50/demo/cw-nft/","b":["Application Demos"]},{"i":184,"t":"Debugging","u":"/spawn/v0.50/install/debugging/","b":["Installation"]},{"i":207,"t":"Overview","u":"/spawn/v0.50/install/install-spawn/","b":["Installation"]},{"i":211,"t":"Network Security Types","u":"/spawn/v0.50/learn/consensus-security/","b":["Learn"]},{"i":241,"t":"Overview","u":"/spawn/v0.50/install/system-setup/","b":["Installation"]},{"i":253,"t":"IBC Name Service Contract","u":"/spawn/v0.50/build/name-service-ibc-contract/","b":["Build Your Application"]},{"i":295,"t":"CosmWasm Validator Reviews","u":"/spawn/v0.50/demo/cw-validator-reviews/","b":["Application Demos"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/2",[0,2.247,1,2.247,2,2.247]],["t/8",[3,2.672,4,2.672]],["t/48",[5,2.247,6,2.247,7,1.795]],["t/52",[8,2.672,9,2.672]],["t/57",[10,2.672,11,2.672]],["t/65",[12,1.292,13,1.549,14,1.549,15,1.939]],["t/91",[16,3.295]],["t/97",[17,2.196]],["t/106",[7,1.795,18,2.247,19,2.247]],["t/114",[12,1.781,20,2.135]],["t/130",[21,3.295]],["t/158",[20,1.549,22,1.939,23,1.939,24,1.939]],["t/184",[25,3.295]],["t/207",[17,2.196]],["t/211",[26,2.247,27,2.247,28,2.247]],["t/241",[17,2.196]],["t/253",[12,1.292,13,1.549,14,1.549,29,1.939]],["t/295",[30,2.247,31,2.247,32,2.247]]],"invertedIndex":[["applic",{"_index":11,"t":{"57":{"position":[[13,11]]}}}],["challeng",{"_index":9,"t":{"52":{"position":[[6,10]]}}}],["client",{"_index":2,"t":{"2":{"position":[[13,6]]}}}],["command",{"_index":0,"t":{"2":{"position":[[0,7]]}}}],["conclus",{"_index":16,"t":{"91":{"position":[[0,10]]}}}],["contract",{"_index":29,"t":{"253":{"position":[[17,8]]}}}],["cosmwasm",{"_index":30,"t":{"295":{"position":[[0,8]]}}}],["data",{"_index":19,"t":{"106":{"position":[[4,4]]}}}],["debug",{"_index":25,"t":{"184":{"position":[[0,9]]}}}],["demo",{"_index":20,"t":{"114":{"position":[[4,4]]},"158":{"position":[[19,4]]}}}],["extra",{"_index":8,"t":{"52":{"position":[[0,5]]}}}],["fungibl",{"_index":23,"t":{"158":{"position":[[4,8]]}}}],["ibc",{"_index":12,"t":{"65":{"position":[[0,3]]},"114":{"position":[[0,3]]},"253":{"position":[[0,3]]}}}],["line",{"_index":1,"t":{"2":{"position":[[8,4]]}}}],["meet",{"_index":3,"t":{"8":{"position":[[0,4]]}}}],["modul",{"_index":15,"t":{"65":{"position":[[17,6]]}}}],["name",{"_index":13,"t":{"65":{"position":[[4,4]]},"253":{"position":[[4,4]]}}}],["network",{"_index":26,"t":{"211":{"position":[[0,7]]}}}],["non",{"_index":22,"t":{"158":{"position":[[0,3]]}}}],["overview",{"_index":17,"t":{"97":{"position":[[0,8]]},"207":{"position":[[0,8]]},"241":{"position":[[0,8]]}}}],["review",{"_index":32,"t":{"295":{"position":[[19,7]]}}}],["run",{"_index":10,"t":{"57":{"position":[[0,7]]}}}],["save",{"_index":5,"t":{"48":{"position":[[0,4]]}}}],["secur",{"_index":27,"t":{"211":{"position":[[8,8]]}}}],["servic",{"_index":14,"t":{"65":{"position":[[9,7]]},"253":{"position":[[9,7]]}}}],["set",{"_index":18,"t":{"106":{"position":[[0,3]]}}}],["spawn",{"_index":4,"t":{"8":{"position":[[5,5]]}}}],["storag",{"_index":6,"t":{"48":{"position":[[5,7]]}}}],["structur",{"_index":7,"t":{"48":{"position":[[13,9]]},"106":{"position":[[9,9]]}}}],["token",{"_index":24,"t":{"158":{"position":[[13,5]]}}}],["tokenfactori",{"_index":21,"t":{"130":{"position":[[0,12]]}}}],["type",{"_index":28,"t":{"211":{"position":[[17,5]]}}}],["valid",{"_index":31,"t":{"295":{"position":[[9,9]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":4,"t":"Query","u":"/spawn/v0.50/build/name-service-client/","h":"/spawn/v0.50/build/name-service-client/#query","p":2},{"i":6,"t":"Transaction","u":"/spawn/v0.50/build/name-service-client/","h":"/spawn/v0.50/build/name-service-client/#transaction","p":2},{"i":10,"t":"NameService Demo","u":"/spawn/v0.50/","h":"/spawn/v0.50/#nameservice-demo","p":8},{"i":12,"t":"Testimonials","u":"/spawn/v0.50/","h":"/spawn/v0.50/#testimonials","p":8},{"i":14,"t":"Spawn Overview","u":"/spawn/v0.50/","h":"/spawn/v0.50/#spawn-overview","p":8},{"i":16,"t":"New Development","u":"/spawn/v0.50/","h":"/spawn/v0.50/#new-development","p":8},{"i":18,"t":"Security Selection","u":"/spawn/v0.50/","h":"/spawn/v0.50/#security-selection","p":8},{"i":20,"t":"Feature Selection","u":"/spawn/v0.50/","h":"/spawn/v0.50/#feature-selection","p":8},{"i":22,"t":"Structure","u":"/spawn/v0.50/","h":"/spawn/v0.50/#structure","p":8},{"i":24,"t":".github/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#github","p":8},{"i":26,"t":"app/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#app","p":8},{"i":28,"t":"chains/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#chains","p":8},{"i":30,"t":"cmd/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#cmd","p":8},{"i":32,"t":"explorer/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#explorer","p":8},{"i":34,"t":"interchaintest/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#interchaintest","p":8},{"i":36,"t":"proto/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#proto","p":8},{"i":38,"t":"scripts/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#scripts","p":8},{"i":40,"t":"chain_metadata.json","u":"/spawn/v0.50/","h":"/spawn/v0.50/#chain_metadatajson","p":8},{"i":42,"t":"chain_registry.json & assets","u":"/spawn/v0.50/","h":"/spawn/v0.50/#chain_registryjson--assets","p":8},{"i":44,"t":"Modules","u":"/spawn/v0.50/","h":"/spawn/v0.50/#modules","p":8},{"i":46,"t":"Testnets","u":"/spawn/v0.50/","h":"/spawn/v0.50/#testnets","p":8},{"i":50,"t":"Application Logic","u":"/spawn/v0.50/build/name-service-application/","h":"/spawn/v0.50/build/name-service-application/#application-logic","p":48},{"i":53,"t":"Challenge 1: Limit Input","u":"/spawn/v0.50/build/name-service-bonus/","h":"/spawn/v0.50/build/name-service-bonus/#challenge-1-limit-input","p":52},{"i":55,"t":"Challenge 2: Resolve Wallet From Name","u":"/spawn/v0.50/build/name-service-bonus/","h":"/spawn/v0.50/build/name-service-bonus/#challenge-2-resolve-wallet-from-name","p":52},{"i":59,"t":"Launch The Network","u":"/spawn/v0.50/build/name-service-testnet/","h":"/spawn/v0.50/build/name-service-testnet/#launch-the-network","p":57},{"i":61,"t":"Interact Set Name","u":"/spawn/v0.50/build/name-service-testnet/","h":"/spawn/v0.50/build/name-service-testnet/#interact-set-name","p":57},{"i":63,"t":"Interaction Get Name","u":"/spawn/v0.50/build/name-service-testnet/","h":"/spawn/v0.50/build/name-service-testnet/#interaction-get-name","p":57},{"i":67,"t":"Prerequisites","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#prerequisites","p":65},{"i":69,"t":"Create your chain","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#create-your-chain","p":65},{"i":71,"t":"Scaffold the IBC Module","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#scaffold-the-ibc-module","p":65},{"i":73,"t":"Use the NameService Module","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#use-the-nameservice-module","p":65},{"i":75,"t":"Provide NameService to the IBC Module","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#provide-nameservice-to-the-ibc-module","p":65},{"i":77,"t":"Set Name on IBC Packet","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#set-name-on-ibc-packet","p":65},{"i":79,"t":"Start Testnet","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#start-testnet","p":65},{"i":81,"t":"Import Testnet Helpers","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#import-testnet-helpers","p":65},{"i":83,"t":"Connect Your IBC Modules","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#connect-your-ibc-modules","p":65},{"i":85,"t":"Submit Name Service Name Over IBC","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#submit-name-service-name-over-ibc","p":65},{"i":87,"t":"Summary","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#summary","p":65},{"i":89,"t":"What you Learned","u":"/spawn/v0.50/build/name-service-ibc-module/","h":"/spawn/v0.50/build/name-service-ibc-module/#what-you-learned","p":65},{"i":93,"t":"What you Learned","u":"/spawn/v0.50/build/name-service-summary/","h":"/spawn/v0.50/build/name-service-summary/#what-you-learned","p":91},{"i":95,"t":"What's Next?","u":"/spawn/v0.50/build/name-service-summary/","h":"/spawn/v0.50/build/name-service-summary/#whats-next","p":91},{"i":99,"t":"Prerequisites","u":"/spawn/v0.50/build/name-service/","h":"/spawn/v0.50/build/name-service/#prerequisites","p":97},{"i":101,"t":"Video Walkthrough","u":"/spawn/v0.50/build/name-service/","h":"/spawn/v0.50/build/name-service/#video-walkthrough","p":97},{"i":102,"t":"Generate a New Chain","u":"/spawn/v0.50/build/name-service/","h":"/spawn/v0.50/build/name-service/#generate-a-new-chain","p":97},{"i":104,"t":"Scaffold the Module","u":"/spawn/v0.50/build/name-service/","h":"/spawn/v0.50/build/name-service/#scaffold-the-module","p":97},{"i":108,"t":"Set Name","u":"/spawn/v0.50/build/name-service-structure/","h":"/spawn/v0.50/build/name-service-structure/#set-name","p":106},{"i":110,"t":"Get Name","u":"/spawn/v0.50/build/name-service-structure/","h":"/spawn/v0.50/build/name-service-structure/#get-name","p":106},{"i":112,"t":"Generate Code","u":"/spawn/v0.50/build/name-service-structure/","h":"/spawn/v0.50/build/name-service-structure/#generate-code","p":106},{"i":116,"t":"Prerequisites","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#prerequisites","p":114},{"i":118,"t":"Create your chain","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#create-your-chain","p":114},{"i":120,"t":"Spin up an IBC testnet","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#spin-up-an-ibc-testnet","p":114},{"i":122,"t":"Send a Transaction","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#send-a-transaction","p":114},{"i":124,"t":"Send an IBC transaction","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#send-an-ibc-transaction","p":114},{"i":126,"t":"(optional) Push to GitHub","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#optional-push-to-github","p":114},{"i":128,"t":"Conclusion","u":"/spawn/v0.50/demo/ibc/","h":"/spawn/v0.50/demo/ibc/#conclusion","p":114},{"i":132,"t":"Prerequisites","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#prerequisites","p":130},{"i":134,"t":"Create your chain","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#create-your-chain","p":130},{"i":136,"t":"Start the testnet","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#start-the-testnet","p":130},{"i":138,"t":"Confirm tokenfactory is enabled","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#confirm-tokenfactory-is-enabled","p":130},{"i":140,"t":"Create a token","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#create-a-token","p":130},{"i":142,"t":"Verify the token was created","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#verify-the-token-was-created","p":130},{"i":144,"t":"Modify token metadata","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#modify-token-metadata","p":130},{"i":146,"t":"Verify the token metadata","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#verify-the-token-metadata","p":130},{"i":148,"t":"Create new tokens to transfer","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#create-new-tokens-to-transfer","p":130},{"i":150,"t":"Create new tokens for another account","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#create-new-tokens-for-another-account","p":130},{"i":152,"t":"Transfer tokens","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#transfer-tokens","p":130},{"i":154,"t":"Burn tokens","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#burn-tokens","p":130},{"i":156,"t":"Conclusion","u":"/spawn/v0.50/demo/tokenfactory/","h":"/spawn/v0.50/demo/tokenfactory/#conclusion","p":130},{"i":160,"t":"Prerequisites","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#prerequisites","p":158},{"i":162,"t":"Create your chain","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#create-your-chain","p":158},{"i":164,"t":"Start the testnet","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#start-the-testnet","p":158},{"i":166,"t":"Verify CosmWasm is enabled","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#verify-cosmwasm-is-enabled","p":158},{"i":168,"t":"Upload the contract to the network","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#upload-the-contract-to-the-network","p":158},{"i":170,"t":"Verify the code was uploaded","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#verify-the-code-was-uploaded","p":158},{"i":172,"t":"Create a new NFT collection","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#create-a-new-nft-collection","p":158},{"i":174,"t":"Contract address","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#contract-address","p":158},{"i":176,"t":"Create an NFT in the collection","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#create-an-nft-in-the-collection","p":158},{"i":178,"t":"Grab this NFT data","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#grab-this-nft-data","p":158},{"i":180,"t":"Transfer the NFT to another account","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#transfer-the-nft-to-another-account","p":158},{"i":182,"t":"Conclusion","u":"/spawn/v0.50/demo/cw-nft/","h":"/spawn/v0.50/demo/cw-nft/#conclusion","p":158},{"i":186,"t":"Golang","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#golang","p":184},{"i":187,"t":"/bin/sh: 1: go: not found","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#binsh-1-go-not-found","p":184},{"i":189,"t":"build constraints excluded all Go files in /usr/local/go/ ...","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#build-constraints-excluded-all-go-files-in-usrlocalgo-","p":184},{"i":191,"t":"make: heighliner: Permission denied","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#make-heighliner-permission-denied","p":184},{"i":193,"t":"Windows / WSL","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#windows--wsl","p":184},{"i":194,"t":"make: /mnt/c/Program: No such file or directory","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#make-mntcprogram-no-such-file-or-directory","p":184},{"i":196,"t":"Docker","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#docker","p":184},{"i":197,"t":"Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running","p":184},{"i":199,"t":"docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#docker-got-permission-denied-while-trying-to-connect-to-the-docker-daemon-socket-at-unixvarrundockersock","p":184},{"i":201,"t":"Generation","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#generation","p":184},{"i":202,"t":"remote: Repository not found. fatal: reposity not found","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#remote-repository-not-found-fatal-reposity-not-found","p":184},{"i":204,"t":"Application","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#application","p":184},{"i":205,"t":"Running the binary gives me panic: reflect: New(nil)","u":"/spawn/v0.50/install/debugging/","h":"/spawn/v0.50/install/debugging/#running-the-binary-gives-me-panic-reflect-newnil","p":184},{"i":209,"t":"Install Spawn","u":"/spawn/v0.50/install/install-spawn/","h":"/spawn/v0.50/install/install-spawn/#install-spawn","p":207},{"i":212,"t":"Prerequisites","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#prerequisites","p":211},{"i":214,"t":"Choose for me (TLDR)","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#choose-for-me-tldr","p":211},{"i":216,"t":"Proof of Authority (PoA)","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#proof-of-authority-poa","p":211},{"i":217,"t":"Default","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#default","p":211},{"i":219,"t":"What it does","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#what-it-does","p":211},{"i":221,"t":"Create a PoA network","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#create-a-poa-network","p":211},{"i":223,"t":"Considerations","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#considerations","p":211},{"i":225,"t":"Proof of Stake (PoS)","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#proof-of-stake-pos","p":211},{"i":226,"t":"What it does","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#what-it-does-1","p":211},{"i":228,"t":"Create a PoS network","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#create-a-pos-network","p":211},{"i":230,"t":"Considerations","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#considerations-1","p":211},{"i":232,"t":"Interchain Security (ICS)","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#interchain-security-ics","p":211},{"i":233,"t":"What it does","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#what-it-does-2","p":211},{"i":235,"t":"Create an ICS Consumer network","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#create-an-ics-consumer-network","p":211},{"i":237,"t":"Considerations","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#considerations-2","p":211},{"i":239,"t":"Conclusion","u":"/spawn/v0.50/learn/consensus-security/","h":"/spawn/v0.50/learn/consensus-security/#conclusion","p":211},{"i":243,"t":"System Requirements","u":"/spawn/v0.50/install/system-setup/","h":"/spawn/v0.50/install/system-setup/#system-requirements","p":241},{"i":245,"t":"Windows","u":"/spawn/v0.50/install/system-setup/","h":"/spawn/v0.50/install/system-setup/#windows","p":241},{"i":247,"t":"MacOS","u":"/spawn/v0.50/install/system-setup/","h":"/spawn/v0.50/install/system-setup/#macos","p":241},{"i":249,"t":"Linux (Ubuntu)","u":"/spawn/v0.50/install/system-setup/","h":"/spawn/v0.50/install/system-setup/#linux-ubuntu","p":241},{"i":251,"t":"CosmWasm","u":"/spawn/v0.50/install/system-setup/","h":"/spawn/v0.50/install/system-setup/#cosmwasm","p":241},{"i":255,"t":"Prerequisites","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#prerequisites","p":253},{"i":257,"t":"Setup the Chain","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#setup-the-chain","p":253},{"i":259,"t":"Build CosmWasm Contract","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#build-cosmwasm-contract","p":253},{"i":261,"t":"Update Contract Dependencies","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#update-contract-dependencies","p":253},{"i":263,"t":"Setup State","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#setup-state","p":253},{"i":265,"t":"Setup Interactions","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#setup-interactions","p":253},{"i":267,"t":"Contract Logic","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#contract-logic","p":253},{"i":269,"t":"Create Transaction acknowledgement","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#create-transaction-acknowledgement","p":253},{"i":271,"t":"Setup Errors","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#setup-errors","p":253},{"i":273,"t":"IBC Specific Logic","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#ibc-specific-logic","p":253},{"i":275,"t":"Build Contract From Source","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#build-contract-from-source","p":253},{"i":277,"t":"Start the chains and connect","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#start-the-chains-and-connect","p":253},{"i":279,"t":"Store the Contract on both chains","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#store-the-contract-on-both-chains","p":253},{"i":281,"t":"Instantiate our Contract on both chains","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#instantiate-our-contract-on-both-chains","p":253},{"i":283,"t":"Relayer connect","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#relayer-connect","p":253},{"i":285,"t":"Verify channels","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#verify-channels","p":253},{"i":287,"t":"Transaction interaction","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#transaction-interaction","p":253},{"i":289,"t":"Verify data","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#verify-data","p":253},{"i":291,"t":"Summary","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#summary","p":253},{"i":293,"t":"What you Learned","u":"/spawn/v0.50/build/name-service-ibc-contract/","h":"/spawn/v0.50/build/name-service-ibc-contract/#what-you-learned","p":253},{"i":297,"t":"Prerequisites","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#prerequisites","p":295},{"i":299,"t":"Setup the Chain","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#setup-the-chain","p":295},{"i":301,"t":"CosmWasm Build Contract","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#cosmwasm-build-contract","p":295},{"i":303,"t":"Set State","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#set-state","p":295},{"i":305,"t":"Set Inputs","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#set-inputs","p":295},{"i":307,"t":"Set new error","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#set-new-error","p":295},{"i":309,"t":"Imports","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#imports","p":295},{"i":311,"t":"Modify Instantiate Message","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#modify-instantiate-message","p":295},{"i":313,"t":"Add Execute Logic","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#add-execute-logic","p":295},{"i":315,"t":"Add Queries","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#add-queries","p":295},{"i":317,"t":"Add New Sudo Message Type","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#add-new-sudo-message-type","p":295},{"i":319,"t":"Build the Contract","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#build-the-contract","p":295},{"i":321,"t":"Modify the Module","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#modify-the-module","p":295},{"i":323,"t":"Setup the Keeper","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#setup-the-keeper","p":295},{"i":325,"t":"'Fix' keeper_test","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#fix-keeper_test","p":295},{"i":327,"t":"Dependency Inject (v2)","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#dependency-inject-v2","p":295},{"i":329,"t":"Fix app.go references","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#fix-appgo-references","p":295},{"i":331,"t":"Module Core Logic","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#module-core-logic","p":295},{"i":333,"t":"Implement the EndBlocker","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#implement-the-endblocker","p":295},{"i":335,"t":"Test Deployment","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#test-deployment","p":295},{"i":336,"t":"Start Testnet","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#start-testnet","p":295},{"i":338,"t":"Upload Contract","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#upload-contract","p":295},{"i":340,"t":"Instantiate our Contract","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#instantiate-our-contract","p":295},{"i":342,"t":"Verify data","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#verify-data","p":295},{"i":344,"t":"Write a review","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#write-a-review","p":295},{"i":346,"t":"Verify the review","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#verify-the-review","p":295},{"i":348,"t":"Write a review for a non-validator","u":"/spawn/v0.50/demo/cw-validator-reviews/","h":"/spawn/v0.50/demo/cw-validator-reviews/#write-a-review-for-a-non-validator","p":295}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/4",[0,5.449]],["t/6",[1,4.42]],["t/10",[2,4.075,3,4.974]],["t/12",[4,6.115]],["t/14",[5,4.432,6,4.974]],["t/16",[7,3.267,8,4.974]],["t/18",[9,4.432,10,4.432]],["t/20",[10,4.432,11,4.974]],["t/22",[12,6.115]],["t/24",[13,5.449]],["t/26",[14,6.115]],["t/28",[15,3.458]],["t/30",[16,6.115]],["t/32",[17,6.115]],["t/34",[18,6.115]],["t/36",[19,6.115]],["t/38",[20,6.115]],["t/40",[21,6.115]],["t/42",[22,4.192,23,3.435,24,4.192]],["t/44",[25,3.852]],["t/46",[26,4.016]],["t/50",[27,4.432,28,3.596]],["t/53",[29,3.228,30,3.228,31,3.623,32,3.228]],["t/55",[29,2.842,33,3.19,34,3.19,35,3.19,36,2.095]],["t/59",[37,4.974,38,3.596]],["t/61",[36,2.753,39,3.21,40,2.881]],["t/63",[36,3.267,39,3.809]],["t/67",[41,3.852]],["t/69",[15,2.813,42,2.567]],["t/71",[25,2.641,43,3.736,44,2.641]],["t/73",[2,3.435,25,2.641,45,4.192]],["t/75",[2,2.968,25,2.282,44,2.282,46,3.623]],["t/77",[36,2.379,40,2.49,44,2.282,47,3.623]],["t/79",[26,3.267,48,3.596]],["t/81",[26,2.753,49,3.736,50,4.192]],["t/83",[25,2.641,44,2.641,51,3.031]],["t/85",[36,2.932,44,1.795,52,2.849,53,2.849,54,2.849]],["t/87",[55,5.449]],["t/89",[56,5.01]],["t/93",[56,5.01]],["t/95",[57,4.974,58,4.974]],["t/99",[41,3.852]],["t/101",[59,4.974,60,4.974]],["t/102",[7,2.753,15,2.371,61,3.435]],["t/104",[25,3.134,43,4.432]],["t/108",[36,3.267,40,3.419]],["t/110",[36,4.016]],["t/112",[61,4.075,62,4.432]],["t/116",[41,3.852]],["t/118",[15,2.813,42,2.567]],["t/120",[26,2.379,44,2.282,63,3.623,64,3.623]],["t/122",[1,3.596,65,4.432]],["t/124",[1,3.031,44,2.641,65,3.736]],["t/126",[13,3.736,66,4.192,67,4.192]],["t/128",[68,4.682]],["t/132",[41,3.852]],["t/134",[15,2.813,42,2.567]],["t/136",[26,3.267,48,3.596]],["t/138",[69,4.192,70,4.192,71,3.736]],["t/140",[42,2.567,72,3.134]],["t/142",[42,2.164,72,2.641,73,2.641]],["t/144",[72,2.641,74,3.435,75,3.736]],["t/146",[72,2.641,73,2.641,75,3.736]],["t/148",[7,2.379,42,1.87,72,2.282,76,2.968]],["t/150",[7,2.095,42,1.646,72,2.01,77,2.842,78,2.842]],["t/152",[72,3.134,76,4.075]],["t/154",[72,3.134,79,4.974]],["t/156",[68,4.682]],["t/160",[41,3.852]],["t/162",[15,2.813,42,2.567]],["t/164",[26,3.267,48,3.596]],["t/166",[71,3.736,73,2.641,80,3.21]],["t/168",[38,3.031,81,3.435,82,2.296]],["t/170",[62,3.736,73,2.641,81,3.435]],["t/172",[7,2.379,42,1.87,83,2.774,84,3.228]],["t/174",[82,2.725,85,4.974]],["t/176",[42,2.164,83,3.21,84,3.736]],["t/178",[83,3.21,86,4.192,87,3.435]],["t/180",[76,2.968,77,3.228,78,3.228,83,2.774]],["t/182",[68,4.682]],["t/186",[88,6.115]],["t/187",[30,3.228,89,3.623,90,3.228,91,3.228]],["t/189",[23,2.109,90,2.293,92,1.861,93,2.574,94,2.574,95,2.293,96,2.574]],["t/191",[97,3.228,98,3.623,99,3.228,100,3.228]],["t/193",[23,3.435,101,3.736,102,4.192]],["t/194",[95,2.842,97,2.842,103,3.19,104,3.19,105,3.19]],["t/196",[106,5.01]],["t/197",[51,1.861,106,3.375,107,3.671,108,2.293,109,2.293]],["t/199",[51,1.56,99,1.922,100,1.922,106,2.924,107,1.922,108,1.922,110,2.158,111,2.158]],["t/201",[61,5.01]],["t/202",[91,3.978,112,2.849,113,2.849,114,2.849,115,2.849]],["t/204",[27,5.449]],["t/205",[109,2.538,116,2.849,117,2.849,118,2.849,119,2.849,120,2.849]],["t/209",[5,4.432,121,4.974]],["t/212",[41,3.852]],["t/214",[122,4.974,123,4.974]],["t/216",[124,3.736,125,4.192,126,3.736]],["t/217",[127,6.115]],["t/219",[]],["t/221",[38,3.031,42,2.164,126,3.736]],["t/223",[128,5.01]],["t/225",[124,3.736,129,4.192,130,3.736]],["t/226",[]],["t/228",[38,3.031,42,2.164,130,3.736]],["t/230",[128,5.01]],["t/232",[9,3.736,131,4.192,132,3.736]],["t/233",[]],["t/235",[38,2.619,42,1.87,132,3.228,133,3.623]],["t/237",[128,5.01]],["t/239",[68,4.682]],["t/243",[134,4.974,135,4.974]],["t/245",[101,5.449]],["t/247",[136,6.115]],["t/249",[137,4.974,138,4.974]],["t/251",[80,4.682]],["t/255",[41,3.852]],["t/257",[15,2.813,139,3.419]],["t/259",[80,3.21,82,2.296,92,3.031]],["t/261",[82,2.296,140,4.192,141,3.736]],["t/263",[139,3.419,142,4.432]],["t/265",[39,3.809,139,3.419]],["t/267",[28,3.596,82,2.725]],["t/269",[1,3.031,42,2.164,143,4.192]],["t/271",[139,3.419,144,4.432]],["t/273",[28,3.031,44,2.641,145,4.192]],["t/275",[82,2.296,92,3.031,146,4.192]],["t/277",[15,2.371,48,3.031,51,3.031]],["t/279",[15,2.049,82,1.984,147,3.623,148,3.228]],["t/281",[15,2.049,82,1.984,148,3.228,149,2.968]],["t/283",[51,3.596,150,4.974]],["t/285",[73,3.134,151,4.974]],["t/287",[1,3.596,39,3.809]],["t/289",[73,3.134,87,4.075]],["t/291",[55,5.449]],["t/293",[56,5.01]],["t/297",[41,3.852]],["t/299",[15,2.813,139,3.419]],["t/301",[80,3.21,82,2.296,92,3.031]],["t/303",[40,3.419,142,4.432]],["t/305",[32,4.432,40,3.419]],["t/307",[7,2.753,40,2.881,144,3.736]],["t/309",[49,5.449]],["t/311",[74,3.435,149,3.435,152,3.736]],["t/313",[28,3.031,153,3.435,154,4.192]],["t/315",[0,4.432,153,4.075]],["t/317",[7,2.095,152,2.842,153,2.613,155,3.19,156,3.19]],["t/319",[82,2.725,92,3.596]],["t/321",[25,3.134,74,4.075]],["t/323",[139,3.419,157,4.974]],["t/325",[158,4.432,159,4.974]],["t/327",[141,3.736,160,4.192,161,4.192]],["t/329",[158,3.736,162,4.192,163,4.192]],["t/331",[25,2.641,28,3.031,164,4.192]],["t/333",[165,4.974,166,4.974]],["t/335",[167,4.974,168,4.974]],["t/336",[26,3.267,48,3.596]],["t/338",[81,4.075,82,2.725]],["t/340",[82,2.725,149,4.075]],["t/342",[73,3.134,87,4.075]],["t/344",[169,4.432,170,4.075]],["t/346",[73,3.134,170,4.075]],["t/348",[169,3.228,170,2.968,171,3.623,172,3.623]]],"invertedIndex":[["",{"_index":23,"t":{"42":{"position":[[20,1]]},"189":{"position":[[58,3]]},"193":{"position":[[8,1]]}}}],["1",{"_index":30,"t":{"53":{"position":[[10,2]]},"187":{"position":[[9,2]]}}}],["2",{"_index":33,"t":{"55":{"position":[[10,2]]}}}],["account",{"_index":78,"t":{"150":{"position":[[30,7]]},"180":{"position":[[28,7]]}}}],["acknowledg",{"_index":143,"t":{"269":{"position":[[19,15]]}}}],["add",{"_index":153,"t":{"313":{"position":[[0,3]]},"315":{"position":[[0,3]]},"317":{"position":[[0,3]]}}}],["address",{"_index":85,"t":{"174":{"position":[[9,7]]}}}],["anoth",{"_index":77,"t":{"150":{"position":[[22,7]]},"180":{"position":[[20,7]]}}}],["app",{"_index":14,"t":{"26":{"position":[[0,4]]}}}],["app.go",{"_index":162,"t":{"329":{"position":[[4,6]]}}}],["applic",{"_index":27,"t":{"50":{"position":[[0,11]]},"204":{"position":[[0,11]]}}}],["asset",{"_index":24,"t":{"42":{"position":[[22,6]]}}}],["author",{"_index":125,"t":{"216":{"position":[[9,9]]}}}],["bin/sh",{"_index":89,"t":{"187":{"position":[[0,8]]}}}],["binari",{"_index":116,"t":{"205":{"position":[[12,6]]}}}],["both",{"_index":148,"t":{"279":{"position":[[22,4]]},"281":{"position":[[28,4]]}}}],["build",{"_index":92,"t":{"189":{"position":[[0,5]]},"259":{"position":[[0,5]]},"275":{"position":[[0,5]]},"301":{"position":[[9,5]]},"319":{"position":[[0,5]]}}}],["burn",{"_index":79,"t":{"154":{"position":[[0,4]]}}}],["chain",{"_index":15,"t":{"28":{"position":[[0,7]]},"69":{"position":[[12,5]]},"102":{"position":[[15,5]]},"118":{"position":[[12,5]]},"134":{"position":[[12,5]]},"162":{"position":[[12,5]]},"257":{"position":[[10,5]]},"277":{"position":[[10,6]]},"279":{"position":[[27,6]]},"281":{"position":[[33,6]]},"299":{"position":[[10,5]]}}}],["chain_metadata.json",{"_index":21,"t":{"40":{"position":[[0,19]]}}}],["chain_registry.json",{"_index":22,"t":{"42":{"position":[[0,19]]}}}],["challeng",{"_index":29,"t":{"53":{"position":[[0,9]]},"55":{"position":[[0,9]]}}}],["channel",{"_index":151,"t":{"285":{"position":[[7,8]]}}}],["choos",{"_index":122,"t":{"214":{"position":[[0,6]]}}}],["cmd",{"_index":16,"t":{"30":{"position":[[0,4]]}}}],["code",{"_index":62,"t":{"112":{"position":[[9,4]]},"170":{"position":[[11,4]]}}}],["collect",{"_index":84,"t":{"172":{"position":[[17,10]]},"176":{"position":[[21,10]]}}}],["conclus",{"_index":68,"t":{"128":{"position":[[0,10]]},"156":{"position":[[0,10]]},"182":{"position":[[0,10]]},"239":{"position":[[0,10]]}}}],["confirm",{"_index":69,"t":{"138":{"position":[[0,7]]}}}],["connect",{"_index":51,"t":{"83":{"position":[[0,7]]},"197":{"position":[[7,7]]},"199":{"position":[[46,7]]},"277":{"position":[[21,7]]},"283":{"position":[[8,7]]}}}],["consider",{"_index":128,"t":{"223":{"position":[[0,14]]},"230":{"position":[[0,14]]},"237":{"position":[[0,14]]}}}],["constraint",{"_index":93,"t":{"189":{"position":[[6,11]]}}}],["consum",{"_index":133,"t":{"235":{"position":[[14,8]]}}}],["contract",{"_index":82,"t":{"168":{"position":[[11,8]]},"174":{"position":[[0,8]]},"259":{"position":[[15,8]]},"261":{"position":[[7,8]]},"267":{"position":[[0,8]]},"275":{"position":[[6,8]]},"279":{"position":[[10,8]]},"281":{"position":[[16,8]]},"301":{"position":[[15,8]]},"319":{"position":[[10,8]]},"338":{"position":[[7,8]]},"340":{"position":[[16,8]]}}}],["core",{"_index":164,"t":{"331":{"position":[[7,4]]}}}],["cosmwasm",{"_index":80,"t":{"166":{"position":[[7,8]]},"251":{"position":[[0,8]]},"259":{"position":[[6,8]]},"301":{"position":[[0,8]]}}}],["creat",{"_index":42,"t":{"69":{"position":[[0,6]]},"118":{"position":[[0,6]]},"134":{"position":[[0,6]]},"140":{"position":[[0,6]]},"142":{"position":[[21,7]]},"148":{"position":[[0,6]]},"150":{"position":[[0,6]]},"162":{"position":[[0,6]]},"172":{"position":[[0,6]]},"176":{"position":[[0,6]]},"221":{"position":[[0,6]]},"228":{"position":[[0,6]]},"235":{"position":[[0,6]]},"269":{"position":[[0,6]]}}}],["daemon",{"_index":107,"t":{"197":{"position":[[29,6],[82,6]]},"199":{"position":[[68,6]]}}}],["data",{"_index":87,"t":{"178":{"position":[[14,4]]},"289":{"position":[[7,4]]},"342":{"position":[[7,4]]}}}],["default",{"_index":127,"t":{"217":{"position":[[0,7]]}}}],["demo",{"_index":3,"t":{"10":{"position":[[12,4]]}}}],["deni",{"_index":100,"t":{"191":{"position":[[29,6]]},"199":{"position":[[23,6]]}}}],["depend",{"_index":141,"t":{"261":{"position":[[16,12]]},"327":{"position":[[0,10]]}}}],["deploy",{"_index":168,"t":{"335":{"position":[[5,10]]}}}],["develop",{"_index":8,"t":{"16":{"position":[[4,11]]}}}],["directori",{"_index":105,"t":{"194":{"position":[[38,9]]}}}],["docker",{"_index":106,"t":{"196":{"position":[[0,6]]},"197":{"position":[[22,6],[75,6]]},"199":{"position":[[0,7],[61,6]]}}}],["enabl",{"_index":71,"t":{"138":{"position":[[24,7]]},"166":{"position":[[19,7]]}}}],["endblock",{"_index":166,"t":{"333":{"position":[[14,10]]}}}],["error",{"_index":144,"t":{"271":{"position":[[6,6]]},"307":{"position":[[8,5]]}}}],["exclud",{"_index":94,"t":{"189":{"position":[[18,8]]}}}],["execut",{"_index":154,"t":{"313":{"position":[[4,7]]}}}],["explor",{"_index":17,"t":{"32":{"position":[[0,9]]}}}],["fatal",{"_index":114,"t":{"202":{"position":[[30,6]]}}}],["featur",{"_index":11,"t":{"20":{"position":[[0,7]]}}}],["file",{"_index":95,"t":{"189":{"position":[[34,5]]},"194":{"position":[[30,4]]}}}],["fix",{"_index":158,"t":{"325":{"position":[[0,5]]},"329":{"position":[[0,3]]}}}],["found",{"_index":91,"t":{"187":{"position":[[20,5]]},"202":{"position":[[23,6],[50,5]]}}}],["gener",{"_index":61,"t":{"102":{"position":[[0,8]]},"112":{"position":[[0,8]]},"201":{"position":[[0,10]]}}}],["github",{"_index":13,"t":{"24":{"position":[[0,8]]},"126":{"position":[[19,6]]}}}],["give",{"_index":117,"t":{"205":{"position":[[19,5]]}}}],["go",{"_index":90,"t":{"187":{"position":[[12,3]]},"189":{"position":[[31,2]]}}}],["golang",{"_index":88,"t":{"186":{"position":[[0,6]]}}}],["grab",{"_index":86,"t":{"178":{"position":[[0,4]]}}}],["heighlin",{"_index":98,"t":{"191":{"position":[[6,11]]}}}],["helper",{"_index":50,"t":{"81":{"position":[[15,7]]}}}],["ibc",{"_index":44,"t":{"71":{"position":[[13,3]]},"75":{"position":[[27,3]]},"77":{"position":[[12,3]]},"83":{"position":[[13,3]]},"85":{"position":[[30,3]]},"120":{"position":[[11,3]]},"124":{"position":[[8,3]]},"273":{"position":[[0,3]]}}}],["ic",{"_index":132,"t":{"232":{"position":[[20,5]]},"235":{"position":[[10,3]]}}}],["implement",{"_index":165,"t":{"333":{"position":[[0,9]]}}}],["import",{"_index":49,"t":{"81":{"position":[[0,6]]},"309":{"position":[[0,7]]}}}],["inject",{"_index":160,"t":{"327":{"position":[[11,6]]}}}],["input",{"_index":32,"t":{"53":{"position":[[19,5]]},"305":{"position":[[4,6]]}}}],["instal",{"_index":121,"t":{"209":{"position":[[0,7]]}}}],["instanti",{"_index":149,"t":{"281":{"position":[[0,11]]},"311":{"position":[[7,11]]},"340":{"position":[[0,11]]}}}],["interact",{"_index":39,"t":{"61":{"position":[[0,8]]},"63":{"position":[[0,11]]},"265":{"position":[[6,12]]},"287":{"position":[[12,11]]}}}],["interchain",{"_index":131,"t":{"232":{"position":[[0,10]]}}}],["interchaintest",{"_index":18,"t":{"34":{"position":[[0,15]]}}}],["keeper",{"_index":157,"t":{"323":{"position":[[10,6]]}}}],["keeper_test",{"_index":159,"t":{"325":{"position":[[6,11]]}}}],["launch",{"_index":37,"t":{"59":{"position":[[0,6]]}}}],["learn",{"_index":56,"t":{"89":{"position":[[9,7]]},"93":{"position":[[9,7]]},"293":{"position":[[9,7]]}}}],["limit",{"_index":31,"t":{"53":{"position":[[13,5]]}}}],["linux",{"_index":137,"t":{"249":{"position":[[0,5]]}}}],["logic",{"_index":28,"t":{"50":{"position":[[12,5]]},"267":{"position":[[9,5]]},"273":{"position":[[13,5]]},"313":{"position":[[12,5]]},"331":{"position":[[12,5]]}}}],["maco",{"_index":136,"t":{"247":{"position":[[0,5]]}}}],["make",{"_index":97,"t":{"191":{"position":[[0,5]]},"194":{"position":[[0,5]]}}}],["messag",{"_index":152,"t":{"311":{"position":[[19,7]]},"317":{"position":[[13,7]]}}}],["metadata",{"_index":75,"t":{"144":{"position":[[13,8]]},"146":{"position":[[17,8]]}}}],["mnt/c/program",{"_index":103,"t":{"194":{"position":[[6,15]]}}}],["modifi",{"_index":74,"t":{"144":{"position":[[0,6]]},"311":{"position":[[0,6]]},"321":{"position":[[0,6]]}}}],["modul",{"_index":25,"t":{"44":{"position":[[0,7]]},"71":{"position":[[17,6]]},"73":{"position":[[20,6]]},"75":{"position":[[31,6]]},"83":{"position":[[17,7]]},"104":{"position":[[13,6]]},"321":{"position":[[11,6]]},"331":{"position":[[0,6]]}}}],["name",{"_index":36,"t":{"55":{"position":[[33,4]]},"61":{"position":[[13,4]]},"63":{"position":[[16,4]]},"77":{"position":[[4,4]]},"85":{"position":[[7,4],[20,4]]},"108":{"position":[[4,4]]},"110":{"position":[[4,4]]}}}],["nameservic",{"_index":2,"t":{"10":{"position":[[0,11]]},"73":{"position":[[8,11]]},"75":{"position":[[8,11]]}}}],["network",{"_index":38,"t":{"59":{"position":[[11,7]]},"168":{"position":[[27,7]]},"221":{"position":[[13,7]]},"228":{"position":[[13,7]]},"235":{"position":[[23,7]]}}}],["new",{"_index":7,"t":{"16":{"position":[[0,3]]},"102":{"position":[[11,3]]},"148":{"position":[[7,3]]},"150":{"position":[[7,3]]},"172":{"position":[[9,3]]},"307":{"position":[[4,3]]},"317":{"position":[[4,3]]}}}],["new(nil",{"_index":120,"t":{"205":{"position":[[44,8]]}}}],["next",{"_index":58,"t":{"95":{"position":[[7,5]]}}}],["nft",{"_index":83,"t":{"172":{"position":[[13,3]]},"176":{"position":[[10,3]]},"178":{"position":[[10,3]]},"180":{"position":[[13,3]]}}}],["non",{"_index":171,"t":{"348":{"position":[[21,3]]}}}],["option",{"_index":66,"t":{"126":{"position":[[0,10]]}}}],["over",{"_index":54,"t":{"85":{"position":[[25,4]]}}}],["overview",{"_index":6,"t":{"14":{"position":[[6,8]]}}}],["packet",{"_index":47,"t":{"77":{"position":[[16,6]]}}}],["panic",{"_index":118,"t":{"205":{"position":[[28,6]]}}}],["permiss",{"_index":99,"t":{"191":{"position":[[18,10]]},"199":{"position":[[12,10]]}}}],["po",{"_index":130,"t":{"225":{"position":[[15,5]]},"228":{"position":[[9,3]]}}}],["poa",{"_index":126,"t":{"216":{"position":[[19,5]]},"221":{"position":[[9,3]]}}}],["prerequisit",{"_index":41,"t":{"67":{"position":[[0,13]]},"99":{"position":[[0,13]]},"116":{"position":[[0,13]]},"132":{"position":[[0,13]]},"160":{"position":[[0,13]]},"212":{"position":[[0,13]]},"255":{"position":[[0,13]]},"297":{"position":[[0,13]]}}}],["proof",{"_index":124,"t":{"216":{"position":[[0,5]]},"225":{"position":[[0,5]]}}}],["proto",{"_index":19,"t":{"36":{"position":[[0,6]]}}}],["provid",{"_index":46,"t":{"75":{"position":[[0,7]]}}}],["push",{"_index":67,"t":{"126":{"position":[[11,4]]}}}],["queri",{"_index":0,"t":{"4":{"position":[[0,5]]},"315":{"position":[[4,7]]}}}],["refer",{"_index":163,"t":{"329":{"position":[[11,10]]}}}],["reflect",{"_index":119,"t":{"205":{"position":[[35,8]]}}}],["relay",{"_index":150,"t":{"283":{"position":[[0,7]]}}}],["remot",{"_index":112,"t":{"202":{"position":[[0,7]]}}}],["repos",{"_index":115,"t":{"202":{"position":[[37,8]]}}}],["repositori",{"_index":113,"t":{"202":{"position":[[8,10]]}}}],["requir",{"_index":135,"t":{"243":{"position":[[7,12]]}}}],["resolv",{"_index":34,"t":{"55":{"position":[[13,7]]}}}],["review",{"_index":170,"t":{"344":{"position":[[8,6]]},"346":{"position":[[11,6]]},"348":{"position":[[8,6]]}}}],["run",{"_index":109,"t":{"197":{"position":[[89,9]]},"205":{"position":[[0,7]]}}}],["scaffold",{"_index":43,"t":{"71":{"position":[[0,8]]},"104":{"position":[[0,8]]}}}],["script",{"_index":20,"t":{"38":{"position":[[0,8]]}}}],["secur",{"_index":9,"t":{"18":{"position":[[0,8]]},"232":{"position":[[11,8]]}}}],["select",{"_index":10,"t":{"18":{"position":[[9,9]]},"20":{"position":[[8,9]]}}}],["send",{"_index":65,"t":{"122":{"position":[[0,4]]},"124":{"position":[[0,4]]}}}],["servic",{"_index":53,"t":{"85":{"position":[[12,7]]}}}],["set",{"_index":40,"t":{"61":{"position":[[9,3]]},"77":{"position":[[0,3]]},"108":{"position":[[0,3]]},"303":{"position":[[0,3]]},"305":{"position":[[0,3]]},"307":{"position":[[0,3]]}}}],["setup",{"_index":139,"t":{"257":{"position":[[0,5]]},"263":{"position":[[0,5]]},"265":{"position":[[0,5]]},"271":{"position":[[0,5]]},"299":{"position":[[0,5]]},"323":{"position":[[0,5]]}}}],["socket",{"_index":111,"t":{"199":{"position":[[75,6]]}}}],["sourc",{"_index":146,"t":{"275":{"position":[[20,6]]}}}],["spawn",{"_index":5,"t":{"14":{"position":[[0,5]]},"209":{"position":[[8,5]]}}}],["specif",{"_index":145,"t":{"273":{"position":[[4,8]]}}}],["spin",{"_index":63,"t":{"120":{"position":[[0,4]]}}}],["stake",{"_index":129,"t":{"225":{"position":[[9,5]]}}}],["start",{"_index":48,"t":{"79":{"position":[[0,5]]},"136":{"position":[[0,5]]},"164":{"position":[[0,5]]},"277":{"position":[[0,5]]},"336":{"position":[[0,5]]}}}],["state",{"_index":142,"t":{"263":{"position":[[6,5]]},"303":{"position":[[4,5]]}}}],["store",{"_index":147,"t":{"279":{"position":[[0,5]]}}}],["structur",{"_index":12,"t":{"22":{"position":[[0,9]]}}}],["submit",{"_index":52,"t":{"85":{"position":[[0,6]]}}}],["such",{"_index":104,"t":{"194":{"position":[[25,4]]}}}],["sudo",{"_index":155,"t":{"317":{"position":[[8,4]]}}}],["summari",{"_index":55,"t":{"87":{"position":[[0,7]]},"291":{"position":[[0,7]]}}}],["system",{"_index":134,"t":{"243":{"position":[[0,6]]}}}],["test",{"_index":167,"t":{"335":{"position":[[0,4]]}}}],["testimoni",{"_index":4,"t":{"12":{"position":[[0,12]]}}}],["testnet",{"_index":26,"t":{"46":{"position":[[0,8]]},"79":{"position":[[6,7]]},"81":{"position":[[7,7]]},"120":{"position":[[15,7]]},"136":{"position":[[10,7]]},"164":{"position":[[10,7]]},"336":{"position":[[6,7]]}}}],["tldr",{"_index":123,"t":{"214":{"position":[[14,6]]}}}],["token",{"_index":72,"t":{"140":{"position":[[9,5]]},"142":{"position":[[11,5]]},"144":{"position":[[7,5]]},"146":{"position":[[11,5]]},"148":{"position":[[11,6]]},"150":{"position":[[11,6]]},"152":{"position":[[9,6]]},"154":{"position":[[5,6]]}}}],["tokenfactori",{"_index":70,"t":{"138":{"position":[[8,12]]}}}],["transact",{"_index":1,"t":{"6":{"position":[[0,11]]},"122":{"position":[[7,11]]},"124":{"position":[[12,11]]},"269":{"position":[[7,11]]},"287":{"position":[[0,11]]}}}],["transfer",{"_index":76,"t":{"148":{"position":[[21,8]]},"152":{"position":[[0,8]]},"180":{"position":[[0,8]]}}}],["tri",{"_index":110,"t":{"199":{"position":[[36,6]]}}}],["type",{"_index":156,"t":{"317":{"position":[[21,4]]}}}],["ubuntu",{"_index":138,"t":{"249":{"position":[[6,8]]}}}],["unix:///var/run/docker.sock",{"_index":108,"t":{"197":{"position":[[39,28]]},"199":{"position":[[85,27]]}}}],["up",{"_index":64,"t":{"120":{"position":[[5,2]]}}}],["updat",{"_index":140,"t":{"261":{"position":[[0,6]]}}}],["upload",{"_index":81,"t":{"168":{"position":[[0,6]]},"170":{"position":[[20,8]]},"338":{"position":[[0,6]]}}}],["us",{"_index":45,"t":{"73":{"position":[[0,3]]}}}],["usr/local/go",{"_index":96,"t":{"189":{"position":[[43,14]]}}}],["v2",{"_index":161,"t":{"327":{"position":[[18,4]]}}}],["valid",{"_index":172,"t":{"348":{"position":[[25,9]]}}}],["verifi",{"_index":73,"t":{"142":{"position":[[0,6]]},"146":{"position":[[0,6]]},"166":{"position":[[0,6]]},"170":{"position":[[0,6]]},"285":{"position":[[0,6]]},"289":{"position":[[0,6]]},"342":{"position":[[0,6]]},"346":{"position":[[0,6]]}}}],["video",{"_index":59,"t":{"101":{"position":[[0,5]]}}}],["walkthrough",{"_index":60,"t":{"101":{"position":[[6,11]]}}}],["wallet",{"_index":35,"t":{"55":{"position":[[21,6]]}}}],["what'",{"_index":57,"t":{"95":{"position":[[0,6]]}}}],["window",{"_index":101,"t":{"193":{"position":[[0,7]]},"245":{"position":[[0,7]]}}}],["write",{"_index":169,"t":{"344":{"position":[[0,5]]},"348":{"position":[[0,5]]}}}],["wsl",{"_index":102,"t":{"193":{"position":[[10,3]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Using the Cosmos-SDKs AutoCLI, you will easily set up the CLI client for transactions and queries.","s":"Command Line Client","u":"/spawn/v0.50/build/name-service-client/","h":"","p":2},{"i":5,"t":"Update the autocli to allow someone to get the name of a wallet account. x/nameservice/autocli.go Query: &autocliv1.ServiceCommandDescriptor{ Service: modulev1.Query_ServiceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ { RpcMethod: \"ResolveName\", Use: \"resolve [wallet]\", Short: \"Resolve the name of a wallet address\", PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: \"wallet\"}, }, }, { RpcMethod: \"Params\", Use: \"params\", Short: \"Query the current module parameters\", }, }, }, AutoCLI Query","s":"Query","u":"/spawn/v0.50/build/name-service-client/","h":"/spawn/v0.50/build/name-service-client/#query","p":2},{"i":7,"t":"Also add interaction in x/nameservice/autocli.go to set the name of a wallet account. x/nameservice/autocli.go Tx: &autocliv1.ServiceCommandDescriptor{ Service: modulev1.Msg_ServiceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ { RpcMethod: \"SetServiceName\", Use: \"set [name]\", Short: \"Set the mapping to your wallet address\", PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: \"name\"}, }, }, { // NOTE: this is already included in the current source RpcMethod: \"UpdateParams\", Skip: false, }, }, }, AutoCLI Tx","s":"Transaction","u":"/spawn/v0.50/build/name-service-client/","h":"/spawn/v0.50/build/name-service-client/#transaction","p":2},{"i":9,"t":"Spawn is the easiest way to build, maintain and scale a Cosmos SDK blockchain. Spawn solves all the key pain points engineers face when building new Cosmos-SDK networks. Tailor-fit: Pick and choose modules to create a network for your needs. Commonality: Use native Cosmos tools and standards you're already familiar with. Integrations: Github actions and end-to-end testing are configured right from the start. Iteration: Quickly test between your new chain and established networks like the local Cosmos-Hub devnet.","s":"Meet Spawn","u":"/spawn/v0.50/","h":"","p":8},{"i":11,"t":"Follow Along with the NameService demo","s":"NameService Demo","u":"/spawn/v0.50/","h":"/spawn/v0.50/#nameservice-demo","p":8},{"i":13,"t":"\"Spawn is a marked transformation in CosmosSDK protocol development, allowing scaffolding and upgrading from 0.47 to 0.50 to be achievable and understandable. Without the tool, this would have been a dedicated multi-month effort\" - Ash, Burnt.com \"Spawn has truly streamlined the developer onboarding process into the Cosmos ecosystem, seamless and efficient.\" - Anil VitWit","s":"Testimonials","u":"/spawn/v0.50/","h":"/spawn/v0.50/#testimonials","p":8},{"i":15,"t":"Setting up a new blockchain used to take at least a week, requiring manual edits, debugging, and configuring tests. Now, with Spawn, you can create a custom network in just a few clicks. It generates a personalized network tailored to your project, letting you focus on writing product logic. The modular approach allows you to include or remove features, so you can start building quickly without the hassle of setting up everything from scratch. Spawn simplifies the process, especially for new developers, by removing guesswork and speeding up the setup.","s":"Spawn Overview","u":"/spawn/v0.50/","h":"/spawn/v0.50/#spawn-overview","p":8},{"i":17,"t":"Get started building using the new-chain command. Spawn will guide you through the process of selecting the modules you need and configuring your new chain. Using --help will showcase examples and other options you may want to consider for your new network. spawn new mychain --help Create a new project Usage: spawn new-chain [project-name] [flags] Aliases: new-chain, new, init, create Flags: -b, --binary string Application binary name (default \"simd\") --bypass-prompt Bypass UI prompter --denom string Bank token denomination (default \"token\") --org string Github organization name (default \"rollchains\") --skip-git No git repository created --wallet-prefix string Users wallet namespace (default \"cosmos\")","s":"New Development","u":"/spawn/v0.50/","h":"/spawn/v0.50/#new-development","p":8},{"i":19,"t":"You can read about different security models in the Consensus Security section. If you don't know which to select, use proof of authority. spawn new mychain After running the new command, navigate with your arrow keys and press 'enter' to select the module you want to use. You can only use 1 from this consensus list. Then select done. Consensus Selector (( enter to toggle )) Done ✔ proof-of-authority proof-of-stake interchain-security","s":"Security Selection","u":"/spawn/v0.50/","h":"/spawn/v0.50/#security-selection","p":8},{"i":21,"t":"You now select which features you want to include in your base application. Usually you would have to do these manually, each taking about 15 minutes to integrate. With spawn, you select them right away. It automatically configures them and give you testing for the assurance it works. An information guide will be displayed for each feature at the bottom of the UI, sharing information about what the feature does. Select the following then press 'enter' on done to continue. Feature Selector (( enter to toggle )) Done ✔ tokenfactory ✔ ibc-packetforward ✔ ibc-ratelimit cosmwasm wasm-light-client ✔ optimistic-execution ✔ block-explorer tokenfactory: Native token minting, sending, and burning on the chain Just like that, an entire network is generated. Everything you need to get started and more! Let's dive in.","s":"Feature Selection","u":"/spawn/v0.50/","h":"/spawn/v0.50/#feature-selection","p":8},{"i":23,"t":"Opening up this newly generated mychain/ gives you a general view into the entire layout. ls -laG .github/ app/ chains/ cmd/ contrib/ explorer/ interchaintest/ proto/ scripts/ .gitignore .goreleaser.yaml chain_metadata.json chain_registry_assets.json chain_registry.json chains.yaml docker-compose.yml Dockerfile go.mod go.sum Makefile README.md","s":"Structure","u":"/spawn/v0.50/","h":"/spawn/v0.50/#structure","p":8},{"i":25,"t":"This directory contains all the workflow actions for native github integration out of the box. It handles Integration & Unit tests for every code change Docker images saved to ghcr on a new version tag Public cloud or private hosted testnets App binary releases PR title formatting Markdown file valid link reviews","s":".github/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#github","p":8},{"i":27,"t":"App is the main location for all of the application connection logic. decorators/ - Initial logic as new transactions are received. Used to override input data, block requests, or add additional logic before the action begins initial processing. upgrades/ - You have to run an upgrade when you add or remove logic and nodes are already running different logic. This is where you put the upgrade information and state migrations. ante.go - The decorators for the entire network, wired together. app.go - The entire application connected and given access to the cosmos-sdk. The brain of the program. upgrades.go - Registers the upgrades/ folder logic when one is pending processing.","s":"app/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#app","p":8},{"i":29,"t":"The chains/ directory is where the local and public testnet configuration files are placed. Reference the testnets section for more information","s":"chains/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#chains","p":8},{"i":31,"t":"The cmd/ directory is the entry point for the wiring connections and is where the main.go file is located. This is where the application is started and the chain is initialized when you run the binary. By default, simd is the binary name and is saved to your $GOPATH (/home/user/go/bin/).","s":"cmd/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#cmd","p":8},{"i":33,"t":"If you enabled the explorer in the feature selection, this is where the ping.pub explorer files are located. When running a testnet with make sh-testnet or make testnet, you can launch the explorer along side the chain to view activity in real time. Blocks, transactions, uptime, connections, and more are all viewable. Easily launch it with the docker compose up command in the root of the directory.","s":"explorer/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#explorer","p":8},{"i":35,"t":"Interchaintest is a generalized integration test environment for the Interchain and beyond. It supports Cosmos, Ethereum, UTXO (Bitcoin), and other chain types. By default you will see many test like ibc_test.go, ibc_rate_limit_test.go and tokenfactory_test.go after generation. Any features you select are placed here automatically to confirm your network is working as expected. This are run with the github action automatically on every code change or you can run them manually with make local-image && make ictest-*, where the * is the testname (ictest-ibc, ictest-tokenfactory, etc).","s":"interchaintest/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#interchaintest","p":8},{"i":37,"t":"Proto, also called protocol buffers, are a generalized way to define the structure of data. Discussed this more in the Modules sub section.","s":"proto/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#proto","p":8},{"i":39,"t":"Scripts automate some more complex requirements list setting up a fast testnet or generating code on the fly. You should not need to modify anything here until you are more advanced. These are shown in the make help command to abstract away complexity.","s":"scripts/","u":"/spawn/v0.50/","h":"/spawn/v0.50/#scripts","p":8},{"i":41,"t":"A cosmetic file showcasing a format for the network. Fill in the data here once you push to the public so developers can easily see what your network is about. This is required for ICS consumer networks. If you do not use ICS, you can delete this file if you wish.","s":"chain_metadata.json","u":"/spawn/v0.50/","h":"/spawn/v0.50/#chain_metadatajson","p":8},{"i":43,"t":"These files are the format needed to upload to https://cosmos.directory/ (github). Frontends use this data to connect to the network, especially in the local-interchain testnet tool.","s":"chain_registry.json & assets","u":"/spawn/v0.50/","h":"/spawn/v0.50/#chain_registryjson--assets","p":8},{"i":45,"t":"We're all here to build new logic on top. The SDK calls these modules, or extensions, x/ for short. To make this easy spawn has a build in generator for a module. spawn module new --help Usage: spawn module new [name] [flags] Aliases: new, c, create Examples: spawn module new mymodule [--ibc-module] Flags: --ibc-middleware Set the module as an IBC Middleware --ibc-module Set the module as an IBC Module All you need to have is the name you wish to call it, and if you want standard or an IBC module. IBC enables cross network communication of the logic. This is a powerful feature that allows you to build a network of networks. You can try this out with the IBC module demo demo. For now, just create a default module called example spawn module new example 🎉 New Module 'example' generated! 🏅 Commands: - $ make proto-gen # convert proto files into code This created a new x/example module and the proto/ files in the expected structure. genesis.proto contains the data saved and more hardcoded. query.proto is how you allow external actors to grab data from the network and tx.proto is how you allow external actors to send data to the network. Spawn also connects it to the application if you look through your app/app.go. Learn how to make a new module with the Name Service guide.","s":"Modules","u":"/spawn/v0.50/","h":"/spawn/v0.50/#modules","p":8},{"i":47,"t":"This uses the local-interchain format and supports JSON or YAML. By default, 2 IBC network defaults are included. self-ibc and testnet. Run the testnet with make testnet to automatically build, setup, and launch a complex network simply. Self IBC is really only useful if you are building IBC Modules. Follow that guide to see how to use it.","s":"Testnets","u":"/spawn/v0.50/","h":"/spawn/v0.50/#testnets","p":8},{"i":49,"t":"You now need to set the data structure in the keeper to store the wallet to name pair. Keeper's are where the data is stored for future use. x/nameservice/keeper/keeper.go type Keeper struct { ... NameMapping collections.Map[string, string] } ... func NewKeeper() Keeper { ... k := Keeper{ ... NameMapping: collections.NewMap(sb, collections.NewPrefix(1), \"name_mapping\", collections.StringKey, collections.StringValue), } }","s":"Save Storage Structure","u":"/spawn/v0.50/build/name-service-application/","h":"","p":48},{"i":51,"t":"Update the msg_server logic to set the name upon request from a user. x/nameservice/keeper/msg_server.go func (ms msgServer) SetServiceName(ctx context.Context, msg *types.MsgSetServiceName) (*types.MsgSetServiceNameResponse, error) { if err := ms.k.NameMapping.Set(ctx, msg.Sender, msg.Name); err != nil { return nil, err } return &types.MsgSetServiceNameResponse{}, nil } and also for the query_server to retrieve the name. x/nameservice/keeper/query_server.go func (k Querier) ResolveName(goCtx context.Context, req *types.QueryResolveNameRequest) (*types.QueryResolveNameResponse, error) { v, err := k.Keeper.NameMapping.Get(goCtx, req.Wallet) if err != nil { return nil, err } return &types.QueryResolveNameResponse{ Name: v, }, nil }","s":"Application Logic","u":"/spawn/v0.50/build/name-service-application/","h":"/spawn/v0.50/build/name-service-application/#application-logic","p":48},{"i":54,"t":"It seems the nameservice will let you set any name length you want. Add a validation check in SetServiceName to ensure the name is less than 32 characters long. Hint #1 The SetServiceName in the msg_server.go looks like an interesting place to start. It should return an error if the name is too long. Solution If a user attempts to submit a name longer than 32 characters, it will return an error that is not allowed. x/nameservice/keeper/msg_server.go // SetServiceName implements types.MsgServer. func (ms msgServer) SetServiceName(ctx context.Context, msg *types.MsgSetServiceName) (*types.MsgSetServiceNameResponse, error) { if len(msg.Name) > 32 { return nil, fmt.Errorf(\"name cannot be longer than 32 characters\") } if err := ms.k.NameMapping.Set(ctx, msg.Sender, msg.Name); err != nil { return nil, err } return &types.MsgSetServiceNameResponse{}, nil }","s":"Challenge 1: Limit Input","u":"/spawn/v0.50/build/name-service-bonus/","h":"/spawn/v0.50/build/name-service-bonus/#challenge-1-limit-input","p":52},{"i":56,"t":"Currently the nameservice only allows you to resolve a name given a wallet. If someone has a name they should be able to resolve the wallet address. Add a new query to the query_server and autocli client to resolve a wallet address from a name. This challenge is signinicantly harder and will some previous Go programming knowledge with iterators. You can also just copy the solutions. Hint #1 Create a new query.proto for ResolveWallet that takes in a name string Solution #1 proto/nameservice/v1/query.proto // Query provides defines the gRPC querier service. service Query { // Params queries all parameters of the module. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = \"/nameservice/v1/params\"; } // ResolveName allows a user to resolve the name of an account. rpc ResolveName(QueryResolveNameRequest) returns (QueryResolveNameResponse) { option (google.api.http).get = \"/nameservice/v1/name/{wallet}\"; } // ResolveWallet allows a user to resolve the wallet of a name. rpc ResolveWallet(QueryResolveWalletRequest) returns (QueryResolveWalletResponse) { option (google.api.http).get = \"/nameservice/v1/wallet/{name}\"; } } message QueryResolveWalletRequest { string name = 1; } message QueryResolveWalletResponse { string wallet = 1; } make proto-gen Hint #2 Iterate through the k.Keeper.NameMapping, check the Value(). if it matches the name requested, return that wallet (Key) Solution #2 x/nameservice/keeper/query_server.go // ResolveWallet implements types.QueryServer. func (k Querier) ResolveWallet(goCtx context.Context, req *types.QueryResolveWalletRequest) (*types.QueryResolveWalletResponse, error) { // create a way to iterate over all the name mappings. iter, err := k.Keeper.NameMapping.Iterate(goCtx, nil) if err != nil { return nil, err } defer iter.Close() for ; iter.Valid(); iter.Next() { // get the value (name) v, err := iter.Value() if err != nil { return nil, err } // if current name matches the requested name, // return the wallet address for the name if v == req.Name { walletAddr, err := iter.Key() if err != nil { return nil, err } return &types.QueryResolveWalletResponse{ Wallet: walletAddr, }, nil } } return nil, fmt.Errorf(\"wallet not found for name %s\", req.Name) } This is not the most efficient way to do this. If you would like, create a new WalletMapping collection that maps name->sender when SetServiceName is called. This way you can resolve the wallet from the name in O(1) time (i.e. instant) instead of looping through all possible wallets. Hint #3 Add the AutoCLI method to ResolveWallet with the ProtoField \"name\" to match the .proto file Solution #3 x/nameservice/autocli.go func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { return &autocliv1.ModuleOptions{ Query: &autocliv1.ServiceCommandDescriptor{ Service: modulev1.Query_ServiceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ { RpcMethod: \"ResolveName\", Use: \"resolve [wallet]\", Short: \"Resolve the name of a wallet address\", PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: \"wallet\"}, }, }, { RpcMethod: \"ResolveWallet\", Use: \"wallet [name]\", Short: \"Resolve the wallet address from a given name\", PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: \"name\"}, }, }, { RpcMethod: \"Params\", Use: \"params\", Short: \"Query the current module parameters\", }, }, }, ... Then make install and re-run the testnet to verify rolld q nameservice wallet Unreleased Docs Here
+
+
+
\ No newline at end of file
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 00000000..08266791
--- /dev/null
+++ b/sitemap.xml
@@ -0,0 +1 @@
+Search the documentation
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-bonus/index.html b/v0.50/build/name-service-bonus/index.html
new file mode 100644
index 00000000..8f26d061
--- /dev/null
+++ b/v0.50/build/name-service-bonus/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+Save Storage Structure
+
+
+x/nameservice/keeper/keeper.go
type Keeper struct {
...
NameMapping collections.Map[string, string]
}
...
func NewKeeper() Keeper {
...
k := Keeper{
...
NameMapping: collections.NewMap(sb, collections.NewPrefix(1), "name_mapping", collections.StringKey, collections.StringValue),
}
}
+Application Logic
+
+x/nameservice/keeper/msg_server.gofunc (ms msgServer) SetServiceName(ctx context.Context, msg *types.MsgSetServiceName) (*types.MsgSetServiceNameResponse, error) {
if err := ms.k.NameMapping.Set(ctx, msg.Sender, msg.Name); err != nil {
return nil, err
}
return &types.MsgSetServiceNameResponse{}, nil
}
+x/nameservice/keeper/query_server.gofunc (k Querier) ResolveName(goCtx context.Context, req *types.QueryResolveNameRequest) (*types.QueryResolveNameResponse, error) {
v, err := k.Keeper.NameMapping.Get(goCtx, req.Wallet)
if err != nil {
return nil, err
}
return &types.QueryResolveNameResponse{
Name: v,
}, nil
}
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-client/index.html b/v0.50/build/name-service-client/index.html
new file mode 100644
index 00000000..6ad92a78
--- /dev/null
+++ b/v0.50/build/name-service-client/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+Extra Challenges
+Challenge 1: Limit Input
+SetServiceName
to ensure the name is less than 32 characters long.
+Hint #1
SetServiceName
in the msg_server.go looks like an interesting place to start. It should return an error if the name is too long.
+Solution
x/nameservice/keeper/msg_server.go// SetServiceName implements types.MsgServer.
func (ms msgServer) SetServiceName(ctx context.Context, msg *types.MsgSetServiceName) (*types.MsgSetServiceNameResponse, error) {
if len(msg.Name) > 32 {
return nil, fmt.Errorf("name cannot be longer than 32 characters")
}
if err := ms.k.NameMapping.Set(ctx, msg.Sender, msg.Name); err != nil {
return nil, err
}
return &types.MsgSetServiceNameResponse{}, nil
}Challenge 2: Resolve Wallet From Name
+query_server
and autocli client to resolve a wallet address from a name.
+
+
+Hint #1
+Solution #1
proto/nameservice/v1/query.proto// Query provides defines the gRPC querier service.
service Query {
// Params queries all parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/nameservice/v1/params";
}
// ResolveName allows a user to resolve the name of an account.
rpc ResolveName(QueryResolveNameRequest) returns (QueryResolveNameResponse) {
option (google.api.http).get = "/nameservice/v1/name/{wallet}";
}
// ResolveWallet allows a user to resolve the wallet of a name.
rpc ResolveWallet(QueryResolveWalletRequest) returns (QueryResolveWalletResponse) {
option (google.api.http).get = "/nameservice/v1/wallet/{name}";
}
}
message QueryResolveWalletRequest {
string name = 1;
}
message QueryResolveWalletResponse {
string wallet = 1;
}make proto-gen
+Hint #2
k.Keeper.NameMapping
, check the Value(). if it matches the name requested, return that wallet (Key)
+Solution #2
x/nameservice/keeper/query_server.go// ResolveWallet implements types.QueryServer.
func (k Querier) ResolveWallet(goCtx context.Context, req *types.QueryResolveWalletRequest) (*types.QueryResolveWalletResponse, error) {
// create a way to iterate over all the name mappings.
iter, err := k.Keeper.NameMapping.Iterate(goCtx, nil)
if err != nil {
return nil, err
}
defer iter.Close()
for ; iter.Valid(); iter.Next() {
// get the value (name)
v, err := iter.Value()
if err != nil {
return nil, err
}
// if current name matches the requested name,
// return the wallet address for the name
if v == req.Name {
walletAddr, err := iter.Key()
if err != nil {
return nil, err
}
return &types.QueryResolveWalletResponse{
Wallet: walletAddr,
}, nil
}
}
return nil, fmt.Errorf("wallet not found for name %s", req.Name)
}SetServiceName
is called. This way you can resolve the wallet from the name in O(1) time (i.e. instant) instead of looping through all possible wallets.
+Hint #3
ResolveWallet
with the ProtoField
"name" to match the .proto fileSolution #3
x/nameservice/autocli.gofunc (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
return &autocliv1.ModuleOptions{
Query: &autocliv1.ServiceCommandDescriptor{
Service: modulev1.Query_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "ResolveName",
Use: "resolve [wallet]",
Short: "Resolve the name of a wallet address",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "wallet"},
},
},
{
RpcMethod: "ResolveWallet",
Use: "wallet [name]",
Short: "Resolve the wallet address from a given name",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "name"},
},
},
{
RpcMethod: "Params",
Use: "params",
Short: "Query the current module parameters",
},
},
},
...make install
and re-run the testnet to verify rolld q nameservice wallet <name>
returns the expected wallet address.
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-ibc-contract/index.html b/v0.50/build/name-service-ibc-contract/index.html
new file mode 100644
index 00000000..6a56610f
--- /dev/null
+++ b/v0.50/build/name-service-ibc-contract/index.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+Command Line Client
+Query
+
+x/nameservice/autocli.go Query: &autocliv1.ServiceCommandDescriptor{
Service: modulev1.Query_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "ResolveName",
Use: "resolve [wallet]",
Short: "Resolve the name of a wallet address",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "wallet"},
},
},
{
RpcMethod: "Params",
Use: "params",
Short: "Query the current module parameters",
},
},
},
+AutoCLI Query
Transaction
+x/nameservice/autocli.go
to set the name of a wallet account.
+x/nameservice/autocli.go Tx: &autocliv1.ServiceCommandDescriptor{
Service: modulev1.Msg_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "SetServiceName",
Use: "set [name]",
Short: "Set the mapping to your wallet address",
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
{ProtoField: "name"},
},
},
{
// NOTE: this is already included in the current source
RpcMethod: "UpdateParams",
Skip: false,
},
},
},AutoCLI Tx
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-ibc-module/index.html b/v0.50/build/name-service-ibc-module/index.html
new file mode 100644
index 00000000..349659c3
--- /dev/null
+++ b/v0.50/build/name-service-ibc-module/index.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+IBC Name Service Contract
+Prerequisites
+
+Setup the Chain
+
+GITHUB_USERNAME=rollchains
spawn new cwchain \
--consensus=proof-of-stake \
--bech32=roll \
--denom=uroll \
--bin=rolld \
--disabled=block-explorer \
--org=${GITHUB_USERNAME}
# move into the chain directory
cd cwchain
# download latest dependencies
go mod tidyBuild CosmWasm Contract
+nameservice-contract
name provided on a specific commit.
+cargo generate --git https://github.com/CosmWasm/cw-template.git \
--name nameservice-contract \
--force-git-init \
-d minimal=true --tag a2a169164324aa1b48ab76dd630f75f504e41d99
+Info
+# open using vscode in the terminal
code nameservice-contract/Update Contract Dependencies
+Cargo.toml
file and add the "ibc3" capability (for IBC support).
+Cargo.toml[dependencies]
cosmwasm-schema = "1.5.7"
cosmwasm-std = { version = "1.5.7", features = [
# "cosmwasm_1_3",
"ibc3"
] }
+cargo update
Setup State
+
+src/state.rsuse std::collections::BTreeMap;
use cw_storage_plus::Map;
// Pair the wallet address to the name a user provides.
pub type WalletMapping = BTreeMap<String, String>;
/// create a new empty wallet mapping for a channel.
/// useful if a channel is opened and we have no data yet
pub fn new_wallet_mapping() -> WalletMapping {
BTreeMap::new()
}
/// Name Service maps for each channel saved to a storage object
pub const NAME_SERVICE: Map<String, WalletMapping> = Map::new("nameservice");Setup Interactions
+
+src/msg.rsuse cosmwasm_schema::{cw_serde, QueryResponses};
#[cw_serde]
pub struct InstantiateMsg {}
#[cw_serde]
pub enum ExecuteMsg {
SetName { channel: String, name: String },
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(GetNameResponse)]
GetName { channel: String, wallet: String },
}
#[cw_serde]
pub enum IbcExecuteMsg {
SetName { wallet: String, name: String },
}
#[cw_serde]
pub struct GetNameResponse {
pub name: String,
}Contract Logic
+
+src/contract.rs#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, IbcExecuteMsg, InstantiateMsg, QueryMsg};
use cosmwasm_std::{to_json_binary, IbcMsg, IbcTimeout, StdError};
+src/contract.rs#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
_msg: InstantiateMsg,
) -> Result<Response, ContractError> {
Ok(Response::new().add_attribute("method", "instantiate"))
}
+src/contract.rs#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
_deps: DepsMut,
env: Env, // removes the underscore _
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::SetName { channel, name } => {
Ok(Response::new()
.add_attribute("method", "set_name")
.add_attribute("channel", channel.clone())
// outbound IBC message, where packet is then received on other chain
.add_message(IbcMsg::SendPacket {
channel_id: channel,
data: to_json_binary(&IbcExecuteMsg::SetName {
name: name,
wallet: info.sender.into_string(),
})?,
// default timeout of two minutes.
timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(120)),
}))
}
}
}NAME_SERVICE
storage Map defined in state.rs
. Using may load grabs the data if the channel has a name set. If no channel is found (no users have set a name from this chain), it returns an error to the user requesting. If a channel of pairs is found, it loads them and checks if the wallet address requested is set in it. If it is, return what the wallets name is set to. If the user with this wallet did not set a name, return an error.
+src/contract.rs#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::GetName { channel, wallet } => {
crate::state::NAME_SERVICE
.may_load(deps.storage, channel.clone())
.and_then(|maybe_wallets| match maybe_wallets {
Some(wallets) => match wallets.get(&wallet) {
Some(wallet) => Ok(to_json_binary(&crate::msg::GetNameResponse {
name: wallet.clone(),
})?),
None => Err(StdError::generic_err("No name set for wallet")),
},
None => Err(StdError::generic_err("Channel not found")),
})
}
}
}try_set_name
method. It updates a given channel to include a new wallet. If the wallet already exists, it will overwrite the name. It then returns the users name back, or an error, for our future IBC logic to handle.
+src/contract.rs/// called on IBC packet receive in other chain
pub fn try_set_name(
deps: DepsMut,
channel: String,
wallet: String,
name: String,
) -> Result<String, StdError> {
crate::state::NAME_SERVICE.update(deps.storage, channel, |wallets| -> StdResult<_> {
let mut wallets = wallets.unwrap_or_default();
wallets.insert(wallet, name.clone());
Ok(wallets)
})?;
Ok(name)
}Create Transaction acknowledgement
+ack.rs
, to handle the IBC ACK (acknowledgement) messages. This just returns back to the user if their interaction was a success or an error.
+touch src/ack.rs
+src/ack.rsuse cosmwasm_schema::cw_serde;
use cosmwasm_std::{to_json_binary, Binary};
/// IBC ACK. See:
/// https://github.com/cosmos/cosmos-sdk/blob/f999b1ff05a4db4a338a855713864497bedd4396/proto/ibc/core/channel/v1/channel.proto#L141-L147
#[cw_serde]
pub enum Ack {
Result(Binary),
Error(String),
}
pub fn make_ack_success() -> Binary {
let res = Ack::Result(b"1".into());
to_json_binary(&res).unwrap()
}
pub fn make_ack_fail(err: String) -> Binary {
let res = Ack::Error(err);
to_json_binary(&res).unwrap()
}
+Note
+src/lib.rspub mod ack;
pub mod contract;
...
pub use crate::error::ContractError;Setup Errors
+
+src/error.rsuse cosmwasm_std::StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),
#[error("Unauthorized")]
Unauthorized {},
// Add any other custom errors you like here.
// Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
#[error("invalid IBC channel version. Got ({actual}), expected ({expected})")]
InvalidVersion { actual: String, expected: String },
#[error("only unordered channels are supported")]
OrderedChannel {},
}
// There is an IBC specific error that is never returned.
#[derive(Error, Debug)]
pub enum Never {}IBC Specific Logic
+ibc.rs
. Add this to the lib.rs. This is where our core IBC logic will go.
+touch src/ibc.rs
+src/lib.rspub mod ibc;
pub mod ack;
pub mod contract;
mod error;
pub mod helpers;
pub mod msg;
pub mod state;
pub use crate::error::ContractError;
+src/ibc.rs#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
from_json, DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg,
IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcOrder, IbcPacketAckMsg,
IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse,
};
use crate::{
ack::{make_ack_fail, make_ack_success},
contract::try_set_name,
msg::IbcExecuteMsg,
state::NAME_SERVICE,
ContractError,
};
pub const IBC_VERSION: &str = "ns-1";
pub fn validate_order_and_version(
channel: &IbcChannel,
counterparty_version: Option<&str>,
) -> Result<(), ContractError> {
// We expect an unordered channel here. Ordered channels have the
// property that if a message is lost the entire channel will stop
// working until you start it again.
if channel.order != IbcOrder::Unordered {
return Err(ContractError::OrderedChannel {});
}
if channel.version != IBC_VERSION {
return Err(ContractError::InvalidVersion {
actual: channel.version.to_string(),
expected: IBC_VERSION.to_string(),
});
}
// Make sure that we're talking with a counterparty who speaks the
// same "protocol" as us.
//
// For a connection between chain A and chain B being established
// by chain A, chain B knows counterparty information during
// `OpenTry` and chain A knows counterparty information during
// `OpenAck`. We verify it when we have it but when we don't it's
// alright.
if let Some(counterparty_version) = counterparty_version {
if counterparty_version != IBC_VERSION {
return Err(ContractError::InvalidVersion {
actual: counterparty_version.to_string(),
expected: IBC_VERSION.to_string(),
});
}
}
Ok(())
}
+src/ibc.rs/// Handles the `OpenInit` and `OpenTry` parts of the IBC handshake.
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn ibc_channel_open(
_deps: DepsMut,
_env: Env,
msg: IbcChannelOpenMsg,
) -> Result<IbcChannelOpenResponse, ContractError> {
validate_order_and_version(msg.channel(), msg.counterparty_version())?;
Ok(None)
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn ibc_channel_close(
deps: DepsMut,
_env: Env,
msg: IbcChannelCloseMsg,
) -> Result<IbcBasicResponse, ContractError> {
let channel = msg.channel().endpoint.channel_id.clone();
NAME_SERVICE.remove(deps.storage, channel.clone());
Ok(IbcBasicResponse::new()
.add_attribute("method", "ibc_channel_close")
.add_attribute("channel", channel))
}
+src/ibc.rs#[cfg_attr(not(feature = "library"), entry_point)]
pub fn ibc_channel_connect(
deps: DepsMut,
_env: Env,
msg: IbcChannelConnectMsg,
) -> Result<IbcBasicResponse, ContractError> {
validate_order_and_version(msg.channel(), msg.counterparty_version())?;
let channel = msg.channel().endpoint.channel_id.clone();
NAME_SERVICE.save(
deps.storage, channel.clone(), &crate::state::new_wallet_mapping(),
)?;
Ok(IbcBasicResponse::new()
.add_attribute("method", "ibc_channel_connect")
.add_attribute("channel_id", channel))
}do_ibc_packet_receive
. It takes the channel and the packet data (the IbcMsg::SetName sent out from the ExecuteMsg earlier), and tries to set the name on a wallet for this channel. If successful, it returns an acknowledgment of success. If not, it returns an acknowledgment of failure. The user will see this in their log event output.
+src/ibc.rs#[cfg_attr(not(feature = "library"), entry_point)]
pub fn ibc_packet_receive(
deps: DepsMut,
_env: Env,
msg: IbcPacketReceiveMsg,
) -> Result<IbcReceiveResponse, crate::error::Never> {
// Regardless of if our processing of this packet works we need to
// commit an ACK to the chain. As such, we wrap all handling logic
// in a septate function and on error write out an error ack.
match do_ibc_packet_receive(deps, msg) {
Ok(response) => Ok(response),
Err(error) => Ok(IbcReceiveResponse::new()
.add_attribute("method", "ibc_packet_receive")
.add_attribute("error", error.to_string())
.set_ack(make_ack_fail(error.to_string()))),
}
}
pub fn do_ibc_packet_receive(
deps: DepsMut,
msg: IbcPacketReceiveMsg,
) -> Result<IbcReceiveResponse, ContractError> {
// The channel this packet is being relayed along on this chain.
let channel = msg.packet.dest.channel_id;
let msg: IbcExecuteMsg = from_json(&msg.packet.data)?;
match msg {
IbcExecuteMsg::SetName { wallet, name } => {
let name = try_set_name(deps, channel, wallet, name)?;
Ok(IbcReceiveResponse::new()
.add_attribute("method", "execute_increment")
.add_attribute("name", name)
.set_ack(make_ack_success()))
}
}
}
+src/ibc.rs#[cfg_attr(not(feature = "library"), entry_point)]
pub fn ibc_packet_ack(
_deps: DepsMut,
_env: Env,
_ack: IbcPacketAckMsg,
) -> Result<IbcBasicResponse, ContractError> {
Ok(IbcBasicResponse::new().add_attribute("method", "ibc_packet_ack"))
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn ibc_packet_timeout(
_deps: DepsMut,
_env: Env,
_msg: IbcPacketTimeoutMsg,
) -> Result<IbcBasicResponse, ContractError> {
Ok(IbcBasicResponse::new().add_attribute("method", "ibc_packet_timeout"))
}Build Contract From Source
+
+cargo-run-script optimize
+Start the chains and connect
+cwchain
directory to begin interacting and uploading the contract to the chain. It is time to start the cosmwasm chain and launch a testnet that connects to itself. The self-ibc
chain is automatically generated for you on the creation with spawn. It launches 2 of your networks, localchain-1 and localchain-2, and connects them with a relayer operator at startup.
+# Build docker image, set configs, keys, and install binary
#
# Error 1 (ignored) codes are okay here if you already have
# the keys and configs setup. If so you only have to `make local-image`
# in future runs :)
make setup-testnet
local-ic start self-ibcStore the Contract on both chains
+
+RPC_1=`curl http://127.0.0.1:8080/info | jq -r .logs.chains[0].rpc_address`
RPC_2=`curl http://127.0.0.1:8080/info | jq -r .logs.chains[1].rpc_address`
echo "Using RPC_1=$RPC_1 and RPC_2=$RPC_2"
CONTRACT_SOURCE=./nameservice-contract/artifacts/nameservice_contract.wasm
rolld tx wasm store $CONTRACT_SOURCE --from=acc0 --gas=auto --gas-adjustment=2.0 --yes --node=$RPC_1
# rolld q wasm list-code --node=$RPC_1
rolld tx wasm store $CONTRACT_SOURCE --from=acc0 --gas=auto --gas-adjustment=2.0 --yes --node=$RPC_2 --chain-id=localchain-2
# rolld q wasm list-code --node=$RPC_2Instantiate our Contract on both chains
+
+rolld tx wasm instantiate 1 '{}' --no-admin --from=acc0 --label="ns-1" --gas=auto --gas-adjustment=2.0 --yes --node=$RPC_1
rolld tx wasm instantiate 1 '{}' --no-admin --from=acc0 --label="ns-1" --gas=auto --gas-adjustment=2.0 --yes --node=$RPC_2 --chain-id=localchain-2
rolld q wasm list-contracts-by-creator roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87
rolld q wasm list-contracts-by-creator roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87 --node=$RPC_2
NSERVICE_CONTRACT=roll14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjczpjhRelayer connect
+Error context canceled
is fine to see. You will verify they were opened in the next step.
+# Import the testnet interaction helper functions
# for local-interchain
curl -s https://raw.githubusercontent.com/strangelove-ventures/interchaintest/main/local-interchain/bash/source.bash > ict_source.bash
source ./ict_source.bash
API_ADDR="http://localhost:8080"
# This will take a moment.
ICT_RELAYER_EXEC "$API_ADDR" "localchain-1" \
"rly tx link localchain-1_localchain-2 --src-port wasm.${NSERVICE_CONTRACT} --dst-port=wasm.${NSERVICE_CONTRACT} --order unordered --version ns-1"Verify channels
+
+# app binary
rolld q ibc channel channels
# relayer
ICT_RELAYER_EXEC "$API_ADDR" "localchain-1" "rly q channels localchain-1"Transaction interaction
+
+# Set the name from chain 1
MESSAGE='{"set_name":{"channel":"channel-1","name":"myname"}}'
rolld tx wasm execute $NSERVICE_CONTRACT "$MESSAGE" --from=acc0 --gas=auto --gas-adjustment=2.0 --yes
# This will take a moment
# 'account sequence mismatch' errors are fine.
ICT_RELAYER_EXEC "$API_ADDR" "localchain-1" "rly tx flush"
+Verify data
+
+# query the name on chain 2, from chain 1
rolld q wasm state smart $NSERVICE_CONTRACT '{"get_name":{"channel":"channel-1","wallet":"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87"}}' --node=$RPC_2
# dump contract state from the other chain
rolld q wasm state all $NSERVICE_CONTRACT --node=$RPC_2Summary
+What you Learned
+
+
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-structure/index.html b/v0.50/build/name-service-structure/index.html
new file mode 100644
index 00000000..f192af6e
--- /dev/null
+++ b/v0.50/build/name-service-structure/index.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+IBC Name Service Module
+Prerequisites
+
+Create your chain
+rollchain
, with the nameservice module from the nameservice tutorial. If you do not, complete that tutorial now.
+warningkillall -9 rolld
Scaffold the IBC Module
+
+# if you are not already in the chain directory:
cd rollchain
# scaffold the base IBC module for The
# cross chain name service
spawn module new nsibc --ibc-module
# compile latest code with matching module name
# failure to do this will result in: `panic: reflect: New(nil)`
make proto-genUse the NameService Module
+
+x/nsibc/keeper/keeper.goimport (
...
nameservicekeeper "github.com/rollchains/rollchain/x/nameservice/keeper"
)
type Keeper struct {
...
NameServiceKeeper *nameservicekeeper.Keeper
}
+Keeper Setup Image
+x/nsibc/keeper/keeper.go// NewKeeper creates a new Keeper instance.
func NewKeeper(
...
nsk *nameservicekeeper.Keeper,
) Keeper {
...
k := Keeper{
...
NameServiceKeeper: nsk,
}
+NewKeeper Image
Provide NameService to the IBC Module
+app/app.go
file. Find where the NameService IBC line is and update it to include the &app.NameserviceKeeper,
reference.NameserviceKeeper
set just after the NsibcKeeper
is set. If you would like to re-order the original NameService keeper, you can do so.
+app/app.go // Create the nsibc IBC Module Keeper
app.NsibcKeeper = nsibckeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(keys[nsibctypes.StoreKey]),
app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.PortKeeper,
scopedNsibc,
&app.NameserviceKeeper, // This line added here
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
+Application NameService Reference Image
Set Name on IBC Packet
+OnRecvPacket
method has a placeholder for where the logic should run called handleOnRecvLogic
. Find the OnRecvPacket
in the ibc_module.go file, then find where the handleOnRecvLogic
method resides.
+x/nsibc/ibc_module.go// Find this method in the file
func (im ExampleIBCModule) handleOnRecvLogic(ctx context.Context, data types.ExamplePacketData) error {
...
return nil
}
+handleOnRecvLogic location
+x/nsibc/ibc_module.gofunc (im ExampleIBCModule) handleOnRecvLogic(ctx context.Context, data types.ExamplePacketData) error {
if len(data.SomeData) > 32 {
return fmt.Errorf("name cannot be longer than 32 characters")
}
return im.keeper.NameServiceKeeper.NameMapping.Set(ctx, data.Sender, data.SomeData)
}
+noteStart Testnet
+
+# build chain binary
make install
# verify the binary works. if you get a panic,
# `make proto-gen`, then re `make install`
rolld
# build docker image
make local-image
# run testnet between itself and an IBC relayer
# this will take a minute
local-ic start self-ibcImport Testnet Helpers
+ICT_
commands.
+# Import the testnet interaction helper functions
# for local-interchain
curl -s https://raw.githubusercontent.com/strangelove-ventures/interchaintest/main/local-interchain/bash/source.bash > ict_source.bash
source ./ict_source.bash
API_ADDR="http://localhost:8080"
# Waits for the testnet to start
ICT_POLL_FOR_START $API_ADDR 50 && echo "Testnet started"Connect Your IBC Modules
+
+note
+# This will take a minute.
ICT_RELAYER_EXEC $API_ADDR "localchain-1" "rly tx connect localchain-1_localchain-2 --src-port=nsibc --dst-port=nsibc --order=unordered --version=nsibc-1"
# Running the channels command now shows 2 channels, one for `transfer`
# and 1 for `nsibc`, marked as channel-1.
echo `ICT_RELAYER_CHANNELS $API_ADDR "localchain-1"`Submit Name Service Name Over IBC
+
+# Set the IBC name from chain 1.
# view this command in x/nsibc/client/tx.go
rolld tx nsibc example-tx nsibc channel-1 testname --from acc0 --chain-id localchain-1 --yes
# View the logs
rolld q tx 8A2009667022BE432B60158498C2256AEED0E86E9DFF79BD11CC9EA70DEC4A8A
# Verify chain 2 set the name (
# `rolld keys show -a acc0` from chain-1
ICT_QUERY "http://localhost:8080" "localchain-2" "nameservice resolve roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87"Summary
+What you Learned
+
+
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-summary/index.html b/v0.50/build/name-service-summary/index.html
new file mode 100644
index 00000000..a41a08df
--- /dev/null
+++ b/v0.50/build/name-service-summary/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+Set Data Structure
+Set Name
+proto/nameservice/v1
directory. Edit tx.proto
to add the transaction setter message.
+proto/nameservice/v1/tx.proto
// SetServiceName allows a user to set their accounts name.
rpc SetServiceName(MsgSetServiceName) returns (MsgSetServiceNameResponse);
}
// MsgSetServiceName defines the structure for setting a name.
message MsgSetServiceName {
option (cosmos.msg.v1.signer) = "sender";
string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string name = 2;
}
// MsgSetServiceNameResponse is an empty reply.
message MsgSetServiceNameResponse {}
+Details
Get Name
+query.proto
and add the following
+proto/nameservice/v1/query.proto
// ResolveName allows a user to resolve the name of an account.
rpc ResolveName(QueryResolveNameRequest) returns (QueryResolveNameResponse) {
option (google.api.http).get = "/nameservice/v1/name/{wallet}";
}
}
// QueryResolveNameRequest grabs the name of a wallet.
message QueryResolveNameRequest {
string wallet = 1;
}
// QueryResolveNameResponse grabs the wallet linked to a name.
message QueryResolveNameResponse {
string name = 1;
}
+Details
Generate Code
+
+make proto-gen
Details
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service-testnet/index.html b/v0.50/build/name-service-testnet/index.html
new file mode 100644
index 00000000..21565f10
--- /dev/null
+++ b/v0.50/build/name-service-testnet/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+Conclusion
+What you Learned
+
+
+What's Next?
+
+
+
+
\ No newline at end of file
diff --git a/v0.50/build/name-service/index.html b/v0.50/build/name-service/index.html
new file mode 100644
index 00000000..6df40054
--- /dev/null
+++ b/v0.50/build/name-service/index.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+Running your Application
+
+Synopsis
+
Launch The Network
+sh-testnet
command (short for shell testnet) to quickly build your application, generate example wallet accounts, and start the local network on your machine.
+# Run a quick shell testnet
make sh-testnetInteract Set Name
+set
transaction to your name. In this example, use "alice". This links account acc1
address to the desired name in the keeper.$(rolld keys show acc1 -a)
is a substitute for the acc1's address. You can also use just roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87
here.
+rolld tx nameservice set alice --from=acc1 --yes
# You can verify this transaction was successful
# By querying it's unique ID.
rolld q tx 565CE77057ACBF6FB5D174231455E61E65009CD628971937C19201328E0A1FFDInteraction Get Name
+$(rolld keys show acc1 -a)
gets the unique address of the acc1 account added when you started the testnet.
+rolld q nameservice resolve roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh --output=json
rolld q nameservice resolve $(rolld keys show acc1 -a) --output=json
+{
"name": "alice"
}
+notectrl + c
or killall -9 rolld
.
+
+
+
\ No newline at end of file
diff --git a/v0.50/demo/cw-nft/index.html b/v0.50/demo/cw-nft/index.html
new file mode 100644
index 00000000..0e1561ef
--- /dev/null
+++ b/v0.50/demo/cw-nft/index.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+Overview
+
+Synopsis
+
Prerequisites
+
+Video Walkthrough
+
+Generate a New Chain
+
+
+
+spawn new rollchain --consensus=pos --disable=cosmwasm --bech32=roll --denom=uroll --bin=rolld
Scaffold the Module
+
+# moves into the rollchain directory you just generated
cd rollchain
# scaffolds your new nameservice module
spawn module new nameservice
# proto-gen proto files to go
#
# If you get a /.cache permission error, run:
# sudo chmod -R 777 $(pwd)/.cache
# sudo chown -R $USER $(pwd)/.cache
#
# If you get a cannot find module error
# go clean -modcache
#
make proto-gennameservice
in the x
and proto
directories. It also automatically connected to your application and is ready for use.
+
+
+
\ No newline at end of file
diff --git a/v0.50/demo/cw-validator-reviews/index.html b/v0.50/demo/cw-validator-reviews/index.html
new file mode 100644
index 00000000..5dcd1143
--- /dev/null
+++ b/v0.50/demo/cw-validator-reviews/index.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+Non-fungible Token Demo
+
+WarningPrerequisites
+
+
+Dangermake testnet
or use a Linux machine or a cloud-based linux instance from Hetzner or Digital Ocean for $6 per month.Create your chain
+
+GITHUB_USERNAME=rollchains
spawn new rollchain \
--consensus=proof-of-stake \
--bech32=roll \
--denom=uroll \
--bin=rolld \
--disabled=block-explorer \
--org=${GITHUB_USERNAME}
+View UI Selector
--disabled
flag; a more intuitive UI selection approach will be taken. Make sure CosmWasm is selected with the green arrow, then press done
.Start the testnet
+
+Notemake sh-testnet
does not start due to a port bind error, you can kill your previously running testnet with killall -9 rolld
, then try again.
+# move into the chain directory
cd rollchain
# - Installs the binary
# - Setups the default keys with funds
# - Starts the chain in your shell
make sh-testnetVerify CosmWasm is enabled
+
+rolld q wasm params
+Expected Output
code_upload_access:
addresses: []
permission: Everybody
instantiate_default_permission: EverybodyUpload the contract to the network
+
+# Download the the NFT contract to your machine
curl -LO https://github.com/public-awesome/cw-nfts/releases/download/v0.19.0/cw721_base.wasm
# Upload the source code to the chain
# - gas is is amount of compute resources to allocate.
rolld tx wasm store ./cw721_base.wasm --from=acc0 \
--gas=auto --gas-adjustment=2.0 --yesVerify the code was uploaded
+
+# Code id: "1" is available
rolld q wasm list-code
# See the details (A lot of spam)
rolld q tx 4601FBACBDF93E4309D92E968F8B4E7F9177BCB132B65AA363AFDC26FE6B5CB6
+Expected Code Info
(main) -> $ rolld q wasm list-code
code_infos:
- code_id: "1"
creator: roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87
data_hash: E13AA30E0D70EA895B294AD1BC809950E60FE081B322B1657F75B67BE6021B1C
instantiate_permission:
addresses: []
permission: Everybody
pagination:
next_key: null
total: "0"Create a new NFT collection
+
+Instantiate Format Source
packages/cw721/src/msg.rsloading...
+WarningERR failure when running app err="accepts 2 arg(s), received 3"
+# Get our account address for the acc0 wallet / key.
rolld keys show acc0 -a # roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87
# Create the NFT collection with our account
# as the authorized minter / creator for new NFTs.
MESSAGE='{"name":"Roll","symbol":"ROLL","minter":"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87"}'
# Create the NFT collection
rolld tx wasm instantiate 1 $MESSAGE --no-admin --from=acc0 --label="my-nft" \
--gas=auto --gas-adjustment=2.0 --yesContract address
+NFT_CONTRACT
is always the RollNFTs collection.
+# View all contract addresses a wallet has created
rolld q wasm list-contracts-by-creator roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87
# The contract address for the NFT collection just created
NFT_CONTRACT=roll14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjczpjhCreate an NFT in the collection
+
+Notetoken_uri
is a URL that points to the metadata of the NFT. This can be a JSON object or a URL to a JSON object.
+This URL can be a link to an external service like IPFS, or the raw text directly. The contract does not care, it is up to you to manage the data and build the services around it.
+Execute Format Source
packages/cw721/src/msg.rsloading...
+MESSAGE='{"mint":{"token_id":"1","owner":"roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87","token_uri":"https://onlinejpgtools.com/images/examples-onlinejpgtools/sunflower.jpg"}}'
rolld tx wasm execute $NFT_CONTRACT $MESSAGE --from=acc0 \
--gas=auto --gas-adjustment=2.0 --yesGrab this NFT data
+roll1hj5fveer5cjtn4wd6wstzugjfdxzl0xpg2te87
. Now query the contract to see the data and verify it is correct.
+Query Format Source
packages/cw721/src/msg.rsloading...
packages/cw721/src/msg.rsloading...
+# Get who is the owner of ID 1
rolld q wasm state smart $NFT_CONTRACT '{"owner_of":{"token_id":"1"}}'
# Retrieve the NFT info
rolld q wasm state smart $NFT_CONTRACT '{"nft_info":{"token_id":"1"}}'Transfer the NFT to another account
+
+Execute Format Source
packages/cw721/src/msg.rsloading...
+# Recipient account
rolld keys show acc1 -a # roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh
MESSAGE='{"transfer_nft":{"recipient":"roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh","token_id":"1"}}'
rolld tx wasm execute $NFT_CONTRACT $MESSAGE --from=acc0 --gas=auto --gas-adjustment=2.0 --yes
# Get who is the owner of 1
# Moved to: roll1efd63aw40lxf3n4mhf7dzhjkr453axur57cawh
rolld q wasm state smart $NFT_CONTRACT '{"owner_of":{"token_id":"1"}}'Conclusion
+CosmWasm Validator Reviews
+Prerequisites
+
+Setup the Chain