Asks deviceId, belonging to userId, to verify itself against this
device, and returns the opaque identifier every other call below
addresses that flow by.
The identifier is opaque: hand it back verbatim and parse nothing out of
it.
The device must already be known, which means a 'keys_query' for
that user must have been pumped and marked sent -- see
getDeviceStatuses. A device this library has never been told
about rejects with kind 'unknown_device', which is fixed by querying
and calling again, and is deliberately a different kind from
'malformed_identifier', which no retry fixes.
Nothing reaches the other device until you pump. This queues an
invitation among takeOutgoingRequests' output; the far side sees
nothing until you have sent it and reported it with
markRequestSent. That is true of every call in this group.
The sequence by short string, for the side that asks:
pump again -- the flow reaches 'done', and only then does
getDeviceStatuses report the device verified
That was the whole of this list until a scannable code arrived, and it
is now one of two ways to finish. Steps 1 and 2 are the same for both;
from 'ready' a flow that negotiated codes takes
getVerificationCode and confirmScan on the showing side,
or submitScannedCode on the reading side, and reaches step 7 the
same way. Nothing is negotiated unless the product asked, so a build that
never calls offerScannableCodes gets exactly the seven steps
above and nothing else. See offerScannableCodes.
The side that was asked does the same from step 2, calling
acceptVerification first. Its verificationId is handed to it by
onCryptoSignal -- exported from this package's root alongside these,
and the thing that announces inbound invitations. See
acceptVerification's own comment. Either side may call
startVerificationComparison; the other gets
'comparison_already_started', answers the comparison with a second
acceptVerification, and carries on from step 4.
One sync between two verifications with the same person
Call receiveSyncChanges at least once between finishing one
verification with somebody and starting the next with that same person.
Without it the new one comes back already cancelled: nothing was refused,
nothing failed, and getVerificationStage simply reads
'cancelled' from the start.
This is the layer underneath, not a rule of this library, and it is not
something a workaround here could remove. It allows one live verification
per person, and a verification that finished is not a cancelled one,
so a second request opened while the first is still in its map cancels
both. The only thing that empties that map is the sweep it runs at the top
of every sync. An ordinary product never notices, because it syncs
continuously; a product that drives two verifications back to back from
one screen, or from a test, walks straight into it.
The same applies after a verification you gave up on with
cancelVerification, and after one that ended any other way. Any
sync will do and it does not have to carry anything: an empty payload is
enough, because it is the sweep that matters and not the contents.
Asks
deviceId, belonging touserId, to verify itself against this device, and returns the opaque identifier every other call below addresses that flow by.The identifier is opaque: hand it back verbatim and parse nothing out of it.
The device must already be known, which means a
'keys_query'for that user must have been pumped and marked sent -- see getDeviceStatuses. A device this library has never been told about rejects with kind'unknown_device', which is fixed by querying and calling again, and is deliberately a different kind from'malformed_identifier', which no retry fixes.Nothing reaches the other device until you pump. This queues an invitation among takeOutgoingRequests' output; the far side sees nothing until you have sent it and reported it with markRequestSent. That is true of every call in this group.
The sequence by short string, for the side that asks:
requestVerification-> pump'ready'(the other side has called acceptVerification and you have pumped their answer in through receiveSyncChanges)'keys-exchanged', pumping throughout'done', and only then does getDeviceStatuses report the device verifiedThat was the whole of this list until a scannable code arrived, and it is now one of two ways to finish. Steps 1 and 2 are the same for both; from
'ready'a flow that negotiated codes takes getVerificationCode and confirmScan on the showing side, or submitScannedCode on the reading side, and reaches step 7 the same way. Nothing is negotiated unless the product asked, so a build that never calls offerScannableCodes gets exactly the seven steps above and nothing else. See offerScannableCodes.The side that was asked does the same from step 2, calling acceptVerification first. Its
verificationIdis handed to it byonCryptoSignal-- exported from this package's root alongside these, and the thing that announces inbound invitations. SeeacceptVerification's own comment. Either side may call startVerificationComparison; the other gets'comparison_already_started', answers the comparison with a second acceptVerification, and carries on from step 4.One sync between two verifications with the same person
Call receiveSyncChanges at least once between finishing one verification with somebody and starting the next with that same person. Without it the new one comes back already cancelled: nothing was refused, nothing failed, and getVerificationStage simply reads
'cancelled'from the start.This is the layer underneath, not a rule of this library, and it is not something a workaround here could remove. It allows one live verification per person, and a verification that finished is not a cancelled one, so a second request opened while the first is still in its map cancels both. The only thing that empties that map is the sweep it runs at the top of every sync. An ordinary product never notices, because it syncs continuously; a product that drives two verifications back to back from one screen, or from a test, walks straight into it.
The same applies after a verification you gave up on with cancelVerification, and after one that ended any other way. Any sync will do and it does not have to carry anything: an empty payload is enough, because it is the sweep that matters and not the contents.