def createAgent(agentClass, name, wallet=None, basedirpath=None, port=None, loop=None, clientClass=Client): config = getConfig() if not wallet: wallet = Wallet(name) wallet.addIdentifier(signer=DidSigner( seed=randomString(32).encode('utf-8'))) if not basedirpath: basedirpath = config.baseDir if not port: _, port = genHa() client = create_client(base_dir_path=basedirpath, client_class=clientClass) return agentClass(basedirpath=basedirpath, client=client, wallet=wallet, port=port, loop=loop)
def test_non_steward_cannot_create_trust_anchor(nodeSet, trustAnchor, addedTrustAnchor, client1, looper): with whitelistextras("UnknownIdentifier"): non_permission = Wallet() signer = DidSigner() non_permission.addIdentifier(signer=signer) createNym(looper, non_permission.defaultId, trustAnchor, addedTrustAnchor, role=None, verkey=non_permission.getVerkey()) op = add_nym_operation(seed=b'a secret trust anchor seed......', role=TRUST_ANCHOR) submitAndCheckRejects(looper=looper, client=client1, wallet=non_permission, op=op, identifier=non_permission.defaultId, contains="UnauthorizedClientRequest")
def test_attr_with_no_dest_added(nodeSet, tdirWithClientPoolTxns, looper, trustAnchor, addedTrustAnchor, attributeData): user_wallet = Wallet() signer = DidSigner() user_wallet.addIdentifier(signer=signer) client, _ = genTestClient(nodeSet, tmpdir=tdirWithClientPoolTxns, usePoolLedger=True) client.registerObserver(user_wallet.handleIncomingReply) looper.add(client) looper.run(client.ensureConnectedToNodes()) makePendingTxnsRequest(client, user_wallet) createNym(looper, user_wallet.defaultId, trustAnchor, addedTrustAnchor, role=None, verkey=user_wallet.getVerkey()) attr1 = json.dumps({'age': "24"}) attrib = Attribute(name='test4 attribute', origin=user_wallet.defaultId, value=attr1, dest=None, ledgerStore=LedgerStore.RAW) addAttributeAndCheck(looper, client, user_wallet, attrib)
def put_load(): port = genHa()[1] ha = HA('0.0.0.0', port) name = "hello" wallet = Wallet(name) wallet.addIdentifier( signer=DidSigner(seed=b'000000000000000000000000Steward1')) client = Client(name, ha=ha) with Looper(debug=getConfig().LOOPER_DEBUG) as looper: looper.add(client) print('Will send {} reqs in all'.format(numReqs)) requests = sendRandomRequests(wallet, client, numReqs) start = perf_counter() for i in range(0, numReqs, numReqs // splits): print('Will wait for {} now'.format(numReqs // splits)) s = perf_counter() reqs = requests[i:i + numReqs // splits + 1] waitForSufficientRepliesForRequests(looper, client, requests=reqs, customTimeoutPerReq=100, override_timeout_limit=True) print('>>> Got replies for {} requests << in {}'. format(numReqs // splits, perf_counter() - s)) end = perf_counter() print('>>>Total {} in {}<<<'.format(numReqs, end - start)) exit(0)
def clientFromSigner(signer, looper, nodeSet, tdir): wallet = Wallet(signer.identifier) wallet.addIdentifier(signer) s = genTestClient(nodeSet, tmpdir=tdir, identifier=signer.identifier) looper.add(s) looper.run(s.ensureConnectedToNodes()) return s
def put_load(): port = genHa()[1] ha = HA('0.0.0.0', port) name = "hello" wallet = Wallet(name) wallet.addIdentifier(signer=DidSigner( seed=b'000000000000000000000000Steward1')) client = Client(name, ha=ha) with Looper(debug=getConfig().LOOPER_DEBUG) as looper: looper.add(client) print('Will send {} reqs in all'.format(numReqs)) requests = sendRandomRequests(wallet, client, numReqs) start = perf_counter() for i in range(0, numReqs, numReqs // splits): print('Will wait for {} now'.format(numReqs // splits)) s = perf_counter() reqs = requests[i:i + numReqs // splits + 1] waitForSufficientRepliesForRequests(looper, client, requests=reqs, customTimeoutPerReq=100, override_timeout_limit=True) print('>>> Got replies for {} requests << in {}'.format( numReqs // splits, perf_counter() - s)) end = perf_counter() print('>>>Total {} in {}<<<'.format(numReqs, end - start)) exit(0)
def clientAndWallet1(client1Signer, looper, nodeSet, tdirWithClientPoolTxns): client, wallet = genTestClient(nodeSet, tmpdir=tdirWithClientPoolTxns, usePoolLedger=True) wallet = Wallet(client.name) wallet.addIdentifier(signer=client1Signer) return client, wallet
def test_non_steward_cannot_create_trust_anchor( nodeSet, trustAnchor, addedTrustAnchor, client1, looper): with whitelistextras("UnknownIdentifier"): non_permission = Wallet() signer = DidSigner() non_permission.addIdentifier(signer=signer) createNym(looper, non_permission.defaultId, trustAnchor, addedTrustAnchor, role=None, verkey=non_permission.getVerkey()) op = add_nym_operation( seed=b'a secret trust anchor seed......', role=TRUST_ANCHOR) submitAndCheckRejects( looper=looper, client=client1, wallet=non_permission, op=op, identifier=non_permission.defaultId, contains="UnauthorizedClientRequest")
def create_thrift(name=None, wallet=None, base_dir_path=None, port=7777, client=None): endpoint_args = {'onlyListener': True} if wallet: endpoint_args['seed'] = wallet._signerById(wallet.defaultId).seed else: wallet = Wallet(name) wallet.addIdentifier(signer=THRIFT_SIGNER) endpoint_args['seed'] = THRIFT_SEED if client is None: client = create_client(base_dir_path=base_dir_path, client_class=TestClient) agent = ThriftAgent(name=name or 'Thrift Bank', basedirpath=base_dir_path, client=client, wallet=wallet, port=port, endpointArgs=endpoint_args) agent._invites = { "77fbf9dc8c8e6acde33de98c6d747b28c": (1, "Alice"), "ousezru20ic4yz3j074trcgthwlsnfsef": (2, "Bob") } return agent
def nonTrustAnchor(looper, nodeSet, tdir): sseed = b'a secret trust anchor seed......' signer = DidSigner(seed=sseed) c, _ = genTestClient(nodeSet, tmpdir=tdir, usePoolLedger=True) w = Wallet(c.name) w.addIdentifier(signer=signer) c.registerObserver(w.handleIncomingReply) looper.add(c) looper.run(c.ensureConnectedToNodes()) return c, w
def createClientAndWalletWithSeed(name, seed, ha=None): if isinstance(seed, str): seed = seed.encode() if not ha: port = genHa()[1] ha = HA('0.0.0.0', port) wallet = Wallet(name) wallet.addIdentifier(signer=DidSigner(seed=seed)) client = Client(name, ha=ha) return client, wallet
def nonTrustAnchor(looper, nodeSet, tdirWithClientPoolTxns): sseed = b'a secret trust anchor seed......' signer = DidSigner(seed=sseed) c, _ = genTestClient(nodeSet, tmpdir=tdirWithClientPoolTxns, usePoolLedger=True) w = Wallet(c.name) w.addIdentifier(signer=signer) c.registerObserver(w.handleIncomingReply) looper.add(c) looper.run(c.ensureConnectedToNodes()) return c, w
def spawnClient(clientName, port, signerSeed, host='0.0.0.0'): clientAddress = HA(host, port) # from plenum.client.request_id_store import FileRequestIdStore # walletFilePath = os.path.join(config.baseDir, "wallet") # print("Storing request ids in {}".format(walletFilePath)) # store = FileRequestIdStore(walletFilePath) # wallet = Wallet(clientName, store) wallet = Wallet(clientName) wallet.addIdentifier(signer=DidSigner(seed=signerSeed)) client = Client(clientName, ha=clientAddress) return client, wallet
def anotherTrustAnchor(nodeSet, steward, stewardWallet, tdirWithClientPoolTxns, looper): sseed = b'1 secret trust anchor seed......' signer = DidSigner(seed=sseed) c, _ = genTestClient(nodeSet, tmpdir=tdirWithClientPoolTxns, usePoolLedger=True) w = Wallet(c.name) w.addIdentifier(signer=signer) c.registerObserver(w.handleIncomingReply) looper.add(c) looper.run(c.ensureConnectedToNodes()) createNym(looper, signer.identifier, steward, stewardWallet, role=TRUST_ANCHOR, verkey=signer.verkey) return c, w
def testNonTrustAnchoredNymCanDoGetNym(nodeSet, addedTrustAnchor, trustAnchorWallet, tdir, looper): signer = DidSigner() someClient, _ = genTestClient(nodeSet, tmpdir=tdir, usePoolLedger=True) wallet = Wallet(someClient.name) wallet.addIdentifier(signer=signer) someClient.registerObserver(wallet.handleIncomingReply) looper.add(someClient) looper.run(someClient.ensureConnectedToNodes()) needle = trustAnchorWallet.defaultId makeGetNymRequest(someClient, wallet, needle) timeout = waits.expectedTransactionExecutionTime(len(nodeSet)) looper.run( eventually(someClient.hasNym, needle, retryWait=1, timeout=timeout))
def testNonTrustAnchoredNymCanDoGetNym(nodeSet, addedTrustAnchor, trustAnchorWallet, tdirWithClientPoolTxns, looper): signer = DidSigner() someClient, _ = genTestClient(nodeSet, tmpdir=tdirWithClientPoolTxns, usePoolLedger=True) wallet = Wallet(someClient.name) wallet.addIdentifier(signer=signer) someClient.registerObserver(wallet.handleIncomingReply) looper.add(someClient) looper.run(someClient.ensureConnectedToNodes()) needle = trustAnchorWallet.defaultId makeGetNymRequest(someClient, wallet, needle) timeout = waits.expectedTransactionExecutionTime(len(nodeSet)) looper.run(eventually(someClient.hasNym, needle, retryWait=1, timeout=timeout))
def addUser(looper, creatorClient, creatorWallet, name, addVerkey=True): wallet = Wallet(name) signer = DidSigner() idr, _ = wallet.addIdentifier(signer=signer) verkey = wallet.getVerkey(idr) if addVerkey else None createNym(looper, idr, creatorClient, creatorWallet, verkey=verkey) return wallet
def new_identity(): wallet = Wallet(randomString(5)) signer = DidSigner() new_idr, _ = wallet.addIdentifier(signer=signer) verkey = wallet.getVerkey(new_idr) idy = Identity(identifier=new_idr, verkey=verkey, role=None) return idy, wallet
def build_wallet_core(wallet_name, seed_file): config = getConfig() baseDir = os.path.expanduser(config.CLI_BASE_DIR) seedFilePath = '{}/{}'.format(baseDir, seed_file) seed = wallet_name + '0' * (32 - len(wallet_name)) # if seed file is available, read seed from it if os.path.isfile(seedFilePath): with open(seedFilePath, mode='r+') as file: seed = file.read().strip(' \t\n\r') wallet = Wallet(wallet_name) seed = bytes(seed, encoding='utf-8') wallet.addIdentifier(signer=DidSigner(seed=seed)) return wallet
def sendRandomRequests(wallet: Wallet, client: Client, count: int): print('{} random requests will be sent'.format(count)) for i in range(count): idr, signer = wallet.addIdentifier() idy = Identity(identifier=idr, verkey=signer.verkey) wallet.addTrustAnchoredIdentity(idy) reqs = wallet.preparePending() return client.submitReqs(*reqs)[0]
def createAgent(agentClass, name, wallet=None, basedirpath=None, port=None, loop=None, clientClass=Client): config = getConfig() if not wallet: wallet = Wallet(name) wallet.addIdentifier(signer=DidSigner( seed=randomString(32).encode('utf-8'))) if not basedirpath: basedirpath = config.CLI_BASE_DIR if not port: _, port = genHa() client = create_client(base_dir_path=basedirpath, client_class=clientClass) return agentClass(basedirpath=basedirpath, client=client, wallet=wallet, port=port, loop=loop)
def testNewKeyChangesWalletsDefaultId(be, do, poolNodesStarted, poolTxnData, susanCLI): mywallet = Wallet('my wallet') keyseed = 'a' * 32 idr, _ = mywallet.addIdentifier(seed=keyseed.encode("utf-8")) be(susanCLI) connect_and_check_output(do, susanCLI.txn_dir) do('new key with seed {}'.format(keyseed)) do('send NYM dest={}'.format(idr)) do('new key with seed {}'.format(poolTxnData['seeds']['Steward1'])) do('send NYM dest={}'.format(idr), within=3, expect=["Nym {} added".format(idr)])
def trustAnchorWallet(trustAnchorSigner): w = Wallet(trustAnchorSigner.identifier) w.addIdentifier(signer=trustAnchorSigner) return w
def _(name): wallet = Wallet(name) wallet.addIdentifier(signer=DidSigner()) return wallet
def trustAnchorWallet(): wallet = Wallet('trustAnchor') seed = b'trust anchors are people too....' wallet.addIdentifier(seed=seed) return wallet
def buildAgentWallet(name, seed): wallet = Wallet(name) wallet.addIdentifier(signer=DidSigner(seed=seed)) return wallet
def create_acme(name=None, wallet=None, base_dir_path=None, port=6666, client=None): if client is None: client = create_client(base_dir_path=base_dir_path, client_class=TestClient) endpoint_args = {'onlyListener': True} if wallet: endpoint_args['seed'] = wallet._signerById(wallet.defaultId).seed else: wallet = Wallet(name) wallet.addIdentifier(signer=ACME_SIGNER) endpoint_args['seed'] = ACME_SEED agent = AcmeAgent(name=name or "Acme Corp", basedirpath=base_dir_path, client=client, wallet=wallet, port=port, endpointArgs=endpoint_args) # maps request nonces to internal ids agent._invites = { "57fbf9dc8c8e6acde33de98c6d747b28c": (1, "Alice"), "3a2eb72eca8b404e8d412c5bf79f2640": (2, "Carol"), "8513d1397e87cada4214e2a650f603eb": (3, "Frank"), "810b78be79f29fc81335abaa4ee1c5e8": (4, "Bob") } job_cert_def = AttribDef('Job-Certificate', [AttribType('first_name', encode=True), AttribType('last_name', encode=True), AttribType('employee_status', encode=True), AttribType('experience', encode=True), AttribType('salary_bracket', encode=True)]) job_appl_def = AttribDef('Job-Application', [AttribType('first_name', encode=True), AttribType('last_name', encode=True), AttribType('phone_number', encode=True), AttribType('degree', encode=True), AttribType('status', encode=True), AttribType('ssn', encode=True)]) agent.add_attribute_definition(job_cert_def) agent.add_attribute_definition(job_appl_def) backend = MockBackendSystem(job_cert_def) backend.add_record(1, first_name="Alice", last_name="Garcia", employee_status="Permanent", experience="3 years", salary_bracket="between $50,000 to $100,000") backend.add_record(2, first_name="Carol", last_name="Atkinson", employee_status="Permanent", experience="2 years", salary_bracket="between $60,000 to $90,000") backend.add_record(3, first_name="Frank", last_name="Jeffrey", employee_status="Temporary", experience="4 years", salary_bracket="between $40,000 to $80,000") backend.add_record(4, first_name="Bob", last_name="Richards", employee_status="On Contract", experience="3 years", salary_bracket="between $50,000 to $70,000") agent.set_issuer_backend(backend) agent._proofRequestsSchema = { "Job-Application-v0.2": { "name": "Job-Application", "version": "0.2", "attributes": { "first_name": "string", "last_name": "string", "phone_number": "string", "degree": "string", "status": "string", "ssn": "string" }, "verifiableAttributes": ["degree", "status", "ssn"] }, "Job-Application-v0.3": { "name": "Job-Application-2", "version": "0.3", "attributes": { "first_name": "string", "last_name": "string", "phone_number": "string", "degree": "string", "status": "string", "ssn": "string" }, "verifiableAttributes": ["degree", "status"] } } return agent
def _newWallet(name=None): signer = SimpleSigner() w = Wallet(name or signer.identifier) w.addIdentifier(signer=signer) return w
def create_faber(name=None, wallet=None, base_dir_path=None, port=5555, client=None): if client is None: client = create_client(base_dir_path=base_dir_path, client_class=TestClient) endpoint_args = {'onlyListener': True} if wallet: endpoint_args['seed'] = wallet._signerById(wallet.defaultId).seed else: wallet = Wallet(name) wallet.addIdentifier(signer=FABER_SIGNER) endpoint_args['seed'] = FABER_SEED agent = WalletedAgent(name=name or "Faber College", basedirpath=base_dir_path, client=client, wallet=wallet, port=port, endpointArgs=endpoint_args) agent._invites = { "b1134a647eb818069c089e7694f63e6d": (1, "Alice"), "2a2eb72eca8b404e8d412c5bf79f2640": (2, "Carol"), "7513d1397e87cada4214e2a650f603eb": (3, "Frank"), "710b78be79f29fc81335abaa4ee1c5e8": (4, "Bob") } transcript_def = AttribDef('Transcript', [AttribType('student_name', encode=True), AttribType('ssn', encode=True), AttribType('degree', encode=True), AttribType('year', encode=True), AttribType('status', encode=True)]) agent.add_attribute_definition(transcript_def) backend = MockBackendSystem(transcript_def) backend.add_record(1, student_name="Alice Garcia", ssn="123-45-6789", degree="Bachelor of Science, Marketing", year="2015", status="graduated") backend.add_record(2, student_name="Carol Atkinson", ssn="783-41-2695", degree="Bachelor of Science, Physics", year="2012", status="graduated") backend.add_record(3, student_name="Frank Jeffrey", ssn="996-54-1211", degree="Bachelor of Arts, History", year="2013", status="dropped") backend.add_record(4, student_name="Bob Richards", ssn="151-44-5876", degree="MBA, Finance", year="2015", status="graduated") agent.set_issuer_backend(backend) return agent
def clientAndWallet1(client1Signer, looper, nodeSet, tdirWithClientPoolTxns, up): client, wallet = genTestClient(nodeSet, tmpdir=tdirWithClientPoolTxns, usePoolLedger=True) wallet = Wallet(client.name) wallet.addIdentifier(signer=client1Signer) return client, wallet
def stewardWallet(poolTxnStewardData): name, sigseed = poolTxnStewardData wallet = Wallet('steward') signer = DidSigner(seed=sigseed) wallet.addIdentifier(signer=signer) return wallet
def trusteeWallet(trusteeData): name, sigseed, txn = trusteeData[0] wallet = Wallet('trustee') signer = DidSigner(seed=sigseed) wallet.addIdentifier(signer=signer) return wallet
class UserScenario(metaclass=ABCMeta): def __init__(self, seed, logFileName=None): if logFileName: Logger().enableFileLogging(logFileName) self._seed = seed self._client = None self._wallet = None self._looper = None @property def identifier(self): if self._wallet: return self._wallet.defaultId else: return None @property def verkey(self): if self._wallet: return self._wallet.getVerkey() else: return None @classmethod def runInstance(cls, *args, **kwargs): cls(*args, **kwargs).run() def run(self): try: self._createClientAndWallet() self._looper = Looper(debug=getConfig().LOOPER_DEBUG) try: self._startClient() self.do() finally: self._looper.shutdownSync() self._looper = None except BaseException as ex: logger.exception( "User scenario throws out exception: {}".format(ex), exc_info=ex) raise ex @abstractmethod def do(self): pass def performOperation(self, op): req = self._wallet.signOp(op) self._client.submitReqs(req) def getRequestResult(reqKey): reply, error = self._client.replyIfConsensus(*reqKey) if reply is None and error is None: raise Exception("Request has not been completed yet") else: return reply, error reply, error = self._looper.run( eventually(partial(getRequestResult, req.key), retryWait=.5, timeout=5)) assert not error, error if reply[DATA]: result = json.loads(reply[DATA]) else: result = None return result def generateNewSigner(self): assert self.identifier return SimpleSigner(identifier=self.identifier) def changeSigner(self, newSigner): assert newSigner.identifier == self.identifier self._wallet.updateSigner(self.identifier, newSigner) logger.info("Changed signer. New verkey: {}".format(self.verkey)) def _createClientAndWallet(self): signer = SimpleSigner(seed=self._seed) port = genHa()[1] ha = HA('0.0.0.0', port) self._client = Client(name=signer.identifier, ha=ha) self._wallet = Wallet(name=signer.identifier) self._wallet.addIdentifier(signer=signer) logger.info("Identifier: {}".format(self.identifier)) logger.info("Signer's verkey: {}".format(self.verkey)) def _startClient(self): self._looper.add(self._client) def ensureConnectedToAll(): connectedNodes = self._client.nodestack.connecteds connectedNodesNum = len(connectedNodes) totalNodes = len(self._client.nodeReg) logger.info("Connected {} / {} nodes".format( connectedNodesNum, totalNodes)) for node in connectedNodes: logger.info(" {}".format(node)) if connectedNodesNum == 0: raise Exception("Not connected to any") elif connectedNodesNum < totalNodes * 0.8: raise Exception("Not connected fully") else: return True self._looper.run( eventually(ensureConnectedToAll, retryWait=.5, timeout=5))
def create_faber(name=None, wallet=None, base_dir_path=None, port=5555, client=None): if client is None: client = create_client(base_dir_path=base_dir_path, client_class=TestClient) endpoint_args = {'onlyListener': True} if wallet: endpoint_args['seed'] = wallet._signerById(wallet.defaultId).seed else: wallet = Wallet(name) wallet.addIdentifier(signer=FABER_SIGNER) endpoint_args['seed'] = FABER_SEED agent = WalletedAgent(name=name or "Faber College", basedirpath=base_dir_path, client=client, wallet=wallet, port=port, endpointArgs=endpoint_args) agent._invites = { "b1134a647eb818069c089e7694f63e6d": (1, "Alice"), "2a2eb72eca8b404e8d412c5bf79f2640": (2, "Carol"), "7513d1397e87cada4214e2a650f603eb": (3, "Frank"), "710b78be79f29fc81335abaa4ee1c5e8": (4, "Bob") } transcript_def = AttribDef('Transcript', [ AttribType('student_name', encode=True), AttribType('ssn', encode=True), AttribType('degree', encode=True), AttribType('year', encode=True), AttribType('status', encode=True) ]) agent.add_attribute_definition(transcript_def) backend = MockBackendSystem(transcript_def) backend.add_record(1, student_name="Alice Garcia", ssn="123-45-6789", degree="Bachelor of Science, Comp Sci", year="2015", status="graduated") backend.add_record(2, student_name="Carol Atkinson", ssn="783-41-2695", degree="Bachelor of Science, Physics", year="2012", status="graduated") backend.add_record(3, student_name="Frank Jeffrey", ssn="996-54-1211", degree="Bachelor of Arts, History", year="2013", status="dropped") backend.add_record(4, student_name="Bob Richards", ssn="151-44-5876", degree="MBA, Finance", year="2015", status="graduated") agent.set_issuer_backend(backend) return agent
def create_acme(name=None, wallet=None, base_dir_path=None, port=6666, client=None): if client is None: client = create_client(base_dir_path=None, client_class=TestClient) endpoint_args = {'onlyListener': True} if wallet: endpoint_args['seed'] = wallet._signerById(wallet.defaultId).seed else: wallet = Wallet(name) wallet.addIdentifier(signer=ACME_SIGNER) endpoint_args['seed'] = ACME_SEED agent = AcmeAgent(name=name or "Acme Corp", basedirpath=base_dir_path, client=client, wallet=wallet, port=port, endpointArgs=endpoint_args) # maps request nonces to internal ids agent._invites = { "57fbf9dc8c8e6acde33de98c6d747b28c": (1, "Alice"), "3a2eb72eca8b404e8d412c5bf79f2640": (2, "Carol"), "8513d1397e87cada4214e2a650f603eb": (3, "Frank"), "810b78be79f29fc81335abaa4ee1c5e8": (4, "Bob") } job_cert_def = AttribDef('Job-Certificate', [AttribType('first_name', encode=True), AttribType('last_name', encode=True), AttribType('employee_status', encode=True), AttribType('experience', encode=True), AttribType('salary_bracket', encode=True)]) job_appl_def = AttribDef('Job-Application', [AttribType('first_name', encode=True), AttribType('last_name', encode=True), AttribType('phone_number', encode=True), AttribType('degree', encode=True), AttribType('status', encode=True), AttribType('ssn', encode=True)]) agent.add_attribute_definition(job_cert_def) agent.add_attribute_definition(job_appl_def) backend = MockBackendSystem(job_cert_def) backend.add_record(1, first_name="Alice", last_name="Garcia", employee_status="Permanent", experience="3 years", salary_bracket="between $50,000 to $100,000") backend.add_record(2, first_name="Carol", last_name="Atkinson", employee_status="Permanent", experience="2 years", salary_bracket="between $60,000 to $90,000") backend.add_record(3, first_name="Frank", last_name="Jeffrey", employee_status="Temporary", experience="4 years", salary_bracket="between $40,000 to $80,000") backend.add_record(4, first_name="Bob", last_name="Richards", employee_status="On Contract", experience="3 years", salary_bracket="between $50,000 to $70,000") agent.set_issuer_backend(backend) agent._proofRequestsSchema = { "Job-Application-v0.2": { "name": "Job-Application", "version": "0.2", "attributes": { "first_name": "string", "last_name": "string", "phone_number": "string", "degree": "string", "status": "string", "ssn": "string" }, "verifiableAttributes": ["degree", "status", "ssn"] }, "Job-Application-v0.3": { "name": "Job-Application-2", "version": "0.3", "attributes": { "first_name": "string", "last_name": "string", "phone_number": "string", "degree": "string", "status": "string", "ssn": "string" }, "verifiableAttributes": ["degree", "status"] } } return agent