Last active
January 13, 2021 14:21
-
-
Save i1skn/7a3f169dd8d70ded02dba096de3846d8 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const isPhoneNumberDetailsFetched = (context) => { | |
return !!context.pepper && !!context.phoneHash | |
} | |
const phoneNumberFetchedWithKomenci = (context) => isPhoneNumberDetailsFetched(context) && komenciEnabled(context) | |
const phoneNumberFetchedWithoutKomenci = (context) => isPhoneNumberDetailsFetched(context) && komenciDisabled(context) | |
const shouldRetry = (context, event, { cond }) => { | |
console.log(cond, context.retries, cond.maxRetries, context.retries < cond.maxRetries) | |
return context.retries < cond.maxRetries | |
} | |
const resetRetriesAction = assign({ | |
retries: 0, | |
}) | |
const onChainAlreadyFetched = (context) => { | |
return context.completed !== null | |
} | |
const actionableAttestationsFetched = (context) => { | |
return context.actionableAttestations !== null | |
} | |
const weHaveEnoughAttestations = (context) => { | |
return actionableAttestationsFetched(context) && context.actionableAttestations.length >= context.numAttestationsRemaining | |
} | |
const doWeNeedMoreAttestations = (context) => { | |
return actionableAttestationsFetched(context) && !weHaveEnoughAttestations(context) | |
} | |
const isVerified = (context) => { | |
return context.numAttestationsRemaining != null && context.numAttestationsRemaining <= 0 | |
} | |
const notVerified = (context) => !isVerified(context) && onChainAlreadyFetched(context) | |
const weHaveEnoughRevealed = (context) => { | |
if (context.revealedAttestations === null) { | |
return false | |
} | |
return context.revealedAttestations.length >= context.numAttestationsRemaining | |
} | |
const komenciEnabled = (context) => context.isKomenciEnabled | |
const komenciDisabled = (context) => !context.isKomenciEnabled | |
const komenciReady = (context) => komenciEnabled(context) && isPhoneNumberDetailsFetched(context) | |
const komenciNotReady = (context) => !komenciEnabled(context) && isPhoneNumberDetailsFetched(context) | |
const and = (guard1, guard2) => (context) => guard1(context) && guard2(context) | |
const mtwReady = (context) => context.mtw !== null | |
const preparingKomenciState = { | |
initial: 'checkingReadiness', | |
states: { | |
checkingReadiness: { | |
on: { | |
SUCCESS: { | |
target: 'fetchSessionState', | |
}, | |
FAILURE: [ | |
{ | |
target: '#main.idle', | |
actions: assign({ | |
isKomenciEnabled: (context, event) => false, | |
}), | |
}, | |
], | |
}, | |
}, | |
fetchSessionState: { | |
on: { | |
EXISTS: { | |
target: '#main.phoneNumberDetails', | |
}, | |
NONE: [ | |
{ | |
target: '#main.checkingIsHuman', | |
actions: assign({ | |
activeKomenciSession: (context, event) => false, | |
}), | |
}, | |
], | |
} | |
}, | |
// startOrResumeKomenciSession: { | |
// on: { | |
// SUCCESS: { | |
// target: '#main.phoneNumberDetails', | |
// }, | |
// FAILURE: [ | |
// { | |
// target: '#main.idle', | |
// actions: assign({ | |
// isKomenciEnabled: (context, event) => false, | |
// }), | |
// }, | |
// ], | |
// } | |
// } | |
} | |
} | |
const checkingIsHumanState = { | |
initial: 'idle', | |
states: { | |
idle: { | |
on: { | |
PASS: { | |
target: '#main.startingKomenciSession', | |
actions: [ | |
assign({ | |
isHuman: () => true, | |
}), | |
], | |
}, | |
GO_BACK: 'idle', | |
}, | |
}, | |
}, | |
} | |
const startingKomenciSessionState = { | |
initial: 'starting', | |
states: { | |
starting: { | |
on: { | |
SUCCESS: { | |
target: '#main.phoneNumberDetails', | |
actions: [ | |
assign({ | |
activeKomenciSession: () => true, | |
}), | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: '#main.idle', | |
actions: assign({ | |
isKomenciEnabled: (context, event) => false, | |
}), | |
}, | |
], | |
}, | |
}, | |
}, | |
} | |
const phoneNumberDetailsState = { | |
initial: 'loading', | |
on: { | |
'': [{ | |
target: '#main.fetchingAccountOnChain', | |
cond: 'phoneNumberFetchedWithoutKomenci', | |
},{ | |
target: '#main.mtw', | |
cond: 'phoneNumberFetchedWithKomenci', | |
}], | |
}, | |
states: { | |
loading: { | |
on: { | |
SUCCESS: { | |
actions: [ | |
assign({ | |
pepper: () => 'pepper', | |
phoneHash: () => 'phoneHash', | |
}), | |
resetRetriesAction, | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: 'loading', | |
actions: assign({ | |
retries: (context, event) => context.retries + 1, | |
}), | |
cond: { | |
type: 'shouldRetry', | |
maxRetries: 3, | |
}, | |
}, | |
{ | |
target: 'error', | |
}, | |
], | |
}, | |
}, | |
error: { | |
type: 'final', | |
}, | |
}, | |
} | |
const onChainState = { | |
initial: 'loading', | |
on: { | |
'': [ | |
{ | |
target: '#main.verified', | |
cond: 'isVerified', | |
}, | |
{ | |
target: '#main.actionableAttestations', | |
cond: 'notVerified' | |
} | |
], | |
}, | |
states: { | |
loading: { | |
on: { | |
SUCCESS_VERIFIED: { | |
actions: [ | |
assign({ | |
numAttestationsRemaining: 0, | |
completed: 3, | |
}), | |
resetRetriesAction, | |
], | |
}, | |
SUCCESS_PARTIALLY_VERIFIED: { | |
actions: [ | |
assign({ | |
numAttestationsRemaining: 2, | |
completed: 1, | |
}), | |
resetRetriesAction, | |
], | |
}, | |
SUCCESS_NOT_VERIFIED: { | |
actions: [ | |
assign({ | |
numAttestationsRemaining: 3, | |
completed: 0, | |
}), | |
resetRetriesAction, | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: 'loading', | |
actions: assign({ | |
retries: (context, event) => context.retries + 1, | |
}), | |
cond: { | |
type: 'shouldRetry', | |
maxRetries: 3, | |
}, | |
}, | |
{ | |
target: 'error', | |
}, | |
], | |
}, | |
}, | |
error: { | |
type: 'final', | |
}, | |
}, | |
} | |
const actionableAttestationsState = { | |
initial: 'loading', | |
states: { | |
loading: { | |
on: { | |
'': { | |
target: '#main.readyToStart', | |
cond: actionableAttestationsFetched, | |
}, | |
SUCCESS_WITH_NOT_ENOUGH: { | |
actions: [ | |
assign({ | |
actionableAttestations: (context) => new Array(context.numAttestationsRemaining - 1).fill('a'), | |
revealedAttestations: (context) => new Array(context.numAttestationsRemaining - 1).fill('a'), | |
}), | |
resetRetriesAction, | |
], | |
}, | |
SUCCESS_WITH_ENOUGH: { | |
actions: [ | |
assign({ | |
actionableAttestations: (context) => new Array(context.numAttestationsRemaining).fill('a'), | |
}), | |
resetRetriesAction, | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: 'loading', | |
actions: assign({ | |
retries: (context, event) => context.retries + 1, | |
}), | |
cond: { | |
type: 'shouldRetry', | |
maxRetries: 3, | |
}, | |
}, | |
{ | |
target: 'error', | |
}, | |
], | |
}, | |
}, | |
error: { | |
type: 'final', | |
}, | |
}, | |
} | |
const readyToStartState = { | |
initial: 'idle', | |
states: { | |
idle: { | |
on: { | |
START: [ | |
{ | |
target: '#main.requestingAttestations', | |
cond: 'doWeNeedMoreAttestations' | |
}, | |
{ | |
target: '#main.revealingAttestations', | |
cond: 'weHaveEnoughAttestations' | |
}], | |
} | |
}, | |
}, | |
} | |
const requestingAttestationsState = { | |
initial: 'requesting', | |
on: { | |
'':{ | |
target: '#main.revealingAttestations', | |
cond: 'weHaveEnoughAttestations' | |
} | |
}, | |
states: { | |
requesting: { | |
on: { | |
SUCCESS: { | |
target: 'requesting', | |
actions: [ | |
assign({ | |
actionableAttestations: (context) => [...context.actionableAttestations, 'a'], | |
}), | |
resetRetriesAction, | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: 'requesting', | |
actions: assign({ | |
retries: (context, event) => context.retries + 1, | |
}), | |
cond: { | |
type: 'shouldRetry', | |
maxRetries: 3, | |
}, | |
}, | |
{ | |
target: 'error', | |
}, | |
], | |
}, | |
}, | |
error: { | |
type: 'final', | |
}, | |
}, | |
} | |
const revealingAttestationsState = { | |
initial: 'revealing', | |
on: { | |
'':{ | |
target: '#main.completingAttestations', | |
cond: 'weHaveEnoughRevealed' | |
} | |
}, | |
states: { | |
revealing: { | |
on: { | |
SUCCESS: { | |
target: 'revealing', | |
actions: [ | |
assign({ | |
revealedAttestations: (context) => [...context.revealedAttestations, 'a'], | |
}), | |
resetRetriesAction, | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: 'revealing', | |
actions: assign({ | |
retries: (context, event) => context.retries + 1, | |
}), | |
cond: { | |
type: 'shouldRetry', | |
maxRetries: 3, | |
}, | |
}, | |
{ | |
target: '#main.requestingAttestations', | |
cond: 'doWeNeedMoreAttestations' | |
}, | |
{ | |
target: '#main.revealingAttestations', | |
cond: 'weHaveEnoughRevealed' | |
}, | |
], | |
}, | |
}, | |
}, | |
} | |
const completingState = { | |
initial: 'awaiting', | |
on: { | |
'': { | |
target: '#main.verified', | |
cond: 'isVerified' | |
}, | |
RESEND_MESSAGES: { | |
target: 'revealingAttestations', | |
actions: [ | |
assign({ | |
revealedAttestations: (context) => [], | |
}), | |
], | |
} | |
}, | |
states: { | |
awaiting: { | |
on: { | |
USER_INPUT:'submitting' | |
} | |
}, | |
submitting: { | |
on: { | |
SUCCESS: { | |
target: 'awaiting', | |
actions: [ | |
assign({ | |
completed: (context, event) => context.completed + 1, | |
numAttestationsRemaining: (context, event) => context.numAttestationsRemaining - 1, | |
actionableAttestations: (context) => context.actionableAttestations.slice(1), | |
revealedAttestations: (context) => context.revealedAttestations.slice(1), | |
}), | |
resetRetriesAction | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: 'submitting', | |
actions: assign({ | |
retries: (context, event) => context.retries + 1, | |
}), | |
cond: { | |
type: 'shouldRetry', | |
maxRetries: 3, | |
}, | |
}, | |
{ | |
target: '#main.requestingAttestations', | |
cond: 'weHaveEnoughRevealed', | |
actions: [ | |
assign({ | |
actionableAttestations: (context) => context.actionableAttestations.slice(1), | |
revealedAttestations: (context) => context.revealedAttestations.slice(1), | |
}), | |
resetRetriesAction | |
], | |
}, | |
// { | |
// target: 'awaiting', | |
// actions: resetRetriesAction, | |
// }, | |
], | |
}, | |
}, | |
}, | |
} | |
const mtwState = { | |
initial: 'fetchingOrDeploing', | |
on: { | |
'': { | |
target: '#main.fetchingAccountOnChain', | |
cond: 'mtwReady' | |
} | |
}, | |
states: { | |
fetchingOrDeploing: { | |
on: { | |
SUCCESS: { | |
target: 'dekAndWalletRegistration', | |
}, | |
FAILURE: [ | |
{ | |
target: '#main.idle', | |
actions: assign({ | |
isKomenciEnabled: (context, event) => false, | |
}), | |
}, | |
], | |
}, | |
}, | |
dekAndWalletRegistration: { | |
on: { | |
SUCCESS: { | |
actions: [ | |
assign({ | |
mtw: (context) => 'address', | |
}), | |
], | |
}, | |
FAILURE: [ | |
{ | |
target: '#main.idle', | |
actions: assign({ | |
isKomenciEnabled: (context, event) => false, | |
}), | |
}, | |
], | |
}, | |
}, | |
} | |
} | |
const mainMachine = Machine( | |
{ | |
id: 'main', | |
key: 'main', | |
initial: 'idle', | |
context: { | |
isKomenciEnabled: true, | |
account: null, | |
pepper: null, | |
phoneHash: null, | |
numAttestationsRemaining: null, | |
completed: null, | |
actionableAttestations: null, | |
revealedAttestations: null, | |
activeKomenciSession: false, | |
isHuman: false, | |
mtw: null, | |
retries: 0, | |
}, | |
states: { | |
idle: { | |
on: { | |
'': { | |
target: 'preparingKomenci', | |
cond: 'komenciEnabled' | |
}, | |
BALANCE_SUFFICIENT: { | |
target: '#main.phoneNumberDetails', | |
cond: 'komenciDisabled' | |
}, | |
BALANCE_INSUFFICIENT: { | |
target: '#main.verificationImpossible', | |
cond: 'komenciDisabled' | |
} | |
}, | |
}, | |
preparingKomenci: { | |
...preparingKomenciState | |
}, | |
checkingIsHuman: { | |
...checkingIsHumanState | |
}, | |
startingKomenciSession: { | |
...startingKomenciSessionState | |
}, | |
phoneNumberDetails: { | |
...phoneNumberDetailsState, | |
}, | |
mtw: { | |
...mtwState | |
}, | |
fetchingAccountOnChain: { | |
...onChainState, | |
}, | |
actionableAttestations: { | |
...actionableAttestationsState, | |
}, | |
readyToStart: { | |
...readyToStartState, | |
}, | |
requestingAttestations: { | |
...requestingAttestationsState, | |
}, | |
revealingAttestations: { | |
...revealingAttestationsState, | |
}, | |
completingAttestations: { | |
...completingState, | |
}, | |
verified: { | |
type: 'final', | |
}, | |
verificationImpossible: { | |
type: 'final', | |
}, | |
}, | |
}, | |
{ | |
guards: { | |
shouldRetry, | |
doWeNeedMoreAttestations, | |
weHaveEnoughAttestations, | |
isVerified, | |
weHaveEnoughRevealed, | |
komenciReady, | |
komenciNotReady, | |
komenciEnabled, | |
komenciDisabled, | |
notVerified, | |
mtwReady, | |
phoneNumberFetchedWithKomenci, | |
phoneNumberFetchedWithoutKomenci | |
}, | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment