Uniform Resources (URs) allow for the encoding of self-describing, structured binary data in text strings that can are optimized for transmission in QR Codes including animated QRs. The types of data that Blockchain Commons has specified for URs appear in the Registry of UR Types and include a variety of key material including seeds, keys, and BIP-39 mnemonics. (SSKR shards can also be encoded as URs.)

Key material is the most valuable data in a cryptography system because private keys and the seeds from which they are derived control cryptocurrency, verify identity, and serve other crucial purposes. For this reason it should be carefully secured — if possible with airgapping, where the material is held in some non-networked place. That’s where URs come in. They allow key material to be encoded as URs, converted into QRs, and then transmitted across an airgap in a way that’s safe and secure, minimizing its vulnerability at the time when it’s the most vulnerable.

The above image, drawn from an interoperability demo for LetheKit and Gordian Cosigner shows how an xpub and an xprv can be transmitted between airgapped devices using standardized, typed URs.

The following major categories of key material are available as URs: seeds, HD keys, EC keys, public-key cryptography keys, and other cryptographic keys and signatures.

Why Use URs for Key Material?

Why use URs for your key material when you could pass bare seeds, the mnemonic words themselves, or xprvs and xpubs for HD keys?

The biggest reason is interoperability. URs are all self-identifying, so you always know exactly what you’re getting. They’re also built to be encoded into QRs, which is a great way to transfer data across airgaps. The result is an easy, safe way to transfer key material and to expect that it will be understood by products produced by a variety of other manufacturers.

This is particularly important for key material because, as noted earlier, it is both the core of controlling cryptocurrency (and other digital assets) and uniquely vulnerable to theft or loss.

  1. By using a system that integrates well with airgaps, you can maximize the safety of key material without potentially falling prey to man-in-the-middle attacks and you can simultaneously maintain the security of airgapped devices.
  2. By using a self-describing, interoperable method to store key material, you can ensure that it will remain well-understood and thus usable far into the future, not becoming muddled with the huge variety of standards for key material that could otherwise result in it becoming effectively unsuable if a user has no idea what it is.

Please note that classics URs are a legacy technology, with Gordian Envelopes being preferred. This is because URs can only hold bare content, while Envelopes can not only hold multiple bits of data but also metadata about the contents of an Envelope. This multiplies the self-descriptive properties of URs while also building on URs’ other advantages.

Key Material: crypto-seed

A seed is the basis of a Bitcoin account. It’s typically generated by a wallet, or alternatively a seed generator such as Blockchain Commons’ LetheKit or seedtool.

A Simple Seed

The example uses Blockchain Commons’ default 128-bit seed, YINMN BLUE.

HEX: 59f2293a5bce7d4de59e71b4207ac5d2
BIP-39 WORDS: fly mule excess resource treat plunge nose soda reflect adult ramp planet
BYTEWORDS: hawk whiz diet fact help taco kiwi gift view noon jugs quiz crux kiln silk tied omit keno lung jade
GORDIAN ENVELOPE (with METADATA): ur:envelope/lptpsogdhkwzdtfthptokigtvwnnjsqzcxknsktdoybdtpsojyhkinjtjnjtcxfwjzkpihcxfpiainiecxfekshsjnoyadcsspoybetpsosecyidbbwnnnoyaatpsoksdighisinjkcxinjkcxjlkpjpcxjkjyhsjtiehsjpiecxeheyetdpidinjycxjyihjkjycxjkihihiedmplrnihld
SEGWIT UR OUTPUT DESCRIPTOR: ur:output-descriptor/oeadisktjojeisdefzdydtaolytantjloxaxhdclaxvlcprfttldjobkredtlnhsidwybaeyjtswyandlgjnehtkdsidbkqzsrkphyfhsaaahdcxhnfgnepefxgdytryckticelyotsstoknfntavevaskiddmolsarntykbrybtjpksamtantjooeadlncsghykaeykaeykaocyhngrmuwzaycyzssajpsndifmkohy
SEGWIT TEXT OUTPUT DESCRIPTOR: wpkh([604b93f2/84'/0'/0']xpub6DVfq9VduocgjGeR69Nyr8CCi9w5gywnU7wXMYGswpHjffjcbLYNzz6G6555VDcSZLDwZPzJHJQabVWWgkpvYntpunL3UjHGrkCJ6VndbQf)#ncwysjuk

:warning: Do not use this seed to hold real monies; they could disappear immediately!

A simple, unadorned seed looks like this:

59F2293A5BCE7D4DE59E71B4207AC5D2

As discussed in the UR Overview, this seed can be converted to the CBOR A1015059F2293A5BCE7D4DE59E71B4207AC5D2 and then a ur:seed:

ur:seed/oyadgdhkwzdtfthptokigtvwnnjsqzcxknsktdhpyljeda

Decoding a Simple Seed

The Bytewords and CBOR apps demonstrate how this seed can then be broken down into its constituent parts.

The bytewords CLI can be used to convert the Bytewords minimal encoding used in URs to CBOR:

$ bytewords -i minimal -o hex OYADGDHKWZDTFTHPTOKIGTVWNNJSQZCXKNSKTDHPYLJEDA
a1015059f2293a5bce7d4de59e71b4207ac5d2

The CBOR CLI can then be used to decode the result, revealing a map with just one item, which is the seed itself:

$ cbor2diag -x a1015059f2293a5bce7d4de59e71b4207ac5d2
{1: h'59f2293a5bce7d4de59e71b4207ac5d2'}

UR was built to support clean and efficient conversion into QR codes. That same seed can be encoded into a QR code as following:

If you read this with a QR reader you’ll get:

UR:SEED/OYADGDHKWZDTFTHPTOKIGTVWNNJSQZCXKNSKTDHPYLJEDA

A Seed with Metadata

More complex examples of ur:seed may incorporate a creation date (map element #2, tagged 100), a name (map element #3), and/or a note (map element #4) as detailed in the seed CDDL.

The CBOR for a ur:seed containing all of these elements could look like the following:

a4015059f2293a5bce7d4de59e71b4207ac5d202D8641A6092DC07036541636F726E046C436F66666565206D6F6E6579

This is a CBOR map containing four elements.

It breaks apart as shown:

A4                                     # map(4)
   01                                  # element #1
   50                                  # 16 bytes in length
      59F2293A5BCE7D4DE59E71B4207AC5D2 # SEED
   02                                  # element #2
   D8 64                               # tag(100) (date)
      1A 6092DC07                      # CREATION DATE (1620237319)
   03                                  # element #3
   65                                  # 5-character text
      41636F726E                       # NAME ("Acorn")
   04                                  # element #4
   6C                                  # 12-character text
      436F66666565206D6F6E6579         # NOTE("Coffee money")

The CBOR-CLI can similarly be used to decode this information:

$ cbor2diag -x a4015059f2293a5bce7d4de59e71b4207ac5d202D8641A6092DC07036541636F726E046C436F66666565206D6F6E6579
{
    1: h'59f2293a5bce7d4de59e71b4207ac5d2',
    2: 100(1620237319),
    3: "Acorn",
    4: "Coffee money"
}

Using the Bytewords CLI you can convert the CBOR to minimal Bytewords:

$ bytewords -i hex -o minimal a4015059f2293a5bce7d4de59e71b4207ac5d202D8641A6092DC07036541636F726E046C436F66666565206D6F6E6579
oxadgdhkwzdtfthptokigtvwnnjsqzcxknsktdaotpiecyhnmouoataxihfpiajljpjtaajzfxjliyiyihihcxjnjljtihkkpseernwl

And you have a ur:seed:

UR:SEED/OXADGDHKWZDTFTHPTOKIGTVWNNJSQZCXKNSKTDAOTPIECYHNMOUOATAXIHFPIAJLJPJTAAJZFXJLIYIYIHIHCXJNJLJTIHKKPSEERNWL

A Seed in Envelope

The preferred method for encoding seeds is now to use a Gordian Envelope.

This is that same seed stored in a Gordian Envelope, which of course still uses UR formatting:

ur:envelope/lntpsogdhkwzdtfthptokigtvwnnjsqzcxknsktdoyadcsspoybdtpsokseceheyetdpidinjycxguihihiecxgdkpidjziniacxghihjkjycxhfihiajyjljpcxdehkinjtjnjtcxfwjzkpihdtcxendyeeideseoiyeyoyaatpsokkadwdghisinjkcxinjkcxjyisihcxeheyetdpidinjycxdeeyeecxktjljpiedtcxjkihihiecxkpjkihiecxhsjkcxhscxjokpidjziniacxjpihiojpihjkjkinjljtcxjyihjkjycxkoihiajyjljpcxiyjljpcxgogmjkdwcxfljljpieinhsjtcxguihihiecxghjljljzdwcxhsjtiecxjkihihiejyjljljzdpiajzindmbkbkghisinjkcxjkihihiecxhsjtiecxhsjzjzcxjeihkkjkcxioihjtihjphsjyihiecxiyjpjljncxinjycxjkisjlkpjziecxidihcxiajljtjkinieihjpihiecxkpjtjkihiakpjpihcxhsjkcxjyisinjkcxjeihkkcxjnhsjyihjpinhsjzcxinjkcxidihinjtiocxjkishsjpihiecxjokpidjziniajzkkcxhsjkcxhscxjyihjkjycxkoihiajyjljpdmbkbkfpjzjkjlcxjejtjlktjtcxhsjkcxfygdfpgscxdpcxvolansfyhsjpjecxgdkpjpjojzihcxfpjskphscxgsjlkoihvolantcxhsjkcxhsjtcxjljziecxkoihjpjkinjljtcxjliycxgsiniyihfdhsjkiscxishsiecxjyishsjycxiajljzjljpdmbkbkfwinjyiajlinjtcxgthsjkjyihjpcxgrihkkcxfginjtioihjpjojpinjtjyftcxendyeeideseoiyeybkfejyisihjpihkpjncxfpiaiajlkpjtjycxcndycxfpieiejpihjkjkcxhpjndleeeedidlendyvolanldldyvolanldldydldyhlftcxdyksececemeceyeciedyeeeoeneceniheseoetecfyetfefgfpfpesfxieeehseohsihfpiefedyehehenetbkoycfadzttpsotantjyoeadjsktjkisdeiajljkiniojtihjpdefzdydtdtaolytantjlonaxhdclaohldlmdrtlacxhnfpptplfyltwelafsnezslyndhllnvdimmwlpylkbwzjltbdmenaahdcxlejtimcnrlbtdemdoereyaqzprkpndbdgwfzflqdbzkohgzobycxcnvabaosbglfamtantjooeadlocsdyykaeykaeykaoykaocyhngrmuwzattantjooyadlslraewkadwklawkaycynewncnlboybetpsosezofptpbtlnlyjzkefmjejldeny

You can convert the minimal Bytewords to hex with the bytewords-cli and then view it in cbor.me:

86                                      # array(6)
   D8 C9                                # tag(201)
      50                                # bytes(16)
         59F2293A5BCE7D4DE59E71B4207AC5D2 # "Y\xF2):[\xCE}M\xE5\x9Eq\xB4 z\xC5\xD2"
   A1                                   # map(1)
      01                                # unsigned(1)
      18 C8                             # unsigned(200)
   A1                                   # map(1)
      0B                                # unsigned(11)
      D8 C9                             # tag(201)
         78 35                          # text(53)
            3132382D6269742053656564205075626C6963205465737420566563746F72202859696E6D6E20426C756529203630346239336632 # "128-bit Seed Public Test Vector (Yinmn Blue) 604b93f2"
   A1                                   # map(1)
      04                                # unsigned(4)
      D8 C9                             # tag(201)
         79 01EA                        # text(490)
            5468697320697320746865203132382D6269742028323420776F726429207365656420757365642061732061207075626C69632072656772657373696F6E207465737420766563746F7220666F72205552732C20476F726469616E205365656420546F6F6C2C20616E642073656564746F6F6C2D636C692E0A0A54686973207365656420616E6420616C6C206B6579732067656E6572617465642066726F6D2069742073686F756C6420626520636F6E7369646572656420756E7365637572652061732074686973206B6579206D6174657269616C206973206265696E6720736861726564207075626C69636C792061732061207465737420766563746F722E0A0A416C736F206B6E6F776E206173204450414C202D20E2809C4461726B20507572706C652041717561204C6F7665E2809D20617320616E206F6C642076657273696F6E206F66204C6966654861736820686164207468617420636F6C6F722E0A0A426974636F696E204D6173746572204B65792046696E6765727072696E743A2036303462393366320A457468657265756D204163636F756E742023302041646472657373205B6D2F3434272F3630E280992F30E280992F302F305D3A203078353537353235643034333635366539333835443845464141394364346133616541644530313136380A # "This is the 128-bit (24 word) seed used as a public regression test vector for URs, Gordian Seed Tool, and seedtool-cli.\n\nThis seed and all keys generated from it should be considered unsecure as this key material is being shared publicly as a test vector.\n\nAlso known as DPAL - “Dark Purple Aqua Love” as an old version of LifeHash had that color.\n\nBitcoin Master Key Fingerprint: 604b93f2\nEthereum Account #0 Address [m/44'/60’/0’/0/0]: 0x557525d043656e9385D8EFAA9Cd4a3aeAdE01168\n"
   A1                                   # map(1)
      19 01FC                           # unsigned(508)
      D8 C9                             # tag(201)
         D9 9D74                        # tag(40308)
            A2                          # map(2)
               01                       # unsigned(1)
               71                       # text(17)
                  77736828636F7369676E65722840302929 # "wsh(cosigner(@0))"
               02                       # unsigned(2)
               81                       # array(1)
                  D9 9D6F               # tag(40303)
                     A5                 # map(5)
                        03              # unsigned(3)
                        58 21           # bytes(33)
                           025D2F95C080206041A9AE4487ED803D9FFA819B5D86E76A9485F77EF26FD62E36 # "\u0002]/\x95\xC0\x80 `A\xA9\xAED\x87\xED\x80=\x9F\xFA\x81\x9B]\x86\xE7j\x94\x85\xF7~\xF2o\xD6.6"
                        04              # unsigned(4)
                        58 20           # bytes(32)
                           8A6E6A23B70D2895A2B5F8B4B2759B0B4F4047B3157657FB112023E60EA71282 # "\x8Anj#\xB7\r(\x95\xA2\xB5\xF8\xB4\xB2u\x9B\vO@G\xB3\u0015vW\xFB\u0011 #\xE6\u000E\xA7\u0012\x82"
                        06              # unsigned(6)
                        D9 9D70         # tag(40304)
                           A2           # map(2)
                              01        # unsigned(1)
                              88        # array(8)
                                 18 30  # unsigned(48)
                                 F5     # primitive(21)
                                 00     # unsigned(0)
                                 F5     # primitive(21)
                                 00     # unsigned(0)
                                 F5     # primitive(21)
                                 02     # unsigned(2)
                                 F5     # primitive(21)
                              02        # unsigned(2)
                              1A 604B93F2 # unsigned(1615565810)
                        07              # unsigned(7)
                        D9 9D70         # tag(40304)
                           A1           # map(1)
                              01        # unsigned(1)
                              83        # array(3)
                                 84     # array(4)
                                    00  # unsigned(0)
                                    F4  # primitive(20)
                                    01  # unsigned(1)
                                    F4  # primitive(20)
                                 80     # array(0)
                                 F4     # primitive(20)
                        08              # unsigned(8)
                        1A 9FF1237F     # unsigned(2683380607)
   A1                                   # map(1)
      10                                # unsigned(16)
      D8 C9                             # tag(201)
         C1                             # tag(1)
            FB 41D80D86816C7C3E         # primitive(4744557078782966846)

Besides the seed, a name, and a long note, this Envelope also contains an output descriptor. It’s everything that you need to actually make use of the seed when you recover it, while a bare seed can’t provide that information.

You can directly compare that CBOR dump to the dump of the ur:seed above, but if you want even a clearer description of your ur:envelope, all you need to do is examine it in bc-envelope-cli-rust:

$ envelope format ur:envelope/lntpsogdhkwzdtfthptokigtvwnnjsqzcxknsktdoyadcsspoybdtpsokseceheyetdpidinjycxguihihiecxgdkpidjziniacxghihjkjycxhfihiajyjljpcxdehkinjtjnjtcxfwjzkpihdtcxendyeeideseoiyeyoyaatpsokkadwdghisinjkcxinjkcxjyisihcxeheyetdpidinjycxdeeyeecxktjljpiedtcxjkihihiecxkpjkihiecxhsjkcxhscxjokpidjziniacxjpihiojpihjkjkinjljtcxjyihjkjycxkoihiajyjljpcxiyjljpcxgogmjkdwcxfljljpieinhsjtcxguihihiecxghjljljzdwcxhsjtiecxjkihihiejyjljljzdpiajzindmbkbkghisinjkcxjkihihiecxhsjtiecxhsjzjzcxjeihkkjkcxioihjtihjphsjyihiecxiyjpjljncxinjycxjkisjlkpjziecxidihcxiajljtjkinieihjpihiecxkpjtjkihiakpjpihcxhsjkcxjyisinjkcxjeihkkcxjnhsjyihjpinhsjzcxinjkcxidihinjtiocxjkishsjpihiecxjokpidjziniajzkkcxhsjkcxhscxjyihjkjycxkoihiajyjljpdmbkbkfpjzjkjlcxjejtjlktjtcxhsjkcxfygdfpgscxdpcxvolansfyhsjpjecxgdkpjpjojzihcxfpjskphscxgsjlkoihvolantcxhsjkcxhsjtcxjljziecxkoihjpjkinjljtcxjliycxgsiniyihfdhsjkiscxishsiecxjyishsjycxiajljzjljpdmbkbkfwinjyiajlinjtcxgthsjkjyihjpcxgrihkkcxfginjtioihjpjojpinjtjyftcxendyeeideseoiyeybkfejyisihjpihkpjncxfpiaiajlkpjtjycxcndycxfpieiejpihjkjkcxhpjndleeeedidlendyvolanldldyvolanldldydldyhlftcxdyksececemeceyeciedyeeeoeneceniheseoetecfyetfefgfpfpesfxieeehseohsihfpiefedyehehenetbkoycfadzttpsotantjyoeadjsktjkisdeiajljkiniojtihjpdefzdydtdtaolytantjlonaxhdclaohldlmdrtlacxhnfpptplfyltwelafsnezslyndhllnvdimmwlpylkbwzjltbdmenaahdcxlejtimcnrlbtdemdoereyaqzprkpndbdgwfzflqdbzkohgzobycxcnvabaosbglfamtantjooeadlocsdyykaeykaeykaoykaocyhngrmuwzattantjooyadlslraewkadwklawkaycynewncnlboybetpsosezofptpbtlnlyjzkefmjejldeny
Bytes(16) [
    'isA': 'Seed'
    '508': 40308({1: "wsh(cosigner(@0))", 2: [40303({3: h'025d2f95c080206041a9ae4487ed803d9ffa819b5d86e76a9485f77ef26fd62e36', 4: h'8a6e6a23b70d2895a2b5f8b4b2759b0b4f4047b3157657fb112023e60ea71282', 6: 40304({1: [48, true, 0, true, 0, true, 2, true], 2: 1615565810}), 7: 40304({1: [[0, false, 1, false], [], false]}), 8: 2683380607})]})
    'date': 2021-02-24T09:19:01Z
    'name': "128-bit Seed Public Test Vector (Yinmn Blue) 604b93f2"
    'note': "This is the 128-bit (24 word) seed used as a public regression test vector for URs, Gordian Seed Tool, and seedtool-cli.\n\nThis seed and all keys generated from it should be considered unsecure as this key material is being shared publicly as a test vector.\n\nAlso known as DPAL - “Dark Purple Aqua Love” as an old version of LifeHash had that color.\n\nBitcoin Master Key Fingerprint: 604b93f2\nEthereum Account #0 Address [m/44'/60’/0’/0/0]: 0x557525d043656e9385D8EFAA9Cd4a3aeAdE01168\n"
]

Mnemonic Seed Words: Deprecated

Mnemonic words were previously supported as a UR type but have been entirely deprecated for SSKR.

Key Material: crypto-hdkey

HD Keys allow for a hierarchy of keys. Both master keys and derived keys can be encoded using URs, as described in the CDDL for hdkeys.

A Master Key

The following master HD key is derived from the seed 59F2293A5BCE7D4DE59E71B4207AC5D2:

xprv9s21ZrQH143K4Mnjc7E8rpSMf8JB1XWmojYf7Ndk6zcNSbUYBsvTqJcdzTok1XwYcgytn5CRxtwhHu93NNXNQwGUbBqL3AHHZZrtKpEvmww

That Base58 xprv decodes to hex as follows:

0488ade4000000000000000000b40359eb975b5e662298db589f75ed694b17755abbd0a230c24ffb8ac2be66fd0046f8a7a92fc3ca4fd4cbf3cb5bacde4356ce790e2cd6bc206ea2574ef8991318fe6a22e3

BIP32 reveals that this information is partitioned as follows:

  • 04 ; version 4
  • 88ade4 ; xprv
  • 00 ; depth 0 == master key
  • 00000000 ; parent fingerprint
  • 00000000 ; child number
  • b40359eb975b5e662298db589f75ed694b17755abbd0a230c24ffb8ac2be66fd ; chain code
  • 0046f8a7a92fc3ca4fd4cbf3cb5bacde4356ce790e2cd6bc206ea2574ef8991318 ; key data
  • fe6a22e3 ; base58 checksum

Per the ur:hdkey CDDL, creating the CBOR for this master key requires creating a map with 3 to 4 elements, which:

  1. identify the hdkey as a master key in map element #1;
  2. optionally mark it as private in map element #2; and
  3. encode the key data and chain code in map elements #3 and #4.

The resulting CBOR is:

A401F502F50358210046F8A7A92FC3CA4FD4CBF3CB5BACDE4356CE790E2CD6BC206EA2574EF8991318045820B40359EB975B5E662298DB589F75ED694B17755ABBD0A230C24FFB8AC2BE66FD

This decodes as follows:

$ cbor2diag -x A401F502F50358210046F8A7A92FC3CA4FD4CBF3CB5BACDE4356CE790E2CD6BC206EA2574EF8991318045820B40359EB975B5E662298DB589F75ED694B17755ABBD0A230C24FFB8AC2BE66FD
{
    1: true,
    2: true,
    3: h'0046f8a7a92fc3ca4fd4cbf3cb5bacde4356ce790e2cd6bc206ea2574ef8991318',
    4: h'b40359eb975b5e662298db589f75ed694b17755abbd0a230c24ffb8ac2be66fd'

}

As usual, converting to Bytewords then allows creation of the UR:

$ bytewords -i hex -o minimal A401F502F50358210046F8A7A92FC3CA4FD4CBF3CB5BACDE4356CE790E2CD6BC206EA2574EF8991318045820B40359EB975B5E662298DB589F75ED694B17755ABBD0A230C24FFB8AC2BE66FD
oxadykaoykaxhdclaefgyaosptdlsrsggwtysbwfsbhppsuefxhftokkbadwtbrfcxjtoehgglyanlbwcsaahdcxqzaxhkwmmshphyiycpmkuyhdnekpweingrchkphtrktioedysagwzolesarniyzcrhdntkbb

The result is:

ur:hdkey/oxadykaoykaxhdclaefgyaosptdlsrsggwtysbwfsbhppsuefxhftokkbadwtbrfcxjtoehgglyanlbwcsaahdcxqzaxhkwmmshphyiycpmkuyhdnekpweingrchkphtrktioedysagwzolesarniyzcrhdntkbb

A Derived Key

A derived key will similarly include the key data and chain code, but also tends to include a derivation path (map element #6) and a parent fingerprint (map element #8) as described in the CDDL for hdkeys. The following test vector demonstrates these elements as well as coininfo (map element #5) to denote the key as testnet. Note that both the coininfo and the derivation paths are defined with tags (305 and 304 respectively).

The following CBOR:

A5035821026FE2355745BB2DB3630BBC80EF5D58951C963C841F54170BA6E5C12BE7FC12A6045820CED155C72456255881793514EDC5BD9447E7F74ABB88C6D6B6480FD016EE8C8505D90131A1020106D90130A1018A182CF501F501F500F401F4081AE9181CF3

Breaks down as follows:

cbor2diag -x A5035821026FE2355745BB2DB3630BBC80EF5D58951C963C841F54170BA6E5C12BE7FC12A6045820CED155C72456255881793514EDC5BD9447E7F74ABB88C6D6B6480FD016EE8C8505D90131A1020106D90130A1018A182CF501F501F500F401F4081AE9181CF3
{
    3: h'026fe2355745bb2db3630bbc80ef5d58951c963c841f54170ba6e5c12be7fc12a6',
    4: h'ced155c72456255881793514edc5bd9447e7f74abb88c6d6b6480fd016ee8c85',
    5: 305({2: 1}),
    6: 304({1: [44, true, 1, true, 1, true, 0, false, 1, false]}),
    8: 3910671603
}

The coininfo element (#5) demonstrates use of the coininfo CDDL. Here, the network is set to testnet.

The key derivation element (#6) demonstrates use of the keypath CDDL. Here, the derivation path is set to m/44'/1'/1'/0/1.

The parent-fingerprint element (#8) is simply set to 3910671603 (or in hex: 1AE9181CF3).

The resulting crypto-hdkey after conversion to minimal Bytewords is:

ur:hdkey/onaxhdclaojlvoechgferkdpqdiabdrflawshlhdmdcemtfnlrctghchbdolvwsednvdztbgolaahdcxtottgostdkhfdahdlykkecbbweskrymwflvdylgerkloswtbrpfdbsticmwylklpahtaadehoyaoadamtaaddyoyadlecsdwykadykadykaewkadwkaycywlcscewfihbdaehn

A few other URs are related to key material:

  • SSKR allows for the transmission of shares that are recombined to reconstruct key material.
  • Envelope is the preferred method for storing key material.

Each is covered in their own document.

Testing Key Material URs with Blockchain Commons’ Reference Tools

Output of bare ur:seeds is no longer supported by Blockchain Commons’ newest reference tools. If you wish to test ur:seed from the command line you can use the older C++-based seedtool-cli.

Integrating Key Material URs Into Your Code

You can incorporate URs into your own code using a variety of UR libraries:

UR Libraries

Language Repo Contributor Status
C++ bc-ur Blockchain Commons  
Java bc-ur-java Bitmark  
Java Hummingbird Craig Raw  
Python foundation-ur-py Foundation  
Rust bc-ur-rust Blockchain Commons  
Rust ur-rust Dominik Spicher  
Swift URKit + URUI Blockchain Commons  
TypeScript bc-ur for TS xardass  

Conclusion

Key material can be transferred using ur:seed or ur:hdkey. Doing so allows you to use airgaps, which increase the safety of these vulnerable operations; and also increases your interoperability, so that other software can work with you, and so that your key material remains usable far into the future.

However, we now prefer the use of ur:envelope to allow for the storage of more data and related metadata.