Urbit
  • Introduction
  • Development

    • Getting Started
    • Environment Setup
    • Grants Program
    • Project Repositories
    • Precepts
    • System Overview

      • Arvo
      • Hoon
      • Nock
      • Vere
      • Azimuth
      • Cryptography
      • Arvo

        • Overview
        • Reference

          • Cryptography
          • Filesystem Hierarchy
          • Ames

            • Overview
            • Cryptography
            • API Reference
            • Behn

              • Overview
              • API Reference
              • Clay

                • Overview
                • Architecture
                • Using Clay
                • Data Types
                • Scry Reference
                • API Reference
                • Examples
                • Dill

                  • Overview
                  • API Reference
                  • Eyre

                    • Overview
                    • External API Reference
                    • Internal API Reference
                    • Scry Reference
                    • Data Types
                    • Examples
                    • Ford

                      • Overview
                      • Gall

                        • Overview
                        • Iris

                          • API Reference
                          • Jael

                            • API Reference
                            • Concepts

                              • Subscriptions
                              • Tutorials

                                • Move Trace
                              • Userspace

                                • Overview
                                • Gall

                                  • Overview
                                  • Tutorial
                                  • API Reference
                                  • Graph Store

                                    • Graph Store Overview
                                    • Data Structure Overview
                                    • Validator Walkthrough
                                    • Advanced Info
                                    • Threads

                                      • Overview
                                      • HTTP API
                                      • Reference
                                      • Basics

                                        • Fundamentals
                                        • Bind
                                        • Input
                                        • Output
                                        • Summary
                                        • Gall

                                          • Start Thread
                                          • Take Result
                                          • Take Facts
                                          • Stop Thread
                                          • Poke Thread
                                          • Examples

                                            • Fetch JSON
                                            • Child Thread
                                            • Main-loop
                                            • Poke Agent
                                            • Scry
                                            • Take Fact
                                          • Landscape

                                            • Overview
                                            • API Reference

                                              • Graph Store
                                          • Hoon

                                            • Overview
                                            • Hoon School

                                              • 1.1 Setup
                                              • 1.1.1 Walkthrough: List of Numbers
                                              • 1.2 Nouns
                                              • 1.3 Hoon Syntax
                                              • 1.3.1 Walkthrough: Conditionals
                                              • 1.4 Gates (Hoon Functions)
                                              • 1.4.1 Walkthrough: Recursion
                                              • 1.5 Lists
                                              • 1.5.1 Walkthrough: Fibonacci Sequence
                                              • 1.6 The Subject and Its Legs
                                              • 1.6.1 Walkthrough: Ackermann Function
                                              • 1.7 Arms and Cores
                                              • 1.7.1 Walkthrough: Caesar Cipher
                                              • 1.8 Doors
                                              • 1.8.1 Bank Account
                                              • 1.9 Generators
                                              • 2.1 Atoms, Auras, and Simple Cell Types
                                              • 2.2 Type Checking and Type Inference
                                              • 2.3 Structures and Complex Types
                                              • 2.3.1 Walkthrough: Libraries
                                              • 2.3.2 Molds
                                              • 2.4 Standard Library: Trees, Sets, and Maps
                                              • 2.5 Type Polymorphism
                                              • 2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism
                                              • 2.5.2 Walkthrough: Lead Polymorphism
                                              • 2.6 Behn
                                              • 2.7 Gall
                                              • 2.7.1 Gall Walkthrough: Egg Timer
                                              • Guides

                                                • CLI apps
                                                • Parsing
                                                • Writing Aqua Tests
                                                • Reference

                                                  • Cheat Sheet
                                                  • Irregular forms
                                                  • Hoon Errors
                                                  • Hoon Style Guide
                                                  • Basic Types
                                                  • Advanced Types
                                                  • Auras
                                                  • Runes

                                                    • Atoms and strings
                                                    • Nock . ('dot')
                                                    • Wild ! ('zap')
                                                    • Change Subject = ('tis')
                                                    • Conditionals ? ('wut')
                                                    • Cores | ('bar')
                                                    • Arms + ('lus')
                                                    • Cells : ('col')
                                                    • Calls % ('cen')
                                                    • Casts ^ ('ket')
                                                    • Structures $ ('buc')
                                                    • Make ; ('mic')
                                                    • Hints ~ ('sig')
                                                    • Terminators -- and ==
                                                    • Limbs and wings

                                                      • Limbs
                                                      • Wings
                                                      • Standard library

                                                        • Table of Contents
                                                        • 1a: Basic Arithmetic
                                                        • 1b: Tree Addressing
                                                        • 1c: Molds and Mold-Builders
                                                        • 2a: Unit Logic
                                                        • 2b: List Logic
                                                        • 2c: Bit Arithmetic
                                                        • 2d: Bit Logic
                                                        • 2e: Insecure Hashing
                                                        • 2f: Noun Ordering
                                                        • 2g: Unsigned Powers
                                                        • 2h: Set Logic
                                                        • 2i: Map Logic
                                                        • 2j: Jar and Jug Logic
                                                        • 2k: Queue Logic
                                                        • 2l: Container from Container
                                                        • 2m: Container from Noun
                                                        • 2n: Functional Hacks
                                                        • 2o: Normalizing Containers
                                                        • 2p: Serialization
                                                        • 2q: Molds and Mold-Builders
                                                        • 3a: Modular and Signed Ints
                                                        • 3b: Floating Point
                                                        • 3c: Urbit Time
                                                        • 3d: SHA Hash Family
                                                        • 3e: AES encryption (Removed)
                                                        • 3f: Scrambling
                                                        • 3g: Molds and Mold-Builders
                                                        • 4a: Exotic Bases
                                                        • 4b: Text Processing
                                                        • 4c: Tank Printer
                                                        • 4d: Parsing (Tracing)
                                                        • 4e: Parsing (Combinators)
                                                        • 4f: Parsing (Rule-Builders)
                                                        • 4g: Parsing (Outside Caller)
                                                        • 4h: Parsing (ASCII Glyphs)
                                                        • 4i: Parsing (Useful Idioms)
                                                        • 4j: Parsing (Bases and Base Digits)
                                                        • 4k: Atom Printing
                                                        • 4l: Atom Parsing
                                                        • 4m: Formatting Functions
                                                        • 4n: Virtualization
                                                        • 4o: Molds
                                                        • 5a: Compiler Utilities
                                                        • 5b: Macro Expansion
                                                        • 5c: Compiler Backend & Prettyprinter
                                                        • 5d: Parser
                                                        • 5e: Caching Compiler
                                                        • 5f: Molds and Mold-Builders
                                                        • 5g: profiling support
                                                    • Nock

                                                      • Nock Definition
                                                      • Explanation
                                                      • Example
                                                      • Implementations
                                                      • Vere

                                                        • C Runtime System
                                                        • Land of Nouns
                                                        • API overview by prefix
                                                        • C in Urbit
                                                        • Writing Jets
                                                        • Cryptography
                                                        • Azimuth

                                                          • Overview
                                                          • Life and Rift
                                                          • Advanced Azimuth Tools
                                                          • Glossary

                                                            • Ames
                                                            • Aqua
                                                            • Arm
                                                            • Arvo
                                                            • Atom
                                                            • Azimuth
                                                            • Battery
                                                            • Behn
                                                            • Breach
                                                            • Bridge
                                                            • Censures
                                                            • Ceremony
                                                            • chat
                                                            • Claims
                                                            • Clay
                                                            • Comet
                                                            • Core
                                                            • Delegated Sending
                                                            • Desk
                                                            • Dill
                                                            • Document Proposal
                                                            • Dojo
                                                            • Door
                                                            • Ecliptic
                                                            • Event Log
                                                            • Eyre
                                                            • Ford
                                                            • Galaxy
                                                            • Gall
                                                            • Gate
                                                            • HD Wallet
                                                            • Hoon
                                                            • Invite Tree
                                                            • Iris
                                                            • Jael
                                                            • Jaque
                                                            • Keyfile
                                                            • Landscape
                                                            • Mark
                                                            • Moon
                                                            • Nock
                                                            • Noun
                                                            • OTA Updates
                                                            • Payload
                                                            • pH
                                                            • Pier
                                                            • Pill
                                                            • Planet
                                                            • Proxies
                                                            • Replay
                                                            • Sail/Udon
                                                            • Senate
                                                            • Ship
                                                            • ship.arvo.network
                                                            • Star
                                                            • |sync
                                                            • Trap
                                                            • Upgrade Proposal
                                                            • Vane
                                                            • Vere
                                                            • Voting
                                                            • Wallet-Generator
                                                            Urbit
                                                            • Introduction
                                                            • Development

                                                              • Getting Started
                                                              • Environment Setup
                                                              • Grants Program
                                                              • Project Repositories
                                                              • Precepts
                                                              • System Overview

                                                                • Arvo
                                                                • Hoon
                                                                • Nock
                                                                • Vere
                                                                • Azimuth
                                                                • Cryptography
                                                                • Arvo

                                                                  • Overview
                                                                  • Reference

                                                                    • Cryptography
                                                                    • Filesystem Hierarchy
                                                                    • Ames

                                                                      • Overview
                                                                      • Cryptography
                                                                      • API Reference
                                                                      • Behn

                                                                        • Overview
                                                                        • API Reference
                                                                        • Clay

                                                                          • Overview
                                                                          • Architecture
                                                                          • Using Clay
                                                                          • Data Types
                                                                          • Scry Reference
                                                                          • API Reference
                                                                          • Examples
                                                                          • Dill

                                                                            • Overview
                                                                            • API Reference
                                                                            • Eyre

                                                                              • Overview
                                                                              • External API Reference
                                                                              • Internal API Reference
                                                                              • Scry Reference
                                                                              • Data Types
                                                                              • Examples
                                                                              • Ford

                                                                                • Overview
                                                                                • Gall

                                                                                  • Overview
                                                                                  • Iris

                                                                                    • API Reference
                                                                                    • Jael

                                                                                      • API Reference
                                                                                      • Concepts

                                                                                        • Subscriptions
                                                                                        • Tutorials

                                                                                          • Move Trace
                                                                                        • Userspace

                                                                                          • Overview
                                                                                          • Gall

                                                                                            • Overview
                                                                                            • Tutorial
                                                                                            • API Reference
                                                                                            • Graph Store

                                                                                              • Graph Store Overview
                                                                                              • Data Structure Overview
                                                                                              • Validator Walkthrough
                                                                                              • Advanced Info
                                                                                              • Threads

                                                                                                • Overview
                                                                                                • HTTP API
                                                                                                • Reference
                                                                                                • Basics

                                                                                                  • Fundamentals
                                                                                                  • Bind
                                                                                                  • Input
                                                                                                  • Output
                                                                                                  • Summary
                                                                                                  • Gall

                                                                                                    • Start Thread
                                                                                                    • Take Result
                                                                                                    • Take Facts
                                                                                                    • Stop Thread
                                                                                                    • Poke Thread
                                                                                                    • Examples

                                                                                                      • Fetch JSON
                                                                                                      • Child Thread
                                                                                                      • Main-loop
                                                                                                      • Poke Agent
                                                                                                      • Scry
                                                                                                      • Take Fact
                                                                                                    • Landscape

                                                                                                      • Overview
                                                                                                      • API Reference

                                                                                                        • Graph Store
                                                                                                    • Hoon

                                                                                                      • Overview
                                                                                                      • Hoon School

                                                                                                        • 1.1 Setup
                                                                                                        • 1.1.1 Walkthrough: List of Numbers
                                                                                                        • 1.2 Nouns
                                                                                                        • 1.3 Hoon Syntax
                                                                                                        • 1.3.1 Walkthrough: Conditionals
                                                                                                        • 1.4 Gates (Hoon Functions)
                                                                                                        • 1.4.1 Walkthrough: Recursion
                                                                                                        • 1.5 Lists
                                                                                                        • 1.5.1 Walkthrough: Fibonacci Sequence
                                                                                                        • 1.6 The Subject and Its Legs
                                                                                                        • 1.6.1 Walkthrough: Ackermann Function
                                                                                                        • 1.7 Arms and Cores
                                                                                                        • 1.7.1 Walkthrough: Caesar Cipher
                                                                                                        • 1.8 Doors
                                                                                                        • 1.8.1 Bank Account
                                                                                                        • 1.9 Generators
                                                                                                        • 2.1 Atoms, Auras, and Simple Cell Types
                                                                                                        • 2.2 Type Checking and Type Inference
                                                                                                        • 2.3 Structures and Complex Types
                                                                                                        • 2.3.1 Walkthrough: Libraries
                                                                                                        • 2.3.2 Molds
                                                                                                        • 2.4 Standard Library: Trees, Sets, and Maps
                                                                                                        • 2.5 Type Polymorphism
                                                                                                        • 2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism
                                                                                                        • 2.5.2 Walkthrough: Lead Polymorphism
                                                                                                        • 2.6 Behn
                                                                                                        • 2.7 Gall
                                                                                                        • 2.7.1 Gall Walkthrough: Egg Timer
                                                                                                        • Guides

                                                                                                          • CLI apps
                                                                                                          • Parsing
                                                                                                          • Writing Aqua Tests
                                                                                                          • Reference

                                                                                                            • Cheat Sheet
                                                                                                            • Irregular forms
                                                                                                            • Hoon Errors
                                                                                                            • Hoon Style Guide
                                                                                                            • Basic Types
                                                                                                            • Advanced Types
                                                                                                            • Auras
                                                                                                            • Runes

                                                                                                              • Atoms and strings
                                                                                                              • Nock . ('dot')
                                                                                                              • Wild ! ('zap')
                                                                                                              • Change Subject = ('tis')
                                                                                                              • Conditionals ? ('wut')
                                                                                                              • Cores | ('bar')
                                                                                                              • Arms + ('lus')
                                                                                                              • Cells : ('col')
                                                                                                              • Calls % ('cen')
                                                                                                              • Casts ^ ('ket')
                                                                                                              • Structures $ ('buc')
                                                                                                              • Make ; ('mic')
                                                                                                              • Hints ~ ('sig')
                                                                                                              • Terminators -- and ==
                                                                                                              • Limbs and wings

                                                                                                                • Limbs
                                                                                                                • Wings
                                                                                                                • Standard library

                                                                                                                  • Table of Contents
                                                                                                                  • 1a: Basic Arithmetic
                                                                                                                  • 1b: Tree Addressing
                                                                                                                  • 1c: Molds and Mold-Builders
                                                                                                                  • 2a: Unit Logic
                                                                                                                  • 2b: List Logic
                                                                                                                  • 2c: Bit Arithmetic
                                                                                                                  • 2d: Bit Logic
                                                                                                                  • 2e: Insecure Hashing
                                                                                                                  • 2f: Noun Ordering
                                                                                                                  • 2g: Unsigned Powers
                                                                                                                  • 2h: Set Logic
                                                                                                                  • 2i: Map Logic
                                                                                                                  • 2j: Jar and Jug Logic
                                                                                                                  • 2k: Queue Logic
                                                                                                                  • 2l: Container from Container
                                                                                                                  • 2m: Container from Noun
                                                                                                                  • 2n: Functional Hacks
                                                                                                                  • 2o: Normalizing Containers
                                                                                                                  • 2p: Serialization
                                                                                                                  • 2q: Molds and Mold-Builders
                                                                                                                  • 3a: Modular and Signed Ints
                                                                                                                  • 3b: Floating Point
                                                                                                                  • 3c: Urbit Time
                                                                                                                  • 3d: SHA Hash Family
                                                                                                                  • 3e: AES encryption (Removed)
                                                                                                                  • 3f: Scrambling
                                                                                                                  • 3g: Molds and Mold-Builders
                                                                                                                  • 4a: Exotic Bases
                                                                                                                  • 4b: Text Processing
                                                                                                                  • 4c: Tank Printer
                                                                                                                  • 4d: Parsing (Tracing)
                                                                                                                  • 4e: Parsing (Combinators)
                                                                                                                  • 4f: Parsing (Rule-Builders)
                                                                                                                  • 4g: Parsing (Outside Caller)
                                                                                                                  • 4h: Parsing (ASCII Glyphs)
                                                                                                                  • 4i: Parsing (Useful Idioms)
                                                                                                                  • 4j: Parsing (Bases and Base Digits)
                                                                                                                  • 4k: Atom Printing
                                                                                                                  • 4l: Atom Parsing
                                                                                                                  • 4m: Formatting Functions
                                                                                                                  • 4n: Virtualization
                                                                                                                  • 4o: Molds
                                                                                                                  • 5a: Compiler Utilities
                                                                                                                  • 5b: Macro Expansion
                                                                                                                  • 5c: Compiler Backend & Prettyprinter
                                                                                                                  • 5d: Parser
                                                                                                                  • 5e: Caching Compiler
                                                                                                                  • 5f: Molds and Mold-Builders
                                                                                                                  • 5g: profiling support
                                                                                                              • Nock

                                                                                                                • Nock Definition
                                                                                                                • Explanation
                                                                                                                • Example
                                                                                                                • Implementations
                                                                                                                • Vere

                                                                                                                  • C Runtime System
                                                                                                                  • Land of Nouns
                                                                                                                  • API overview by prefix
                                                                                                                  • C in Urbit
                                                                                                                  • Writing Jets
                                                                                                                  • Cryptography
                                                                                                                  • Azimuth

                                                                                                                    • Overview
                                                                                                                    • Life and Rift
                                                                                                                    • Advanced Azimuth Tools
                                                                                                                    • Glossary

                                                                                                                      • Ames
                                                                                                                      • Aqua
                                                                                                                      • Arm
                                                                                                                      • Arvo
                                                                                                                      • Atom
                                                                                                                      • Azimuth
                                                                                                                      • Battery
                                                                                                                      • Behn
                                                                                                                      • Breach
                                                                                                                      • Bridge
                                                                                                                      • Censures
                                                                                                                      • Ceremony
                                                                                                                      • chat
                                                                                                                      • Claims
                                                                                                                      • Clay
                                                                                                                      • Comet
                                                                                                                      • Core
                                                                                                                      • Delegated Sending
                                                                                                                      • Desk
                                                                                                                      • Dill
                                                                                                                      • Document Proposal
                                                                                                                      • Dojo
                                                                                                                      • Door
                                                                                                                      • Ecliptic
                                                                                                                      • Event Log
                                                                                                                      • Eyre
                                                                                                                      • Ford
                                                                                                                      • Galaxy
                                                                                                                      • Gall
                                                                                                                      • Gate
                                                                                                                      • HD Wallet
                                                                                                                      • Hoon
                                                                                                                      • Invite Tree
                                                                                                                      • Iris
                                                                                                                      • Jael
                                                                                                                      • Jaque
                                                                                                                      • Keyfile
                                                                                                                      • Landscape
                                                                                                                      • Mark
                                                                                                                      • Moon
                                                                                                                      • Nock
                                                                                                                      • Noun
                                                                                                                      • OTA Updates
                                                                                                                      • Payload
                                                                                                                      • pH
                                                                                                                      • Pier
                                                                                                                      • Pill
                                                                                                                      • Planet
                                                                                                                      • Proxies
                                                                                                                      • Replay
                                                                                                                      • Sail/Udon
                                                                                                                      • Senate
                                                                                                                      • Ship
                                                                                                                      • ship.arvo.network
                                                                                                                      • Star
                                                                                                                      • |sync
                                                                                                                      • Trap
                                                                                                                      • Upgrade Proposal
                                                                                                                      • Vane
                                                                                                                      • Vere
                                                                                                                      • Voting
                                                                                                                      • Wallet-Generator
                                                                                                                      Urbit/Documentation/Arvo/Eyre

                                                                                                                      Examples

                                                                                                                      Contents

                                                                                                                      • Introduction
                                                                                                                      • Authenticating
                                                                                                                      • Using the Channel System
                                                                                                                      • Scrying
                                                                                                                      • Direct HTTP Handling With Gall Agents
                                                                                                                      • Generators
                                                                                                                      • Managing CORS Origins

                                                                                                                      Introduction

                                                                                                                      This documents contains practical examples of the various ways of interacting with Eyre.

                                                                                                                      General documentation of the tasks and methods described here are available in the External API Reference document and the Internal API Reference document.

                                                                                                                      Authenticating

                                                                                                                      In most cases we must obtain a valid session cookie by authenticating with our web login code (which can be obtained by running +code in the dojo) before we can use Eyre's interfaces (such as the channel system or scry interface).

                                                                                                                      Here we'll try authenticating with the default fakezod code.

                                                                                                                      Using curl in the unix terminal, we'll make an HTTP POST request with "password=" in the body:

                                                                                                                      curl -i localhost:8080/~/login -X POST -d "password=lidlut-tabwed-pillex-ridrup"

                                                                                                                      Eyre will respond with HTTP status 204, and a set-cookie header containing the session cookie.

                                                                                                                      HTTP/1.1 204 ok
                                                                                                                      Date: Tue, 18 May 2021 01:38:48 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800

                                                                                                                      The urbauth-.... cookie can be now be included in subsequent requests (e.g. to the channel system) by providing it in a Cookie HTTP header.

                                                                                                                      Using The Channel System

                                                                                                                      Here we'll look at a practical example of Eyre's channel system. You can refer to the Channels section of the External API Reference document for relevant details.

                                                                                                                      First, we must obtain a session cookie by authenticating. You will be copying the entry of the set-cookie field into the --cookie field in subsequent commands.

                                                                                                                      Now that we have our cookie, we can try poking an app & simultaneously opening a new channel. In this case, we'll poke the hood app with a mark of helm-hi to print "Opening airlock" in the dojo.

                                                                                                                      We'll do this with an HTTP PUT request, and we'll include the cookie we obtained when we authenticated in the Cookie header. The URL path we'll make the request to will be http://localhost:8080/~/channel/mychannel. The last part of the path is the channel UID - the name for our new channel. Normally you'd use the current unix time plus a hash to ensure uniqueness, but in this case we'll just use mychannel for simplicity.

                                                                                                                      The data will be a JSON array containing a poke action:

                                                                                                                      curl --header "Content-Type: application/json" \
                                                                                                                           --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
                                                                                                                           --request PUT \
                                                                                                                           --data '[{"id":1,"action":"poke","ship":"zod","app":"hood","mark":"helm-hi","json":"Opening airlock"}]' \
                                                                                                                           http://localhost:8080/~/channel/my-channel

                                                                                                                      If we now have a look in the dojo we'll see it's printed our message, so the poke was successful:

                                                                                                                      < ~zod: Opening airlock

                                                                                                                      Now we can connect to the mychannel channel we opened. We do this with an HTTP GET request with our session cookie and the same path as the last request:

                                                                                                                      curl -i --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" http://localhost:8080/~/channel/my-channel

                                                                                                                      Eyre will respond with an HTTP status code of 200 and a content-type of text/event-stream, indicating an SSE (Server Sent Event) stream. It will also send us any pending events on the channel - in this case the poke ack as a poke response for our original poke:

                                                                                                                      HTTP/1.1 200 ok
                                                                                                                      Date: Tue, 18 May 2021 01:40:47 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
                                                                                                                      connection: keep-alive
                                                                                                                      cache-control: no-cache
                                                                                                                      content-type: text/event-stream
                                                                                                                      transfer-encoding: chunked
                                                                                                                      
                                                                                                                      id: 0
                                                                                                                      data: {"ok":"ok","id":1,"response":"poke"}

                                                                                                                      Normally this event stream would be handled by an EventSource object or similar in Javascript or the equivalent in whatever other language you're using. Here, though, we'll continue using curl for simplicity.

                                                                                                                      Leaving the event stream connection open, in another shell session on unix we'll try subscribing to the watch path of a Gall agent - the /updates watch path of graph-store in this case.

                                                                                                                      We'll do this in the same way as the initial poke, except this time it will be a subscribe action:

                                                                                                                      curl --header "Content-Type: application/json" \
                                                                                                                           --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
                                                                                                                           --request PUT \
                                                                                                                           --data '[{"id":2,"action":"subscribe","ship":"zod","app":"graph-store","path":"/updates"}]' \
                                                                                                                           http://localhost:8080/~/channel/my-channel

                                                                                                                      Notice we've incremented the id to 2. Eyre doesn't require IDs to be sequential, merely numerical and unique, but sequential IDs are typically the most practical.

                                                                                                                      Back in the event stream, we'll see a positive watch ack as a subscribe response, meaning the subscription has been successful:

                                                                                                                      id: 1
                                                                                                                      data: {"ok":"ok","id":2,"response":"subscribe"}

                                                                                                                      Now we'll try trigger an event on our event stream. In fakezod's Landscape, create a new chat channel named "test". You should see the add-graph graph-update come through on our channel in a diff response:

                                                                                                                      id: 2
                                                                                                                      data: {"json":{"graph-update":{"add-graph":{"graph":{},"resource":{"name":"test-1183","ship":"zod"},"mark":"graph-validator-chat","overwrite":false}}},"id":2,"response":"diff"}

                                                                                                                      All events we receive must be acked so Eyre knows we've successfully received them. To do this we'll send an ack action which specifies the event-id of the event in question - 2 in this case:

                                                                                                                      curl --header "Content-Type: application/json" \
                                                                                                                           --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
                                                                                                                           --request PUT \
                                                                                                                           --data '[{"id":3,"action":"ack","event-id":2}]' \
                                                                                                                           http://localhost:8080/~/channel/my-channel

                                                                                                                      This same pattern would be repeated for all subsequent events. Note that when you ack one event, you also implicitly ack all previous events, so in this case event 1 will also be acked.

                                                                                                                      When we're finished, we can unsubscribe from graph-store /update. We do this by sending Eyre a unsubscribe action, and specify the request ID of the original subscribe action in the subscription field - 2 in our case:

                                                                                                                      curl --header "Content-Type: application/json" \
                                                                                                                           --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
                                                                                                                           --request PUT \
                                                                                                                           --data '[{"id":4,"action":"unsubscribe","subscription":2}]' \
                                                                                                                           http://localhost:8080/~/channel/my-channel

                                                                                                                      Unlike poke and subscribe actions, Eyre doesn't acknowledge unsubscribes, but we'll now have stopped receiving updates from graph-store.

                                                                                                                      Finally, let's close the channel itself. We can do this simply by sending Eyre a delete action:

                                                                                                                      curl --header "Content-Type: application/json" \
                                                                                                                           --cookie "urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm" \
                                                                                                                           --request PUT \
                                                                                                                           --data '[{"id":5,"action":"delete"}]' \
                                                                                                                           http://localhost:8080/~/channel/my-channel

                                                                                                                      With our channel deleted, we can now close the connection on the client side.

                                                                                                                      Scrying

                                                                                                                      Here we'll look at performing scries through Eyre. You can refer to the Scry section of the External API Reference document for relevant details.

                                                                                                                      First we must obtain a session cookie by authenticating.

                                                                                                                      Having obtained a cookie, we can now try a scry. We'll scry the graph-store Gall agent on the /x/keys scry path, which will return the list of channels it has. If you don't already have any chat channels on your fakezod, go ahead and create one via landscape so it'll have something to return.

                                                                                                                      The url path will be /~/scry/graph-store/keys.json. The /~/scry part specifies a scry, the /graph-store part is the Gall agent, the /keys is the scry path without the care, and the .json file extension specifies the return mark.

                                                                                                                      The request will be an HTTP GET request:

                                                                                                                      curl -i --cookie "urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm" \
                                                                                                                              --request GET \
                                                                                                                              http://localhost:8080/~/scry/graph-store/keys.json

                                                                                                                      Eyre will respond with HTTP status 200 if it's successful and the body of the response will contain the data we requested:

                                                                                                                      HTTP/1.1 200 ok
                                                                                                                      Date: Fri, 04 Jun 2021 10:16:32 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Content-Length: 61
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
                                                                                                                      content-type: application/json
                                                                                                                      
                                                                                                                      {"graph-update":{"keys":[{"name":"test-1183","ship":"zod"}]}}

                                                                                                                      Now let's make a request to a non-existent scry endpoint:

                                                                                                                      curl -i --cookie "urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm" \
                                                                                                                              --request GET \
                                                                                                                              http://localhost:8080/~/scry/foo/bar/baz.json

                                                                                                                      Eyre will respond with a 404 Missing status and an error message:

                                                                                                                      HTTP/1.1 404 missing
                                                                                                                      Date: Fri, 04 Jun 2021 10:22:51 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Content-Length: 187
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
                                                                                                                      content-type: text/html
                                                                                                                      
                                                                                                                      <html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>There was an error while handling the request for /foo/bar/baz.json.</p><code>no scry result</code></body></html>

                                                                                                                      Direct HTTP Handling With Gall Agents

                                                                                                                      In many cases you'll just want to interact with Gall agents through the JSON API of the channel system, but it's also possible to bypass all that and just deal with HTTP requests directly. Here we'll take a look at how that practically works.

                                                                                                                      You can refer to the %connect section of the Internal API Reference document for relevant details.

                                                                                                                      Here's a Gall agent that demonstrates this method. It binds the URL path /foo, serves

                                                                                                                      Hello, World!

                                                                                                                      for GET requests and a 405 error for all others. It also prints debug information to the terminal as various things happen.

                                                                                                                      Note that this example does a lot of things manually for demonstrative purposes. In practice you'd likely want to use a library like /lib/server.hoon to cut down on boilerplate code.

                                                                                                                      eyre-agent.hoon

                                                                                                                      /+  default-agent, dbug
                                                                                                                      =*  card  card:agent:gall
                                                                                                                      %-  agent:dbug
                                                                                                                      ^-  agent:gall
                                                                                                                      |_  =bowl:gall
                                                                                                                      +*  this      .
                                                                                                                          def   ~(. (default-agent this %|) bowl)
                                                                                                                      ::
                                                                                                                      ++  on-init  on-init:def
                                                                                                                      ++  on-save  on-save:def
                                                                                                                      ++  on-load  on-load:def
                                                                                                                      ++  on-poke
                                                                                                                        |=  [=mark =vase]
                                                                                                                        ^-  (quip card _this)
                                                                                                                        ?+    mark
                                                                                                                          (on-poke:def [mark vase])
                                                                                                                        ::
                                                                                                                            %noun
                                                                                                                          ?.  =(q.vase %bind)
                                                                                                                            %-  (slog leaf+"Bad argument." ~)
                                                                                                                            `this
                                                                                                                          %-  (slog leaf+"Attempting to bind /foo." ~)
                                                                                                                          :_  this
                                                                                                                          [%pass /bind-foo %arvo %e %connect `/'foo' %eyre-agent]~
                                                                                                                        ::
                                                                                                                            %handle-http-request
                                                                                                                          =/  req  !<  (pair @ta inbound-request:eyre)  vase
                                                                                                                          ~&  [mark req]
                                                                                                                          ?+    method.request.q.req
                                                                                                                            =/  data=octs
                                                                                                                              (as-octs:mimes:html '

                                                                                                                      405 Method Not Allowed

                                                                                                                      '
                                                                                                                      ) =/ content-length=@t (crip ((d-co:co 1) p.data)) =/ =response-header:http :- 405 :~ ['Content-Length' content-length] ['Content-Type' 'text/html'] ['Allow' 'GET'] == :_ this :~ [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)] [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)] [%give %kick [/http-response/[p.req]]~ ~] == :: %'GET' =/ data=octs (as-octs:mimes:html '

                                                                                                                      Hello, World!

                                                                                                                      '
                                                                                                                      ) =/ content-length=@t (crip ((d-co:co 1) p.data)) =/ =response-header:http :- 200 :~ ['Content-Length' content-length] ['Content-Type' 'text/html'] == :_ this :~ [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)] [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)] [%give %kick [/http-response/[p.req]]~ ~] == == == ++ on-watch |= =path ^- (quip card _this) ?+ path (on-watch:def path) :: [%http-response *] %- (slog leaf+"Eyre subscribed to {(spud path)}." ~) `this == ++ on-leave on-leave:def ++ on-peek on-peek:def ++ on-agent on-agent:def ++ on-arvo |= [=wire =sign-arvo] ^- (quip card _this) ?. ?=([%bind-foo ~] wire) (on-arvo:def [wire sign-arvo]) ?> ?=([%eyre %bound *] sign-arvo) ?: accepted.sign-arvo %- (slog leaf+"/foo bound successfully!" ~) `this %- (slog leaf+"Binding /foo failed!" ~) `this ++ on-fail on-fail:def --

                                                                                                                      Save the above to /app/eyre-agent.hoon. Commit it:

                                                                                                                      > |commit %home
                                                                                                                      >=
                                                                                                                      + /~zod/home/2/app/eyre-agent/hoon

                                                                                                                      ...and start it:

                                                                                                                      > |start %eyre-agent
                                                                                                                      >=
                                                                                                                      gall: loading %eyre-agent
                                                                                                                      activated app home/eyre-agent
                                                                                                                      [unlinked from [p=~zod q=%eyre-agent]]

                                                                                                                      Now, first we need to bind a URL to our app. In the ++ on-poke arm, our agent will send a %connect task to Eyre when poked with %bind:

                                                                                                                      %noun
                                                                                                                      ?.  =(q.vase %bind)
                                                                                                                        %-  (slog leaf+"Bad argument." ~)
                                                                                                                        `this
                                                                                                                      %-  (slog leaf+"Attempting to bind /foo." ~)
                                                                                                                      :_  this
                                                                                                                      [%pass /eyre %arvo %e %connect `/'foo' %eyre-agent]~
                                                                                                                      

                                                                                                                      ...and when %eyre responds with a %bound gift, the +on-agent arm will print whether the bind succeeded:

                                                                                                                      [%eyre %bound *]
                                                                                                                      ?:  accepted.sign-arvo
                                                                                                                        %-  (slog leaf+"/foo bound successfully!" ~)
                                                                                                                        `this
                                                                                                                      %-  (slog leaf+"Binding /foo failed!" ~)
                                                                                                                      `this
                                                                                                                      

                                                                                                                      ...so let's try:

                                                                                                                      > :eyre-agent %bind
                                                                                                                      >=
                                                                                                                      Attempting to bind /foo.
                                                                                                                      /foo bound successfully!

                                                                                                                      As you can see, we have successfully bound the /foo url path. Now we can try making an HTTP request. Over in the unix terminal, we can make a GET request using curl:

                                                                                                                      > curl -i localhost:8080/foo
                                                                                                                      HTTP/1.1 200 ok
                                                                                                                      Date: Mon, 17 May 2021 04:39:40 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      Content-Type: text/html
                                                                                                                      Content-Length: 22
                                                                                                                      transfer-encoding: chunked
                                                                                                                      
                                                                                                                      <h1>Hello, World!</h1>%

                                                                                                                      ...which has succeed! This is because the +on-poke arm tests for http GET requests and responds with Hello, World! when it sees one:

                                                                                                                      %'GET'
                                                                                                                      =/  data=octs
                                                                                                                        (as-octs:mimes:html '

                                                                                                                      Hello, World!

                                                                                                                      '
                                                                                                                      ) =/ content-length=@t (crip ((d-co:co 1) p.data)) =/ =response-header:http :- 200 :~ ['Content-Length' content-length] ['Content-Type' 'text/html'] == :_ this :~ [%give %fact [/http-response/[p.req]]~ %http-response-header !>(response-header)] [%give %fact [/http-response/[p.req]]~ %http-response-data !>(`data)] [%give %kick [/http-response/[p.req]]~ ~] ==

                                                                                                                      Back in the dojo, our app's +on-watch arm has printed the path on which Eyre has subscribed for the response:

                                                                                                                      Eyre subscribed to /http-response/~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929.

                                                                                                                      ...and it's also printed the request so you can see how it looks when it comes in:

                                                                                                                      [ %handle-http-request
                                                                                                                        p=~.~.eyre_0v3.1knjk.l544e.5uds6.fn9l2.f8929
                                                                                                                          q
                                                                                                                        [ authenticated=%.n
                                                                                                                          secure=%.n
                                                                                                                          address=[%ipv4 .127.0.0.1]
                                                                                                                            request
                                                                                                                          [ method=%'GET'
                                                                                                                            url='/foo'
                                                                                                                              header-list
                                                                                                                            ~[
                                                                                                                              [key='host' value='localhost:8080']
                                                                                                                              [key='user-agent' value='curl/7.76.1']
                                                                                                                              [key='accept' value='*/*']
                                                                                                                            ]
                                                                                                                            body=~
                                                                                                                          ]
                                                                                                                        ]
                                                                                                                      ]

                                                                                                                      This is a very rudimentary app but it demonstrates the basic mechanics of dealing with HTTP requests and serving responses.

                                                                                                                      Generators

                                                                                                                      Here we'll look at running a generator via Eyre. Eyre doesn't have a mediated JSON API for generators, instead it just passes through the HTTP request and returns the HTTP response composed by the generator.

                                                                                                                      You can refer to the %serve section of the Internal API Reference document for relevant details.

                                                                                                                      Here's a very simple generator that will just echo back the body of the request (if available) along with the current datetime. You can save it in the /gen directory and |commit %home.

                                                                                                                      Note that this example does some things manually for demonstrative purposes. In practice you'd likely want to use a library like /lib/server.hoon to cut down on boilerplate code.

                                                                                                                      eyre-gen.hoon

                                                                                                                      |=  [[now=@da eny=@uvJ bec=beak] ~ ~]
                                                                                                                      |=  [authenticated=? =request:http]
                                                                                                                      ^-  simple-payload:http
                                                                                                                      =/  msg=@t
                                                                                                                        ?~  body.request
                                                                                                                          (scot %da now)
                                                                                                                        (cat 3 (cat 3 (scot %da now) 10) q.u.body.request)
                                                                                                                      =/  data=octs
                                                                                                                        (as-octs:mimes:html msg)
                                                                                                                      =/  =response-header:http
                                                                                                                        [200 ['Content-Type' 'text/plain']~]
                                                                                                                      [response-header `data]
                                                                                                                      

                                                                                                                      Eyre requires generators to be a gate within a gate. The sample of the first gate must be:

                                                                                                                      [[now=@da eny=@uvJ bec=beak] ~ ~]
                                                                                                                      

                                                                                                                      The sample of the second nested gate must be:

                                                                                                                      [authenticated=? =request:http]
                                                                                                                      

                                                                                                                      The return type of the generator must be simple-payload:http. If you look at our example generator you'll see it meets these requirements.

                                                                                                                      Because generators return the entire HTTP message as a single simple-payload, Eyre can calculate the content-length itself and automatically add the header.

                                                                                                                      In order to make our generator available, we must bind it to a URL path. To do this, we send Eyre a %serve task, which looks like:

                                                                                                                      [%serve =binding =generator]
                                                                                                                      

                                                                                                                      The binding specifies the site and URL path, and the generator specifies the desk, the path to the generator, and arguments. Note that the passing of arguments to the generator by Eyre is not currently implemented, so you can just leave that as ~ since it won't do anything.

                                                                                                                      Let's bind our generator to the /mygen URL path with the |pass command in the dojo:

                                                                                                                      |pass [%e [%serve `/mygen %home /gen/eyre-gen/hoon ~]]

                                                                                                                      Note that Eyre responds with a %bound gift to indicate whether the binding succeeded but |pass doesn't take such responses so it's not shown.

                                                                                                                      Now let's try making an HTTP request using curl in the unix terminal:

                                                                                                                      curl -i http://localhost:8080/mygen --data 'blah blah blah'

                                                                                                                      We can see that the request has succeeded and our generator has responded with the datetime and request body:

                                                                                                                      HTTP/1.1 200 ok
                                                                                                                      Date: Sat, 29 May 2021 09:19:45 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Content-Length: 41
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      Content-Type: text/plain
                                                                                                                      Content-Length: 41
                                                                                                                      
                                                                                                                      ~2021.5.29..09.19.45..e096
                                                                                                                      blah blah blah

                                                                                                                      Managing CORS Origins

                                                                                                                      Here we'll look at approving and rejecting a CORS origin by passing Clay a %approve-origin task and %reject-origin task respectively.

                                                                                                                      In this example we'll use more manual methods for demonstrative purposes but note there are also the |cors-approve and |cors-reject generators to approve/reject origins from the dojo, and the +cors-registry generator for viewing the CORS configuration.

                                                                                                                      First, using |pass in the dojo, let's approve the origin http://foo.example by sending Eyre a %approve-origin task:

                                                                                                                      |pass [%e [%approve-origin 'http://foo.example']]

                                                                                                                      Now if we scry for the approved CORS set:

                                                                                                                      > .^(approved=(set @t) %ex /=//=/cors/approved)
                                                                                                                      approved={'http://foo.example'}

                                                                                                                      ...we can see that http://foo.example has been added.

                                                                                                                      Next, let's test it by sending Eyre a CORS preflight request via curl in unix:

                                                                                                                      curl -i -X OPTIONS \
                                                                                                                           -H "Access-Control-Request-Method: POST" \
                                                                                                                           -H "Access-Control-Request-Headers: X-Requested-With" \
                                                                                                                           -H "Origin: http://foo.example" \
                                                                                                                           http://localhost:8080

                                                                                                                      We can see in the response that it has succeeded:

                                                                                                                      HTTP/1.1 204 ok
                                                                                                                      Date: Fri, 28 May 2021 12:37:12 GMT
                                                                                                                      Connection: keep-alive
                                                                                                                      Server: urbit/vere-1.5
                                                                                                                      Access-Control-Allow-Origin: http://foo.example
                                                                                                                      Access-Control-Allow-Credentials: true
                                                                                                                      Access-Control-Allow-Headers: X-Requested-With
                                                                                                                      Access-Control-Allow-Methods: POST

                                                                                                                      Now we'll try rejecting an origin. Back in the dojo, let's |pass Eyre a %reject-origin task for http://bar.example:

                                                                                                                      |pass [%e [%reject-origin 'http://bar.example']]

                                                                                                                      If we scry for the rejected CORS set:

                                                                                                                      > .^(rejected=(set @t) %ex /=//=/cors/rejected)
                                                                                                                      rejected={'http://bar.example'}

                                                                                                                      ...we can see that http://bar.example has been added.

                                                                                                                      If we again test it with curl in unix:

                                                                                                                      curl -i -X OPTIONS \
                                                                                                                           -H "Access-Control-Request-Method: POST" \
                                                                                                                           -H "Access-Control-Request-Headers: X-Requested-With" \
                                                                                                                           -H "Origin: http://bar.example" \
                                                                                                                           http://localhost:8080

                                                                                                                      ...we can see that, as expected, it has not returned the access control headers:

                                                                                                                      HTTP/1.1 404 missing
                                                                                                                      Date: Fri, 28 May 2021 12:38:47 GMT
                                                                                                                      Connection: close
                                                                                                                      Server: urbit/vere-1.5

                                                                                                                      Finally, let's look at CORS requests that are neither approved nor rejected.

                                                                                                                      If we make another request with curl on unix, this time for http://baz.example which we haven't added to a list:

                                                                                                                      curl -i -X OPTIONS \
                                                                                                                           -H "Access-Control-Request-Method: POST" \
                                                                                                                           -H "Access-Control-Request-Headers: X-Requested-With" \
                                                                                                                           -H "Origin: http://baz.example" \
                                                                                                                           http://localhost:8080

                                                                                                                      ...we can see it also correctly fails to return the access control headers:

                                                                                                                      HTTP/1.1 404 missing
                                                                                                                      Date: Fri, 28 May 2021 12:39:59 GMT
                                                                                                                      Connection: close
                                                                                                                      Server: urbit/vere-1.5

                                                                                                                      Now if we scry for the requests CORS set:

                                                                                                                      > .^(requests=(set @t) %ex /=//=/cors/requests)
                                                                                                                      requests={'http://baz.example' 'http://localhost:8080'}

                                                                                                                      ... we can see it has automatically been added by the mere fact of the request being made.

                                                                                                                      <-

                                                                                                                      Data Types