Skip to content

Commit

Permalink
Scripts to join a multisig group migrated from a multisig created wit…
Browse files Browse the repository at this point in the history
…h 4 KLI participants. These scripts create 4 KERIA agents each with their own Salty AID and then accepts the rotation of a mutlsig group AID adding them as the sole participants in the group multisig.

Signed-off-by: pfeairheller <[email protected]>
  • Loading branch information
pfeairheller committed Nov 9, 2023
1 parent 83292c0 commit cf985d4
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 3 deletions.
96 changes: 96 additions & 0 deletions scripts/join_new_quadlet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# -*- encoding: utf-8 -*-
"""
SIGNIFY
join new quadlet script
"""

from time import sleep

from keri.core import eventing, coring
from keri.core.coring import Tiers
from signify.app.clienting import SignifyClient


def join_new_quadlet():
group = "multisig"
client1 = get_client(bran=b'0123456789abcdefghsec')
client2 = get_client(bran=b'0123456789abcdefghsaw')

op2 = accept_join_request(client2, name="multisig2", group=group)
if not op2:
raise ValueError("No op created for multisig2")
op1 = accept_join_request(client1, name="multisig1", group=group)
if not op1:
raise ValueError("No op created for multisig1")

while not op2['done']:
sleep(1)
op2 = client2.operations().get(op2['name'])

while not op1['done']:
sleep(1)
op1 = client1.operations().get(op1['name'])


def get_client(bran):
url = "http://localhost:3901"
tier = Tiers.low

return SignifyClient(passcode=bran, tier=tier, url=url)


def accept_join_request(client, name, group):
identifiers = client.identifiers()
notificatons = client.notifications()
exchanges = client.exchanges()
groups = client.groups()

hab = identifiers.get(name)

resp = notificatons.list()

for note in resp['notes']:
payload = note['a']
route = payload['r']
if route == "/multisig/rot":
said = payload['d']

res = exchanges.get(name=name, said=said)
exn = res['exn']
a = exn['a']

gid = a['gid']
smids = a['smids']
rmids = a['rmids']

recipients = list(set(smids + (rmids or [])))
recipients.remove(hab['prefix'])

idx = smids.index(hab["prefix"])
odx = rmids.index(hab['prefix'])

embeds = exn['e']
ked = embeds['rot']
rot = coring.Serder(ked=ked)

keeper = client.manager.get(aid=hab)
sigs = keeper.sign(ser=rot.raw, indexed=True, indices=[idx], ondices=[odx])

op = groups.join(group, rot, sigs, gid, smids, rmids)

embeds = dict(
rot=eventing.messagize(serder=rot, sigers=[coring.Siger(qb64=sig) for sig in sigs])
)

exchanges.send(name, "multisig", sender=hab, route="/multisig/rot",
payload=dict(gid=gid, smids=smids, rmids=smids),
embeds=embeds, recipients=recipients)

return op

return None


if __name__ == "__main__":
join_new_quadlet()
29 changes: 29 additions & 0 deletions scripts/list_kevers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- encoding: utf-8 -*-
"""
SIGNIFY
signify.app.clienting module
Testing clienting with integration tests that require a running KERIA Cloud Agent
"""
import json

from keri.core.coring import Tiers
from signify.app.clienting import SignifyClient


def list_contacts():
url = "http://localhost:3901"
bran = b'0123456789abcdefghsaw'
tier = Tiers.low

client = SignifyClient(passcode=bran, tier=tier, url=url)
keyStates = client.keyStates()

multisig1 = keyStates.get("EKYLUMmNPZeEs77Zvclf0bSN5IN-mLfLpx2ySb-HDlk4")
multisig2 = keyStates.get("EJccSRTfXYF6wrUVuenAIHzwcx3hJugeiJsEKmndi5q1")

print(json.dumps([multisig1, multisig2]))


if __name__ == "__main__":
list_contacts()
4 changes: 2 additions & 2 deletions scripts/multisig-kli-rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ def create_multisig():
while not op["done"]:
op = operations.get(op["name"])
sleep(1)
gAid = op["response"]
print(f"group multisig created {gAid}")
gid = op["response"]
print(f"group multisig created {gid}")

# Join an interaction event with the group
data = {"i": "EE77q3_zWb5ojgJr-R1vzsL5yiL4Nzm-bfSOQzQl02dy"}
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
],
entry_points={
'console_scripts': [
'signify = signify.app.cli.signify:main',
'sigpy = signify.app.cli.sigpy:main',
]
},
)
Expand Down
Empty file added src/signify/app/cli/__init__.py
Empty file.
Empty file.
92 changes: 92 additions & 0 deletions src/signify/app/cli/commands/status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# -*- encoding: utf-8 -*-
"""
KERI
keri.kli.commands module
"""
import argparse
import sys

from hio import help
from hio.base import doing
from keri.app.cli.common import terming
from keri.core.coring import Tiers

from signify.app import clienting

logger = help.ogler.getLogger()

parser = argparse.ArgumentParser(description='View status of a local AID')
parser.set_defaults(handler=lambda args: handler(args),
transferable=True)
parser.add_argument('--url', '-u', help='Agent URL, defaults to "http://localhost:3901"',
default="http://localhost:3901")
parser.add_argument('--alias', '-a', help='human readable alias for the new identifier prefix', default=None)
parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)',
dest="bran", default=None) # passcode => bran

parser.add_argument("--verbose", "-V", help="print JSON of all current events", action="store_true")


def handler(args):
kwa = dict(args=args)
return [doing.doify(status, **kwa)]


def status(tymth, tock=0.0, **opts):
""" Command line status handler
"""
_ = (yield tock)
args = opts["args"]
alias = args.alias
bran = args.bran

url = args.url
tier = Tiers.low

client = clienting.SignifyClient(passcode=bran, tier=tier, url=url)
identifiers = client.identifiers()

aid = identifiers.get(alias)

printIdentifier(aid)


def printIdentifier(aid, label="Identifier"):

state = aid["state"]

print(f"Alias: \t{aid['name']}")
print("{}: {}".format(label, aid["prefix"]))
print("Seq No:\t{}".format(state['s']))
if state['di']:
anchor = True
print("Delegated Identifier")
sys.stdout.write(f" Delegator: {state['di']} ")
if anchor:
print(f"{terming.Colors.OKGREEN}{terming.Symbols.CHECKMARK} Anchored{terming.Colors.ENDC}")
else:
print(f"{terming.Colors.FAIL}{terming.Symbols.FAILED} Not Anchored{terming.Colors.ENDC}")
print()

if "group" in aid:
group = aid["group"]
accepted = True
print("Group Identifier")
sys.stdout.write(f" Local Indentifier: {group['mhab']['prefix']} ")
if accepted:
print(f"{terming.Colors.OKGREEN}{terming.Symbols.CHECKMARK} Fully Signed{terming.Colors.ENDC}")
else:
print(f"{terming.Colors.FAIL}{terming.Symbols.FAILED} Not Fully Signed{terming.Colors.ENDC}")

print("\nWitnesses:")
print("Count:\t\t{}".format(len(state['b'])))
print("Receipts:\t{}".format(len(aid['windexes'])))
print("Threshold:\t{}".format(state['bt']))
print("\nPublic Keys:\t")
for idx, key in enumerate(state['k']):
print(f'\t{idx+1}. {key}')

print()

38 changes: 38 additions & 0 deletions src/signify/app/cli/sigpy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- encoding: utf-8 -*-
"""
keri.kli.commands module
"""
import multicommand
from keri import help

from keri.app import directing
from signify.app.cli import commands

logger = help.ogler.getLogger()


def main():
parser = multicommand.create_parser(commands)
args = parser.parse_args()

if not hasattr(args, 'handler'):
parser.print_help()
return

try:
doers = args.handler(args)
directing.runController(doers=doers, expire=0.0)

except Exception as ex:
import os
if os.getenv('DEBUG_SIGPY'):
import traceback
traceback.print_exc()
else:
print(f"ERR: {ex}")
return -1


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions src/signify/app/grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,31 @@ def send_request(self, name, exn, sigs, atc):

res = self.client.post(f"/identifiers/{name}/multisig/request", json=body)
return res.json()

def join(self, name, rot, sigs, gid, smids, rmids):
"""
Parameters:
name:
rot:
sigs:
gid:
smids:
rmids:
Returns:
dict: ked of sent message
"""

body = dict(
tpc='multisig',
rot=rot.ked,
sigs=sigs,
gid=gid,
smids=smids,
rmids=rmids,
)

res = self.client.post(f"/identifiers/{name}/multisig/join", json=body)
return res.json()

0 comments on commit cf985d4

Please sign in to comment.