keri 1.2.0.dev5__tar.gz → 1.2.0.dev7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. {keri-1.2.0.dev5/src/keri.egg-info → keri-1.2.0.dev7}/PKG-INFO +1 -1
  2. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/setup.py +1 -1
  3. keri-1.2.0.dev7/src/keri/__init__.py +5 -0
  4. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/agenting.py +6 -0
  5. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/delegate/confirm.py +9 -3
  6. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/local/watch.py +2 -42
  7. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/mailbox/debug.py +7 -4
  8. keri-1.2.0.dev7/src/keri/app/cli/commands/mailbox/list.py +68 -0
  9. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/rename.py +6 -3
  10. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/rotate.py +7 -3
  11. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/watcher/add.py +26 -12
  12. keri-1.2.0.dev7/src/keri/app/cli/commands/watcher/adjudicate.py +159 -0
  13. keri-1.2.0.dev7/src/keri/app/cli/commands/watcher/list.py +68 -0
  14. keri-1.2.0.dev7/src/keri/app/cli/commands/witness/list.py +56 -0
  15. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/delegating.py +33 -4
  16. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/grouping.py +1 -1
  17. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/indirecting.py +9 -7
  18. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/querying.py +2 -2
  19. keri-1.2.0.dev7/src/keri/app/watching.py +223 -0
  20. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/eventing.py +117 -20
  21. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/parsing.py +2 -2
  22. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/routing.py +0 -3
  23. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/basing.py +63 -3
  24. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vdr/credentialing.py +1 -1
  25. {keri-1.2.0.dev5 → keri-1.2.0.dev7/src/keri.egg-info}/PKG-INFO +1 -1
  26. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri.egg-info/SOURCES.txt +5 -0
  27. keri-1.2.0.dev5/src/keri/__init__.py +0 -5
  28. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/LICENSE +0 -0
  29. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/README.md +0 -0
  30. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/setup.cfg +0 -0
  31. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/__init__.py +0 -0
  32. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/apping.py +0 -0
  33. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/challenging.py +0 -0
  34. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/__init__.py +0 -0
  35. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/__init__.py +0 -0
  36. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/aid.py +0 -0
  37. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/challenge/__init__.py +0 -0
  38. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/challenge/generate.py +0 -0
  39. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/challenge/respond.py +0 -0
  40. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/challenge/verify.py +0 -0
  41. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/clean.py +0 -0
  42. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/contacts/__init__.py +0 -0
  43. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/contacts/list.py +0 -0
  44. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/decrypt.py +0 -0
  45. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/delegate/__init__.py +0 -0
  46. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/delegate/request.py +0 -0
  47. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/did/__init__.py +0 -0
  48. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/did/generate.py +0 -0
  49. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ends/__init__.py +0 -0
  50. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ends/add.py +0 -0
  51. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ends/export.py +0 -0
  52. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ends/list.py +0 -0
  53. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/escrow.py +0 -0
  54. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/export.py +0 -0
  55. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/incept.py +0 -0
  56. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/init.py +0 -0
  57. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/interact.py +0 -0
  58. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/__init__.py +0 -0
  59. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/admit.py +0 -0
  60. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/agree.py +0 -0
  61. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/apply.py +0 -0
  62. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/grant.py +0 -0
  63. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/join.py +0 -0
  64. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/list.py +0 -0
  65. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/offer.py +0 -0
  66. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ipex/spurn.py +0 -0
  67. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/kevers.py +0 -0
  68. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/list.py +0 -0
  69. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/local/__init__.py +0 -0
  70. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/mailbox/__init__.py +0 -0
  71. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/mailbox/add.py +0 -0
  72. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/mailbox/update.py +0 -0
  73. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/migrate/__init__.py +0 -0
  74. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/migrate/list.py +0 -0
  75. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/migrate/run.py +0 -0
  76. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/migrate/show.py +0 -0
  77. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/migrate.py +0 -0
  78. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/__init__.py +0 -0
  79. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/continue.py +0 -0
  80. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/demo.py +0 -0
  81. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/incept.py +0 -0
  82. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/interact.py +0 -0
  83. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/join.py +0 -0
  84. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/notice.py +0 -0
  85. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/rotate.py +0 -0
  86. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/shell.py +0 -0
  87. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/multisig/update.py +0 -0
  88. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/nonce.py +0 -0
  89. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/oobi/__init__.py +0 -0
  90. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/oobi/clean.py +0 -0
  91. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/oobi/generate.py +0 -0
  92. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/oobi/resolve.py +0 -0
  93. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/passcode/__init__.py +0 -0
  94. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/passcode/generate.py +0 -0
  95. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/passcode/remove.py +0 -0
  96. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/passcode/set.py +0 -0
  97. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/query.py +0 -0
  98. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/rollback.py +0 -0
  99. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/saidify.py +0 -0
  100. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/salt.py +0 -0
  101. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/sign.py +0 -0
  102. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ssh/__init__.py +0 -0
  103. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/ssh/export.py +0 -0
  104. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/status.py +0 -0
  105. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/time.py +0 -0
  106. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/__init__.py +0 -0
  107. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/create.py +0 -0
  108. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/export.py +0 -0
  109. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/list.py +0 -0
  110. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/registry/__init__.py +0 -0
  111. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/registry/incept.py +0 -0
  112. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/registry/list.py +0 -0
  113. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/registry/status.py +0 -0
  114. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/vc/revoke.py +0 -0
  115. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/verify.py +0 -0
  116. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/version.py +0 -0
  117. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/watcher/__init__.py +0 -0
  118. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/witness/__init__.py +0 -0
  119. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/witness/authenticate.py +0 -0
  120. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/witness/demo.py +0 -0
  121. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/witness/start.py +0 -0
  122. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/commands/witness/submit.py +0 -0
  123. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/__init__.py +0 -0
  124. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/config.py +0 -0
  125. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/displaying.py +0 -0
  126. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/existing.py +0 -0
  127. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/incepting.py +0 -0
  128. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/rotating.py +0 -0
  129. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/common/terming.py +0 -0
  130. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/cli/kli.py +0 -0
  131. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/configing.py +0 -0
  132. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/connecting.py +0 -0
  133. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/directing.py +0 -0
  134. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/forwarding.py +0 -0
  135. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/habbing.py +0 -0
  136. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/httping.py +0 -0
  137. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/keeping.py +0 -0
  138. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/notifying.py +0 -0
  139. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/oobiing.py +0 -0
  140. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/signaling.py +0 -0
  141. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/signing.py +0 -0
  142. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/specing.py +0 -0
  143. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/app/storing.py +0 -0
  144. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/__init__.py +0 -0
  145. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/coring.py +0 -0
  146. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/counting.py +0 -0
  147. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/indexing.py +0 -0
  148. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/scheming.py +0 -0
  149. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/serdering.py +0 -0
  150. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/signing.py +0 -0
  151. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/streaming.py +0 -0
  152. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/core/structing.py +0 -0
  153. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/__init__.py +0 -0
  154. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/dbing.py +0 -0
  155. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/escrowing.py +0 -0
  156. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/koming.py +0 -0
  157. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/migrations/__init__.py +0 -0
  158. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/migrations/rekey_habs.py +0 -0
  159. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/db/subing.py +0 -0
  160. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/demo/__init__.py +0 -0
  161. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/demo/demo_bob.py +0 -0
  162. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/demo/demo_eve.py +0 -0
  163. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/demo/demo_kev.py +0 -0
  164. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/demo/demo_sam.py +0 -0
  165. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/demo/demoing.py +0 -0
  166. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/end/__init__.py +0 -0
  167. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/end/ending.py +0 -0
  168. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/end/priming.py +0 -0
  169. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/help/__init__.py +0 -0
  170. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/help/helping.py +0 -0
  171. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/kering.py +0 -0
  172. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/peer/__init__.py +0 -0
  173. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/peer/exchanging.py +0 -0
  174. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vc/__init__.py +0 -0
  175. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vc/protocoling.py +0 -0
  176. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vc/proving.py +0 -0
  177. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vc/walleting.py +0 -0
  178. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vdr/__init__.py +0 -0
  179. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vdr/eventing.py +0 -0
  180. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vdr/verifying.py +0 -0
  181. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri/vdr/viring.py +0 -0
  182. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri.egg-info/dependency_links.txt +0 -0
  183. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri.egg-info/entry_points.txt +0 -0
  184. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri.egg-info/not-zip-safe +0 -0
  185. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri.egg-info/requires.txt +0 -0
  186. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/src/keri.egg-info/top_level.txt +0 -0
  187. {keri-1.2.0.dev5 → keri-1.2.0.dev7}/tests/test_kering.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: keri
3
- Version: 1.2.0.dev5
3
+ Version: 1.2.0.dev7
4
4
  Summary: Key Event Receipt Infrastructure
5
5
  Home-page: https://github.com/WebOfTrust/keripy
6
6
  Author: Samuel M. Smith
@@ -37,7 +37,7 @@ from os.path import splitext
37
37
  from setuptools import find_packages, setup
38
38
  setup(
39
39
  name='keri',
40
- version='1.2.0-dev5', # also change in src/keri/__init__.py
40
+ version='1.2.0-dev7', # also change in src/keri/__init__.py
41
41
  license='Apache Software License 2.0',
42
42
  description='Key Event Receipt Infrastructure',
43
43
  long_description="KERI Decentralized Key Management Infrastructure",
@@ -0,0 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ __version__ = '1.2.0-dev7' # also change in setup.py
4
+
5
+
@@ -581,6 +581,7 @@ class WitnessPublisher(doing.DoDoer):
581
581
 
582
582
  """
583
583
  self.hby = hby
584
+ self.posted = 0
584
585
  self.msgs = msgs if msgs is not None else decking.Deck()
585
586
  self.cues = cues if cues is not None else decking.Deck()
586
587
  super(WitnessPublisher, self).__init__(doers=[doing.doify(self.sendDo)], **kwa)
@@ -599,6 +600,7 @@ class WitnessPublisher(doing.DoDoer):
599
600
  while True:
600
601
  while self.msgs:
601
602
  evt = self.msgs.popleft()
603
+ self.posted += 1
602
604
  pre = evt["pre"]
603
605
  msg = evt["msg"]
604
606
 
@@ -642,6 +644,10 @@ class WitnessPublisher(doing.DoDoer):
642
644
 
643
645
  return False
644
646
 
647
+ @property
648
+ def idle(self):
649
+ return len(self.msgs) == 0 and self.posted == len(self.cues)
650
+
645
651
 
646
652
  class TCPMessenger(doing.DoDoer):
647
653
  """ Send events to witnesses for receipting using TCP direct connection
@@ -37,6 +37,7 @@ parser.add_argument("--authenticate", '-z', help="Prompt the controller for auth
37
37
  action='store_true')
38
38
  parser.add_argument('--code', help='<Witness AID>:<code> formatted witness auth codes. Can appear multiple times',
39
39
  default=[], action="append", required=False)
40
+ parser.add_argument('--code-time', help='Time the witness codes were captured.', default=None, required=False)
40
41
 
41
42
 
42
43
  def confirm(args):
@@ -54,16 +55,18 @@ def confirm(args):
54
55
  auto = args.auto
55
56
  authenticate = args.authenticate
56
57
  codes = args.code
58
+ codeTime = args.code_time
57
59
 
58
60
  confirmDoer = ConfirmDoer(name=name, base=base, alias=alias, bran=bran, interact=interact, auto=auto,
59
- authenticate=authenticate, codes=codes)
61
+ authenticate=authenticate, codes=codes, codeTime=codeTime)
60
62
 
61
63
  doers = [confirmDoer]
62
64
  return doers
63
65
 
64
66
 
65
67
  class ConfirmDoer(doing.DoDoer):
66
- def __init__(self, name, base, alias, bran, interact=False, auto=False, authenticate=False, codes=None):
68
+ def __init__(self, name, base, alias, bran, interact=False, auto=False, authenticate=False, codes=None,
69
+ codeTime=None):
67
70
  hby = existing.setupHby(name=name, base=base, bran=bran)
68
71
  self.hbyDoer = habbing.HaberyDoer(habery=hby) # setup doer
69
72
  self.witq = agenting.WitnessInquisitor(hby=hby)
@@ -73,6 +76,7 @@ class ConfirmDoer(doing.DoDoer):
73
76
  self.mux = grouping.Multiplexor(hby=hby, notifier=self.notifier)
74
77
  self.authenticate = authenticate
75
78
  self.codes = codes if codes is not None else []
79
+ self.codeTime = codeTime
76
80
 
77
81
  exc = exchanging.Exchanger(hby=hby, handlers=[])
78
82
  delegating.loadHandlers(hby=hby, exc=exc, notifier=self.notifier)
@@ -185,9 +189,11 @@ class ConfirmDoer(doing.DoDoer):
185
189
 
186
190
  auths = {}
187
191
  if self.authenticate:
192
+ codeTime = helping.fromIso8601(
193
+ self.codeTime) if self.codeTime is not None else helping.nowIso8601()
188
194
  for arg in self.codes:
189
195
  (wit, code) = arg.split(":")
190
- auths[wit] = f"{code}#{helping.nowIso8601()}"
196
+ auths[wit] = f"{code}#{codeTime}"
191
197
 
192
198
  for wit in hab.kever.wits:
193
199
  if wit in auths:
@@ -7,14 +7,13 @@ import argparse
7
7
  import random
8
8
  import sys
9
9
  import time
10
- from collections import namedtuple
11
10
 
12
11
  from hio import help
13
12
  from hio.base import doing
14
13
  from keri.app import agenting, indirecting, habbing, forwarding
15
14
  from keri.app.cli.common import existing, terming
16
15
  from keri.app.habbing import GroupHab
17
- from keri.core import coring
16
+ from keri.app.watching import States, diffState
18
17
 
19
18
  logger = help.ogler.getLogger()
20
19
 
@@ -31,17 +30,6 @@ parser.add_argument('--passcode', '-p', help='21 character encryption passcode f
31
30
  parser.add_argument('--aeid', help='qualified base64 of non-transferable identifier prefix for authentication '
32
31
  'and encryption of secrets in keystore', default=None)
33
32
 
34
- Stateage = namedtuple("Stateage", 'even ahead behind duplicitous')
35
-
36
- States = Stateage(even="even", ahead="ahead", behind="behind", duplicitous="duplicitous")
37
-
38
-
39
- class WitnessState:
40
- wit: str
41
- state: Stateage
42
- sn: int
43
- dig: str
44
-
45
33
 
46
34
  def watch(args):
47
35
  name = args.name
@@ -135,7 +123,7 @@ class WatchDoer(doing.DoDoer):
135
123
  mystate = hab.kever.state()
136
124
  witstate = hab.db.ksns.get((saider.qb64,))
137
125
 
138
- states.append(self.diffState(wit, mystate, witstate))
126
+ states.append(diffState(wit, mystate, witstate))
139
127
 
140
128
  # First check for any duplicity, if so get out of here
141
129
  dups = [state for state in states if state.state == States.duplicitous]
@@ -213,31 +201,3 @@ class WatchDoer(doing.DoDoer):
213
201
 
214
202
  yield self.tock
215
203
  yield self.tock
216
-
217
- @staticmethod
218
- def diffState(wit, preksn, witksn):
219
-
220
- witstate = WitnessState()
221
- witstate.wit = wit
222
- mysn = int(preksn.s, 16)
223
- mydig = preksn.d
224
- witstate.sn = int(witksn.f, 16)
225
- witstate.dig = witksn.d
226
-
227
- # At the same sequence number, check the DIGs
228
- if mysn == witstate.sn:
229
- if mydig == witstate.dig:
230
- witstate.state = States.even
231
- else:
232
- witstate.state = States.duplicitous
233
-
234
- # This witness is behind and will need to be caught up.
235
- elif mysn > witstate.sn:
236
- witstate.state = States.behind
237
-
238
- # mysn < witstate.sn - We are behind this witness (multisig or restore situation).
239
- # Must ensure that controller approves this event or a recovery rotation is needed
240
- else:
241
- witstate.state = States.ahead
242
-
243
- return witstate
@@ -85,7 +85,7 @@ class ReadDoer(doing.DoDoer):
85
85
 
86
86
  hab = self.hby.habByName(name=self.alias)
87
87
  topics = {"/receipt": 0, "/replay": 0, "/multisig": 0, "/credential": 0, "/delegate": 0, "/challenge": 0,
88
- "/oobi": 0}
88
+ "/oobi": 0, "/reply": 0}
89
89
  try:
90
90
  client, clientDoer = agenting.httpClient(hab, self.witness)
91
91
  except kering.MissingEntryError as e:
@@ -95,8 +95,11 @@ class ReadDoer(doing.DoDoer):
95
95
 
96
96
  print("Local Index per Topic")
97
97
  witrec = hab.db.tops.get((hab.pre, self.witness))
98
- for topic in witrec.topics:
99
- print(f" Topic {topic}: {witrec.topics[topic]}")
98
+ if witrec:
99
+ for topic in witrec.topics:
100
+ print(f" Topic {topic}: {witrec.topics[topic]}")
101
+ else:
102
+ print("\tNo local index")
100
103
  print()
101
104
 
102
105
  q = dict(pre=hab.pre, topics=topics)
@@ -107,7 +110,7 @@ class ReadDoer(doing.DoDoer):
107
110
 
108
111
  httping.createCESRRequest(msg, client, dest=self.witness)
109
112
 
110
- while client.requests:
113
+ while client.requests or (not client.events and not client.requests):
111
114
  yield self.tock
112
115
 
113
116
  yield 1.0
@@ -0,0 +1,68 @@
1
+ # -*- encoding: utf-8 -*-
2
+ """
3
+ KERI
4
+ keri.kli.commands module
5
+
6
+ """
7
+ import argparse
8
+
9
+ from hio import help
10
+ from hio.base import doing
11
+
12
+ from keri.app import connecting
13
+ from keri.app.cli.common import existing
14
+ from keri.kering import ConfigurationError, Roles
15
+
16
+ logger = help.ogler.getLogger()
17
+
18
+ parser = argparse.ArgumentParser(description='List current mailboxes')
19
+ parser.set_defaults(handler=lambda args: handle(args),
20
+ transferable=True)
21
+ parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True)
22
+ parser.add_argument('--alias', '-a', help='human readable alias for the identifier to whom the credential was issued',
23
+ required=True)
24
+ parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore',
25
+ required=False, default="")
26
+ parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)',
27
+ dest="bran", default=None) # passcode => bran
28
+
29
+
30
+ def handle(args):
31
+ """ Command line handler for adding an aid to a watcher's list of AIds to watch
32
+
33
+ Parameters:
34
+ args(Namespace): parsed command line arguments
35
+
36
+ """
37
+
38
+ kwa = dict(args=args)
39
+ return [doing.doify(listMailboxes, **kwa)]
40
+
41
+
42
+ def listMailboxes(tymth, tock=0.0, **opts):
43
+ """ Command line status handler
44
+
45
+ """
46
+ _ = (yield tock)
47
+ args = opts["args"]
48
+ name = args.name
49
+ alias = args.alias
50
+ base = args.base
51
+ bran = args.bran
52
+
53
+ try:
54
+ with existing.existingHby(name=name, base=base, bran=bran) as hby:
55
+ org = connecting.Organizer(hby=hby)
56
+ if alias is None:
57
+ alias = existing.aliasInput(hby)
58
+
59
+ hab = hby.habByName(alias)
60
+
61
+ for (aid, role, eid), ender in hab.db.ends.getItemIter(keys=(hab.pre, Roles.mailbox)):
62
+ if ender.allowed:
63
+ contact = org.get(eid)
64
+ print(f"{contact['alias']}: {eid}")
65
+
66
+ except ConfigurationError as e:
67
+ print(f"identifier prefix for {name} does not exist, incept must be run first", )
68
+ return -1
@@ -48,16 +48,19 @@ def rename(tymth, tock=0.0, **opts):
48
48
  if hby.habByName(newAlias) is not None:
49
49
  print(f"{newAlias} is already in use")
50
50
 
51
- if (pre := hab.db.names.get(keys=("", name))) is not None:
51
+ if (pre := hab.db.names.get(keys=("", alias))) is not None:
52
52
 
53
53
  habord = hab.db.habs.get(keys=pre)
54
- habord.name = name
54
+ habord.name = newAlias
55
55
  hab.db.habs.pin(keys=habord.hid,
56
56
  val=habord)
57
- hab.db.names.pin(keys=("", name), val=pre)
57
+ hab.db.names.pin(keys=("", newAlias), val=pre)
58
58
  hab.db.names.rem(keys=("", alias))
59
59
 
60
60
  print(f"Hab {alias} renamed to {newAlias}")
61
+ else:
62
+ raise ConfigurationError(f"No AID with name {alias} found")
63
+
61
64
 
62
65
  except ConfigurationError as e:
63
66
  print(f"identifier prefix for {name} does not exist, incept must be run first", )
@@ -31,6 +31,7 @@ parser.add_argument("--authenticate", '-z', help="Prompt the controller for auth
31
31
  action='store_true')
32
32
  parser.add_argument('--code', help='<Witness AID>:<code> formatted witness auth codes. Can appear multiple times',
33
33
  default=[], action="append", required=False)
34
+ parser.add_argument('--code-time', help='Time the witness codes were captured.', default=None, required=False)
34
35
 
35
36
  parser.add_argument("--proxy", help="alias for delegation communication proxy", default="")
36
37
 
@@ -66,7 +67,8 @@ def rotate(args):
66
67
  cuts=opts.witsCut, adds=opts.witsAdd,
67
68
  isith=opts.isith, nsith=opts.nsith,
68
69
  count=opts.ncount, toad=opts.toad,
69
- data=opts.data, proxy=args.proxy, authenticate=args.authenticate, codes=args.code)
70
+ data=opts.data, proxy=args.proxy, authenticate=args.authenticate,
71
+ codes=args.code, codeTime=args.code_time)
70
72
 
71
73
  doers = [rotDoer]
72
74
 
@@ -122,7 +124,7 @@ class RotateDoer(doing.DoDoer):
122
124
 
123
125
  def __init__(self, name, base, bran, alias, endpoint=False, isith=None, nsith=None, count=None,
124
126
  toad=None, wits=None, cuts=None, adds=None, data: list = None, proxy=None, authenticate=False,
125
- codes=None):
127
+ codes=None, codeTime=None):
126
128
  """
127
129
  Returns DoDoer with all registered Doers needed to perform rotation.
128
130
 
@@ -149,6 +151,7 @@ class RotateDoer(doing.DoDoer):
149
151
  self.proxy = proxy
150
152
  self.authenticate = authenticate
151
153
  self.codes = codes if codes is not None else []
154
+ self.codeTime = codeTime
152
155
 
153
156
  self.wits = wits if wits is not None else []
154
157
  self.cuts = cuts if cuts is not None else []
@@ -198,9 +201,10 @@ class RotateDoer(doing.DoDoer):
198
201
 
199
202
  auths = {}
200
203
  if self.authenticate:
204
+ codeTime = helping.fromIso8601(self.codeTime) if self.codeTime is not None else helping.nowIso8601()
201
205
  for arg in self.codes:
202
206
  (wit, code) = arg.split(":")
203
- auths[wit] = f"{code}#{helping.nowIso8601()}"
207
+ auths[wit] = f"{code}#{codeTime}"
204
208
 
205
209
  for wit in hab.kever.wits:
206
210
  if wit in auths:
@@ -11,7 +11,8 @@ from hio.base import doing
11
11
 
12
12
  from keri.app import connecting, habbing, forwarding
13
13
  from keri.app.cli.common import existing
14
- from keri.core import eventing, serdering
14
+ from keri.core import serdering
15
+ from keri.kering import Roles
15
16
 
16
17
  logger = help.ogler.getLogger()
17
18
 
@@ -53,24 +54,26 @@ class AddDoer(doing.DoDoer):
53
54
  self.hab = self.hby.habByName(alias)
54
55
  self.org = connecting.Organizer(hby=self.hby)
55
56
 
57
+ wat = None
56
58
  if watcher in self.hby.kevers:
57
59
  wat = watcher
58
60
  else:
59
- wat = self.org.find("alias", watcher)
60
- if len(wat) != 1:
61
- raise ValueError(f"invalid recipient {watcher}")
62
- wat = wat[0]['id']
61
+ contacts = self.org.find("alias", watcher)
62
+ for contact in contacts:
63
+ if contact['alias'] == watcher:
64
+ wat = contact['id']
63
65
 
64
66
  if not wat:
65
67
  raise ValueError(f"unknown watcher {watcher}")
66
68
 
69
+ watd = None
67
70
  if watched in self.hby.kevers:
68
71
  watd = watched
69
72
  else:
70
- watd = self.org.find("alias", watched)
71
- if len(watd) != 1:
72
- raise ValueError(f"invalid recipient {watched}")
73
- watd = watd[0]['id']
73
+ contacts = self.org.find("alias", watched)
74
+ for contact in contacts:
75
+ if contact['alias'] == watched:
76
+ watd = contact['id']
74
77
 
75
78
  if not watd:
76
79
  raise ValueError(f"unknown watched {watched}")
@@ -91,7 +94,7 @@ class AddDoer(doing.DoDoer):
91
94
  super(AddDoer, self).__init__(doers=doers)
92
95
 
93
96
  def addDo(self, tymth, tock=0.0):
94
- """ Grant credential by creating /ipex/grant exn message
97
+ """ Add an AID to a watcher's list of AIDs to watch
95
98
 
96
99
  Parameters:
97
100
  tymth (function): injected function wrapper closure returned by .tymen() of
@@ -109,17 +112,28 @@ class AddDoer(doing.DoDoer):
109
112
  if isinstance(self.hab, habbing.GroupHab):
110
113
  raise ValueError("watchers for multisig AIDs not currently supported")
111
114
 
115
+ ender = self.hab.db.ends.get(keys=(self.hab.pre, Roles.watcher, self.watcher))
116
+ if not ender or not ender.allowed:
117
+ msg = self.hab.reply(route="/end/role/add",
118
+ data=dict(cid=self.hab.pre, role=Roles.watcher, eid=self.watcher))
119
+ self.hab.psr.parseOne(ims=msg)
120
+
112
121
  postman = forwarding.StreamPoster(hby=self.hby, hab=self.hab, recp=self.watcher, topic="reply")
122
+ for msg in self.hab.db.cloneDelegation(self.hab.kever):
123
+ serder = serdering.SerderKERI(raw=msg)
124
+ postman.send(serder=serder, attachment=msg[serder.size:])
125
+
113
126
  for msg in self.hab.db.clonePreIter(pre=self.hab.pre):
114
127
  serder = serdering.SerderKERI(raw=msg)
115
128
  postman.send(serder=serder, attachment=msg[serder.size:])
116
129
 
117
130
  data = dict(cid=self.hab.pre,
118
- wid=self.watched,
131
+ oid=self.watched,
119
132
  oobi=self.oobi)
120
133
 
121
- route = "/watcher/aid/add"
134
+ route = f"/watcher/{self.watcher}/add"
122
135
  msg = self.hab.reply(route=route, data=data)
136
+ self.hab.psr.parseOne(ims=bytes(msg))
123
137
  rpy = serdering.SerderKERI(raw=msg)
124
138
  postman.send(serder=rpy, attachment=msg[rpy.size:])
125
139
 
@@ -0,0 +1,159 @@
1
+ # -*- encoding: utf-8 -*-
2
+ """
3
+ KERI
4
+ keri.kli.commands module
5
+
6
+ """
7
+ import argparse
8
+ import datetime
9
+ import random
10
+ import sys
11
+
12
+ from hio import help
13
+ from hio.base import doing
14
+
15
+ from keri.app import connecting, indirecting, querying, watching
16
+ from keri.app.cli.common import existing
17
+ from keri.app.watching import diffState, States
18
+ from keri.help import helping
19
+ from keri.kering import ConfigurationError
20
+ logger = help.ogler.getLogger()
21
+
22
+ parser = argparse.ArgumentParser(description='Perform key event adjudication on any new key state from watchers.')
23
+ parser.set_defaults(handler=lambda args: handle(args),
24
+ transferable=True)
25
+ parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True)
26
+ parser.add_argument('--alias', '-a', help='human readable alias for the identifier to whom the credential was issued',
27
+ required=True)
28
+ parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore',
29
+ required=False, default="")
30
+ parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)',
31
+ dest="bran", default=None) # passcode => bran
32
+ parser.add_argument('--toad', '-t', default=None, required=False, type=int,
33
+ help='int of watcher threshold (threshold of acceptable duplicity)', )
34
+ parser.add_argument("--watched", '-W', help="the watched AID or alias to add", required=True)
35
+ parser.add_argument("--poll", "-P", help="Poll mailboxes for any issued credentials", action="store_true")
36
+
37
+
38
+ def handle(args):
39
+ """ Command line handler for adding an aid to a watcher's list of AIds to watch
40
+
41
+ Parameters:
42
+ args(Namespace): parsed command line arguments
43
+
44
+ """
45
+
46
+ kwa = dict(args=args)
47
+ adjudicator = AdjudicationDoer(**kwa)
48
+
49
+ return [adjudicator]
50
+
51
+
52
+ class AdjudicationDoer(doing.DoDoer):
53
+
54
+ def __init__(self, **kwa):
55
+ args = kwa["args"]
56
+ base = args.base
57
+ bran = args.bran
58
+ self.name = args.name
59
+ self.alias = args.alias
60
+ self.watched = args.watched
61
+ self.poll = args.poll
62
+ self.toad = args.toad
63
+
64
+ self.hby = existing.setupHby(name=self.name, base=base, bran=bran)
65
+ self.mbx = indirecting.MailboxDirector(hby=self.hby, topics=['/reply', '/replay'])
66
+ doers = [doing.doify(self.adjudicate, **kwa), self.mbx]
67
+
68
+ super(AdjudicationDoer, self).__init__(**kwa, doers=doers)
69
+
70
+ def adjudicate(self, tymth, tock=0.0, **opts):
71
+ """ Command line status handler
72
+
73
+ """
74
+ _ = (yield tock)
75
+
76
+ try:
77
+ org = connecting.Organizer(hby=self.hby)
78
+
79
+ if self.poll:
80
+ end = helping.nowUTC() + datetime.timedelta(seconds=5)
81
+ sys.stdout.write(f"Polling mailboxes")
82
+ sys.stdout.flush()
83
+ while helping.nowUTC() < end:
84
+ sys.stdout.write(".")
85
+ sys.stdout.flush()
86
+ yield 1.0
87
+ print("\n")
88
+
89
+ if self.watched in self.hby.kevers:
90
+ watd = self.watched
91
+ else:
92
+ watd = org.find("alias", self.watched)
93
+ if len(watd) != 1:
94
+ raise ValueError(f"invalid recipient {self.watched}")
95
+ watd = watd[0]['id']
96
+
97
+ if not watd:
98
+ raise ValueError(f"unknown watched {self.watched}")
99
+
100
+ if self.alias is None:
101
+ self.alias = existing.aliasInput(self.hby)
102
+
103
+ hab = self.hby.habByName(self.alias)
104
+ if hab is None:
105
+ raise ValueError(f"unknown alias {self.alias}")
106
+
107
+ adj = watching.Adjudicator(hby=self.hby, hab=hab)
108
+ adjDoer = watching.AdjudicationDoer(adj)
109
+ self.extend([adjDoer])
110
+
111
+ adj.msgs.append(dict(oid=self.watched, toad=self.toad))
112
+
113
+ while not adj.cues:
114
+ yield self.tock
115
+
116
+ cue = adj.cues.pull()
117
+ kin = cue['kin']
118
+
119
+ match kin:
120
+ case "keyStateConsistent":
121
+ states = cue['states']
122
+ wids = cue["wids"]
123
+ print(f"Local key state is consistent with the {len(states)} (out of "
124
+ f"{len(wids)} total) watchers that responded")
125
+
126
+ case "keyStateLagging":
127
+ bhds = cue["behinds"]
128
+ print("The following watchers are behind the local KEL:")
129
+ for state in bhds:
130
+ print(f"\tWatcher {state.wit} at seq No. {state.sn} with digest: {state.dig}")
131
+
132
+ print(f"Recommend the checking those watchers for access to {self.watched} witnesses")
133
+
134
+ case "keyStateUpdate":
135
+ ahds = cue["aheads"]
136
+ logger.info(f"Threshold ({self.toad}) satisfying number of watchers ({len(ahds)}) are ahead")
137
+ for state in ahds:
138
+ logger.info(f"\tWatcher {state.wit} at Seq No. {state.sn} with digest: {state.dig}")
139
+
140
+ state = random.choice(ahds)
141
+ querier = querying.SeqNoQuerier(hby=self.hby, hab=hab, pre=self.watched, sn=state.sn,
142
+ wits=[state.wit])
143
+ self.extend([querier])
144
+
145
+ while not querier.done:
146
+ yield self.tock
147
+
148
+ case "keyStateDuplicitous":
149
+ dups = cue["dups"]
150
+ print(f"Duplicity detected for AID {self.watched}, local key state remains intact.")
151
+ for state in dups:
152
+ print(f"\tWatcher {state.wit} at seq No. {state.sn} with digest: {state.dig}")
153
+
154
+ self.remove([self.mbx, adjDoer])
155
+
156
+ except ConfigurationError as e:
157
+ print(f"identifier prefix for {self.name} does not exist, incept must be run first", )
158
+ return -1
159
+
@@ -0,0 +1,68 @@
1
+ # -*- encoding: utf-8 -*-
2
+ """
3
+ KERI
4
+ keri.kli.commands module
5
+
6
+ """
7
+ import argparse
8
+
9
+ from hio import help
10
+ from hio.base import doing
11
+
12
+ from keri.app import connecting
13
+ from keri.app.cli.common import existing
14
+ from keri.kering import ConfigurationError, Roles
15
+
16
+ logger = help.ogler.getLogger()
17
+
18
+ parser = argparse.ArgumentParser(description='List current watchers')
19
+ parser.set_defaults(handler=lambda args: handle(args),
20
+ transferable=True)
21
+ parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True)
22
+ parser.add_argument('--alias', '-a', help='human readable alias for the identifier to whom the credential was issued',
23
+ required=True)
24
+ parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore',
25
+ required=False, default="")
26
+ parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)',
27
+ dest="bran", default=None) # passcode => bran
28
+
29
+
30
+ def handle(args):
31
+ """ Command line handler for adding an aid to a watcher's list of AIds to watch
32
+
33
+ Parameters:
34
+ args(Namespace): parsed command line arguments
35
+
36
+ """
37
+
38
+ kwa = dict(args=args)
39
+ return [doing.doify(listWatchers, **kwa)]
40
+
41
+
42
+ def listWatchers(tymth, tock=0.0, **opts):
43
+ """ Command line status handler
44
+
45
+ """
46
+ _ = (yield tock)
47
+ args = opts["args"]
48
+ name = args.name
49
+ alias = args.alias
50
+ base = args.base
51
+ bran = args.bran
52
+
53
+ try:
54
+ with existing.existingHby(name=name, base=base, bran=bran) as hby:
55
+ org = connecting.Organizer(hby=hby)
56
+ if alias is None:
57
+ alias = existing.aliasInput(hby)
58
+
59
+ hab = hby.habByName(alias)
60
+
61
+ for (aid, role, eid), ender in hab.db.ends.getItemIter(keys=(hab.pre, Roles.watcher, )):
62
+ if ender.allowed:
63
+ contact = org.get(eid)
64
+ print(f"{contact['alias']}: {eid}")
65
+
66
+ except ConfigurationError as e:
67
+ print(f"identifier prefix for {name} does not exist, incept must be run first", )
68
+ return -1