Urbit Docs
  • What is Urbit?
  • Get on Urbit
  • Build on Urbit
    • Contents
    • Environment Setup
    • Hoon School
      • 1. Hoon Syntax
      • 2. Azimuth (Urbit ID)
      • 3. Gates (Functions)
      • 4. Molds (Types)
      • 5. Cores
      • 6. Trees and Addressing
      • 7. Libraries
      • 8. Testing Code
      • 9. Text Processing I
      • 10. Cores and Doors
      • 11. Data Structures
      • 12. Type Checking
      • 13. Conditional Logic
      • 14. Subject-Oriented Programming
      • 15. Text Processing II
      • 16. Functional Programming
      • 17. Text Processing III
      • 18. Generic and Variant Cores
      • 19. Mathematics
    • App School I
      • 1. Arvo
      • 2. The Agent Core
      • 3. Imports and Aliases
      • 4. Lifecycle
      • 5. Cards
      • 6. Pokes
      • 7. Structures and Marks
      • 8. Subscriptions
      • 9. Vanes
      • 10. Scries
      • 11. Failure
      • 12. Next Steps
      • Appendix: Types
    • App School II (Full-Stack)
      • 1. Types
      • 2. Agent
      • 3. JSON
      • 4. Marks
      • 5. Eyre
      • 6. React app setup
      • 7. React app logic
      • 8. Desk and glob
      • 9. Summary
    • Core Academy
      • 1. Evaluating Nock
      • 2. Building Hoon
      • 3. The Core Stack
      • 4. Arvo I: The Main Sequence
      • 5. Arvo II: The Boot Sequence
      • 6. Vere I: u3 and the Serf
      • 7. Vere II: The Loom
      • 8. Vanes I: Behn, Dill, Kahn, Lick
      • 9. Vanes II: Ames
      • 10. Vanes III: Eyre, Iris
      • 11. Vanes IV: Clay
      • 12. Vanes V: Gall and Userspace
      • 13. Vanes VI: Khan, Lick
      • 14. Vanes VII: Jael, Azimuth
    • Runtime
      • U3
      • Conn.c Guide
      • How to Write a Jet
      • API Overview by Prefix
      • C in Urbit
      • Cryptography
      • Land of Nouns
    • Tools
      • Useful Links
      • JS Libraries
        • HTTP API
      • Docs App
        • File Format
        • Index File
        • Suggested Structure
    • Userspace
      • Command-Line App Tutorial
      • Remote Scry
      • Unit Tests
      • Software Distribution
        • Software Distribution Guide
        • Docket File
        • Glob
      • Examples
        • Building a CLI App
        • Debugging Wrapper
        • Host a Website
        • Serving a JS Game
        • Ship Monitoring
        • Styled Text
  • Urbit ID
    • What is Urbit ID?
    • Azimuth Data Flow
    • Life and Rift
    • Urbit HD Wallet
    • Advanced Azimuth Tools
    • Custom Roller Tutorial
    • Azimuth.eth Reference
    • Ecliptic.eth Reference
    • Layer 2
      • L2 Actions
      • L2 Rollers
      • L2 Roller HTTP RPC-API
      • L2 Transaction Format
  • Urbit OS
    • What is Urbit OS?
    • Base
      • Hood
      • Threads
        • Basics Tutorial
          • Bind
          • Fundamentals
          • Input
          • Output
          • Summary
        • HTTP API Guide
        • Spider API Reference
        • Strandio Reference
        • Examples
          • Child Thread
          • Fetch JSON
          • Gall
            • Poke Thread
            • Start Thread
            • Stop Thread
            • Take Facts
            • Take Result
          • Main-loop
          • Poke Agent
          • Scry
          • Take Fact
    • Kernel
      • Arvo
        • Cryptography
        • Move Trace
        • Scries
        • Subscriptions
      • Ames
        • Ames API Reference
        • Ames Cryptography
        • Ames Data Types
        • Ames Scry Reference
      • Behn
        • Behn API Reference
        • Behn Examples
        • Behn Scry Reference
      • Clay
        • Clay API Reference
        • Clay Architecture
        • Clay Data Types
        • Clay Examples
        • Clay Scry Reference
        • Filesystem Hierarchy
        • Marks
          • Mark Examples
          • Using Marks
          • Writing Marks
        • Using Clay
      • Dill
        • Dill API Reference
        • Dill Data Types
        • Dill Scry Reference
      • Eyre
        • EAuth
        • Eyre Data Types
        • Eyre External API
        • Eyre Internal API
        • Eyre Scry Reference
        • Low-Level Eyre Guide
        • Noun channels
      • Gall
        • Gall API Reference
        • Gall Data Types
        • Gall Scry Reference
      • Iris
        • Iris API Reference
        • Iris Data Types
        • Iris Example
      • Jael
        • Jael API Reference
        • Jael Data Types
        • Jael Examples
        • Jael Scry Reference
      • Khan
        • Khan API Reference
        • Khan Data Types
        • Khan Example
      • Lick
        • Lick API Reference
        • Lick Guide
        • Lick Examples
        • Lick Scry Reference
  • Hoon
    • Why Hoon?
    • Advanced Types
    • Arvo
    • Auras
    • Basic Types
    • Cheat Sheet
    • Cryptography
    • Examples
      • ABC Blocks
      • Competitive Programming
      • Emirp
      • Gleichniszahlenreihe
      • Islands
      • Luhn Number
      • Minimum Path Sum
      • Phone Letters
      • Restore IP
      • Rhonda Numbers
      • Roman Numerals
      • Solitaire Cipher
      • Water Towers
    • Generators
    • Hoon Errors
    • Hoon Style Guide
    • Implementing an Aura
    • Irregular forms
    • JSON
    • Limbs and wings
      • Limbs
      • Wings
    • Mips (Maps of Maps)
    • Parsing Text
    • Runes
      • | bar · Cores
      • $ buc · Structures
      • % cen · Calls
      • : col · Cells
      • . dot · Nock
      • / fas · Imports
      • ^ ket · Casts
      • + lus · Arms
      • ; mic · Make
      • ~ sig · Hints
      • = tis · Subject
      • ? wut · Conditionals
      • ! zap · Wild
      • Constants (Atoms and Strings)
      • --, == · Terminators
    • Sail (HTML)
    • Serialization
    • Sets
    • Standard Library
      • 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: Molds and mold builders
      • 5f: Profiling support
    • Strings
    • The Engine Pattern
    • Udon (Markdown-esque)
    • Vases
    • Zuse
      • 2d(1-5): To JSON, Wains
      • 2d(6): From JSON
      • 2d(7): From JSON (unit)
      • 2e(2-3): Print & Parse JSON
      • 2m: Ordered Maps
  • Nock
    • What is Nock?
    • Decrement
    • Definition
    • Fast Hints and Jets
    • Implementations
    • Specification
  • User Manual
    • Contents
    • Running Urbit
      • Cloud Hosting
      • Home Servers
      • Runtime Reference
      • Self-hosting S3 Storage with MinIO
    • Urbit ID
      • Bridge Troubleshooting
      • Creating an Invite Pool
      • Get an Urbit ID
      • Guide to Factory Resets
      • HD Wallet (Master Ticket)
      • Layer 2 for planets
      • Layer 2 for stars
      • Proxies
      • Using Bridge
    • Urbit OS
      • Basics
      • Configuring S3 Storage
      • Dojo Tools
      • Filesystem
      • Shell
      • Ship Troubleshooting
      • Star and Galaxy Operations
      • Updates
Powered by GitBook

GitHub

  • Urbit ID
  • Urbit OS
  • Runtime

Resources

  • YouTube
  • Whitepaper
  • Awesome Urbit

Contact

  • X
  • Email
  • Gather
On this page
  • %private-keys
  • %public-keys and %nuke
  • %turf
  • %step
Edit on GitHub
  1. Urbit OS
  2. Kernel
  3. Jael

Jael Examples

This documents contains practical examples of a number of Jael's tasks.

General documentation of the tasks demonstrated here can be found in the API Reference document, and details of the data types mentioned can be found in the Data Types document.

%private-keys

Here we'll look at subscribing to private key updates from Jael. We'll use a thread to pass Jael a %private-keys task, take the %private-keys gift it returns, debug print it to the terminal and finally unsubscribe with a %nuke task.

sub-priv.hoon

/-  spider
/+  strandio
=,  strand=strand:spider
=,  card=card:agent:gall
^-  thread:spider
|=  arg=vase
=/  m  (strand ,vase)
^-  form:m
;<  ~  bind:m  (send-raw-card:strandio %pass /sub-priv %arvo %j %private-keys ~)
;<  res=[=wire =sign-arvo]  bind:m  take-sign-arvo:strandio
?>  ?=([%sub-priv ~] wire.res)
?>  ?=([%jael *] sign-arvo.res)
~&  +.sign-arvo.res
;<  ~  bind:m  (send-raw-card:strandio %pass /sub-priv %arvo %j %nuke ~)
(pure:m !>(~))

Save the above thread in the /ted directory of your %base desk and |commit %base.

Now let's run the thread:

> -sub-priv

You should see the %private-key gift it returns in the Dojo:

[ %private-keys
  life=1
    vein
  { [ p=1
        q
      1.729.646.917.183.337.[...truncated for brevity]
    ]
  }
]

At this point our thread unsubscribes again with a %nuke task but without that it would send a new %private-key gift each time the private keys were changed.

%public-keys and %nuke

Here we'll look at both subscribing and unsubscribing to updates of a ship's public keys in Jael. We'll subscribe by sending Jael a %public-keys task, take the %public-keys gift it responds with, print it to the terminal, scry for the set of ducts subscribed to the ship in question, print them to the terminal, and finally send Jael a %nuke task to unsubscribe.

Here's a thread that performs these actions:

sub-pub.hoon

/-  spider
/+  strandio
=,  strand=strand:spider
=,  card=card:agent:gall
=>
|%
+$  subs
  $:  yen=(jug duct ship)
      ney=(jug ship duct)
      nel=(set duct)
  ==
--
^-  thread:spider
|=  arg=vase
=/  m  (strand ,vase)
^-  form:m
=/  =@p  (need !<((unit @p) arg))
::
::  sub to public updates for specified ship
=/  c1=card  [%pass /sub-pubkeys %arvo %j %public-keys (silt ~[p])]
;<  ~  bind:m  (send-raw-card:strandio c1)
::
::  take response from jael & print it
;<  res=[=wire =sign-arvo]  bind:m  take-sign-arvo:strandio
?>  ?=([%sub-pubkeys ~] wire.res)
?>  ?=([%jael %public-keys *] sign-arvo.res)
~&  +.sign-arvo.res
::
::  scry for tracking subs for specified ship in jael & print
;<  =subs  bind:m  (scry:strandio ,subs /j/subscriptions/1)
=/  ducts=(set duct)  (~(get ju ney.subs) p)
~&  ducts
::
::  unsub from public updates for specified ships
=/  c2=card  [%pass /sub-pubkeys %arvo %j %nuke (silt ~[p])]
;<  ~  bind:m  (send-raw-card:strandio c2)
(pure:m !>(~))

Note this example was performed on a comet as a fake ship won't have the required information in Jael.

Save the above thread in the /ted directory and |commit %base. The thread takes a ship as an argument, so we'll try to subscribe to pubkey updates for ~dopzod. Let's run the thread:

> -sub-pub ~dopzod

It first passes a %public-keys task to Jael that looks like [%public-keys (silt ~[~dopzod])] in order to subscribe. Jael will immediately respond with a %public-keys gift that contains a %full $public-keys-result. The (map ship point) contained will (for each ship specified in the task) include the current pubkeys for the ship's current life as well as previous keys for previous lifes. It thus contains a complete record of keys up to the present for each ship. Our thread will print these out to the terminal like so:

[ %public-keys
    public-keys-result
  [ %full
      points
    { [ p=~dopzod
          q
        [ rift=2
          life=3
            keys
          { [ p=1
                q
              [ crypto-suite=1
                  pass
                939.529.329.928[...truncated for brevity...]
              ]
            ]
            [ p=2
                q
              [ crypto-suite=1
                  pass
                2.215.774.809.906.200.376.0[...truncated for brevity...]
              ]
            ]
            [ p=3
                q
              [ crypto-suite=1
                  pass
                707.070.568.606.374.[...truncated for brevity...]
              ]
            ]
          }
          sponsor=~
        ]
      ]
    }
  ]
]

Along with giving us the current information, Jael will also subscribe us to any future updates for the ships in question. Such updates will come as additional %public-keys gifts, but rather than a %full public-keys-result, they'll instead contain either a %diff or %breach public-keys-result, depending on what's happened to the ship in question. It's difficult to simulate such events for demonstrative purposes so an example is not included, but you can look at the $public-keys-result to get an idea.

Jael maintains a (jug duct ship) and its reverse (jug ship duct) in its state to track subscriptions. If we do a subscriptions scry and filter the result for ~dopzod, we can see the duct of our thread has now been added to the ~dopzod set. Our thread does this, and will output something like:

{~[/gall/use/spider/0w1.vGVi-/~sampel-palnet/thread/~.dojo_0v6.0hlak.dam1b.bcdou.ai7gq.19fi8/sub-pubkeys /dill //term/1]}

At this point our thread will send a %nuke task like [%nuke (silt ~[~dopzod])] to cancel our subscription. Jael doesn't respond to it, but now, with our thread having finished and exited, we can again scry & filter for subscriptions to ~dopzod:

> =/(a .^([yen=(jug duct ship) ney=(jug ship duct) nel=(set duct)] %j /=subscriptions=/1) (~(get ju ney.a) ~dopzod))
~

As you can see the set is now empty, so we know the %nuke succeeded and Jael will no longer send us pubkey updates for ~dopzod. One thing to note about %nuke is that it must come from the same duct as the original subscription. You can't unsubscribe another app, ship, thread or what have you, so if we'd tried %nukeing the subscription from a separate thread it wouldn't have worked.

%turf

Here we'll look at using a %turf task to get Jael's list of domains. Note on a fake ship the list will be empty, so you may wish to run it on a comet or moon.

Here's a simple thread that'll pass Jael a %turf task, take the %turf gift it sends back and print it to the terminal:

turf.hoon

/-  spider
/+  strandio
=,  strand=strand:spider
^-  thread:spider
|=  arg=vase
=/  m  (strand ,vase)
^-  form:m
=/  =task:jael  [%turf ~]
=/  =card:agent:gall  [%pass /get-domains %arvo %j task]
;<  ~  bind:m  (send-raw-card:strandio card)
;<  resp=[=wire =sign-arvo]  bind:m  take-sign-arvo:strandio
?>  ?=([%get-domains ~] wire.resp)
?>  ?=([%jael %turf *] sign-arvo.resp)
~&  +.sign-arvo.resp
(pure:m !>(~))

Save in in the /ted directory of your ship and |commit %base. Next, let's try running it:

> -turf
[%turf turf=~[<|org urbit|>]]

As you see, the %turf gift contains urbit.org as ~['org' 'urbit'].

%step

Here we'll look at changing the web login code with a %step task.

First, let's see the current step with a %step scry:

> .^(@ud %j /=step=/(scot %p our))
0

...and the current code with the +code generator:

> +code
lidlut-tabwed-pillex-ridrup

Now, let's pass Jael a %step task by using |pass in the dojo:

> |pass [%j %step ~]

Jael will pass Eyre a %code-changed task:eyre to let Eyre know the code's changed so you'll see a message from Eyre in the terminal:

eyre: code-changed: throwing away cookies and sessions

Now let's again scry for the step and see that it's been incremented:

> .^(@ud %j /=step=/(scot %p our))
1

And finally, let's again run +code and see there's now a new web login code:

> +code
raldev-topnul-mirnut-lablut
PreviousJael Data TypesNextJael Scry Reference

Last updated 1 day ago