-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: improve vc export api surface #770
Conversation
* | ||
* After adding the proof stub to the credential, the resulting document must be processed | ||
* by the `finalizeProof` method to make necessary adjustments to the document itself. | ||
* To do so, the document, with the proof added, must be processed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to expose one additional method that returns an object that the createProof
proof then takes? So instead of exposing a createProof
and saying that the finalizeProof
must be called, having a method that returns a NonFinalizedProof
, which is then passed to the createProof
to finalize the object? So basically the first method does what the createProof
does now, and createProof
would do what finalizeProof
does now.
In short, relying on the static type system TS provides to make sure that a user won't be able to use a half-created proof.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you look at the implementation in jsonld-signatures
, this is called only with the following arguments:
const proof = await suite.createProof({
document: input, purpose, documentLoader
});
-> there is no good way to pass additional input besides the document to be signed, which also cannot be altered in the signing process. I'm saying no good way bc you could probably craft a purpose
that contains the non-finalised proof, but then again, where is the point if the result is a document that still can't be verified with that proof?
The changes I proposed make the suite class stateless. If you want to swap the order of things, I could offer that we keep it stateful and require users to call some method (maybe anchorCredential
) before using createProof
or functions that rely on it (jsigs sign
& vc-js issue
). In that case, the story would be 'you first anchor the credential on the blockchain, then you create a proof over it being anchored'. Note that in this case, anchorCredential
would be the step at which an attestation is made, and no longer createProof
. The class instance would then keep track of data required to create the proof (block of inclusion, nonces, etc) and look them up on creating a proof.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be best, if not possible to have compilation-time errors, to have runtime errors before the user sends anything to the verifier. Hence, we should aim to provide a guarantee that "if the proof has been generated and sent following the logic in this SDK, it won't fail to pass the verifier's checks (except revocation etc etc)".
So it's probably fine to have one more step in between, rather than entirely relying on documentation, as is the case now, AFAICT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a pretty easy fix for producing compile-time errors if you try to send off a credential that has not yet been run through finalizeProof
would be creating proofs where the type field is something else (e.g. NonFinalizedKiltAttestationProof
), which is then changed once processed. Personally, I don't really like that solution though... It seems like a more straightforward interface to require preprocessing/anchoring first, and then create the proof after the fact. If you get past this point you are sure to have a valid credential.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it! I am just not sure about specifying the TxHandler
so early on in the process of creating a new credential.
ctypes?: ICType[] | ||
transactionHandler?: AttestationHandler | ||
}) { | ||
transactionHandler?: TxHandler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the advantage of having a DidSigner
as a class member, but what if the TxHandler
would be provided only when needed?
Both are optional, but it’s true that they are only used by a single method, so if you think they should be parameters on it instead, that can be done
|
I think moving the |
In my eyes, any argument that applies to the txHandler applies to the didSigner just as much, so I'd move them both. |
What changes:
timestamp
an optional parameter onKiltCredentialV1.fromInput
and fixes a bug on this function.ctype
parameter to be a CType id only, as the CType object has no use here any more.KiltAttestationV1Suite.createProof
so that it returns a complete proof object. There is still another step needed prior to calling this (anchorCredential
) which produces the attestation and adds it to chain, as well as edits the credential so that it becomes verifiable with this proof (id, issuanceDate, credentialStatus, etc).api
parameter of the attestation suite - simply uses the cached api now, as this did not filter down to all functions called under the hood.did
&didSigner
parameters onissue
to adidSigner
interface and thesubmitterAddress
&txSubmissionHandler
to atransactionHandler
interface. Callers now also have the choice between implementing submission themselves or only supplying a transactionsigner
, in which case a default submitter callback will be constructed.How to test:
Ideally, try out the new api surface and see if it is nice(r) to use.
Checklist: