Skip to content

Instantly share code, notes, and snippets.

@korshunad
Last active April 22, 2021 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save korshunad/2ed4d824bd0de7bef5fef3909d3b9383 to your computer and use it in GitHub Desktop.
Save korshunad/2ed4d824bd0de7bef5fef3909d3b9383 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
TRANSFER_STATES = {
START: 'start',
INITIAL: 'initial',
ELIGIBLE_TO_TRANSFER: 'eligible_to_transfer',
NOT_ELIGIBLE_TO_TRANSFER: 'not_eligible_to_transfer',
REQUIREMENTS: 'requirements',
SHOW_REQUIREMENTS: 'show_requirements',
FETCH_REQUIREMENTS: 'fetch_requirements',
FORM: 'form',
IDLE: 'idle',
ERROR: 'error',
VALIDATING: 'validating',
TRANSFER: 'transfer',
VALIDATING_USERNAME: 'validating_username',
VALIDATING_FLOW_ADDRESS: 'validating_flow_address',
CREATING_TRANSFER: 'creating_transfer',
POLLING_FOR_INVOCATION: 'polling_for_invocation',
SUCCESS: 'success',
BLOCKED: 'blocked'
};
const MESSAGES = {
FORM: {
SUCCESS: 'momentTransferFlow.status.success',
AUTHENTICATING_USER: 'momentTransferFlow.status.authenticating',
MOMENT_TRANSFER_REQUEST: 'momentTransferFlow.status.creatingRequest',
INVOCATION_REQUEST: 'momentTransferFlow.status.gettingInvocation',
},
};
IGNORE_ERRORS_DURATION = 30000;
Machine(
{
id: 'momentTransfer',
initial: 'start',
on: {
UPDATE_FLAGS: {
actions: ['assignFlags'],
},
},
states: {
[TRANSFER_STATES.START]: {
id: 'start',
initial: TRANSFER_STATES.IDLE,
states: {
[TRANSFER_STATES.IDLE]: {
always: [
{
target: '#start.fetch_requirements',
cond: 'isGiftingRequirementsEnabled',
},
{
target: '#start.eligible_to_transfer',
},
],
},
[TRANSFER_STATES.FETCH_REQUIREMENTS]: {
invoke: {
src: 'checkingRequirements',
onDone: [
{
target: '#start.eligible_to_transfer',
cond: 'areAllRequirementsMet',
actions: ['assignRequirements'],
},
{
target: '#start.not_eligible_to_transfer',
actions: ['assignRequirements'],
},
],
onError: '#start.not_eligible_to_transfer',
},
},
[TRANSFER_STATES.ELIGIBLE_TO_TRANSFER]: {
on: {
OPEN_MODAL: [
{
target: '#transfer-form.idle',
},
],
},
},
[TRANSFER_STATES.NOT_ELIGIBLE_TO_TRANSFER]: {
on: {
OPEN_MODAL: [
{
target: '#requirements',
},
],
},
},
},
},
[TRANSFER_STATES.REQUIREMENTS]: {
id: 'requirements',
initial: TRANSFER_STATES.IDLE,
states: {
[TRANSFER_STATES.IDLE]: {
always: [
{
target: '#requirements.fetch_requirements',
cond: 'isGiftingRequirementsEnabled',
},
{
target: '#transfer-form.idle',
},
],
},
[TRANSFER_STATES.FETCH_REQUIREMENTS]: {
invoke: {
src: 'checkingRequirements',
onDone: [
{
target: '#transfer-form.idle',
cond: 'areAllRequirementsMet',
actions: ['assignRequirements'],
},
{
target: '#requirements.show_requirements',
actions: ['assignRequirements'],
},
],
onError: '#requirements.show_requirements',
},
},
[TRANSFER_STATES.SHOW_REQUIREMENTS]: {
type: 'final',
on: {
CLOSE: '#start.idle',
},
},
},
},
[TRANSFER_STATES.FORM]: {
initial: 'idle',
id: 'transfer-form',
states: {
[TRANSFER_STATES.IDLE]: {
on: {
VALIDATE: '#transfer-form.validating',
CLOSE: '#start.idle',
},
},
[TRANSFER_STATES.ERROR]: {
on: {
RESET_FORM: '#transfer-form.idle',
CLOSE: '#start.idle',
},
exit: 'clearErrorMessage',
},
[TRANSFER_STATES.BLOCKED]: {
on: {
RESET_FORM: '#transfer-form.idle',
CLOSE: '#start.idle',
},
entry: 'setErrorMessage',
exit: 'clearErrorMessage',
},
[TRANSFER_STATES.VALIDATING]: {
initial: 'validating_username',
states: {
[TRANSFER_STATES.VALIDATING_USERNAME]: {
invoke: {
id: 'validatingUsername',
src: 'getUserByNickname',
onDone: 'validating_flow_address',
onError: {
target: '#transfer-form.error',
actions: 'setErrorMessage',
},
},
},
[TRANSFER_STATES.VALIDATING_FLOW_ADDRESS]: {
invoke: {
id: 'validatingFlowAddress',
src: 'validateFlowAddress',
onDone: '#transfer-form.transfer',
onError: {
target: '#transfer-form.error',
actions: 'setErrorMessage',
},
},
meta: {
message: MESSAGES.FORM.AUTHENTICATING_USER,
},
},
},
},
[TRANSFER_STATES.TRANSFER]: {
initial: 'creating_transfer',
states: {
[TRANSFER_STATES.CREATING_TRANSFER]: {
invoke: {
id: 'createTransferRequest',
src: 'createTransferRequest',
onDone: [
{
target: '#transfer-form.blocked',
cond: 'isTransferBlocked',
},
{
target: 'polling_for_invocation',
},
],
onError: {
target: '#transfer-form.error',
actions: 'setErrorMessage',
},
},
meta: {
message: MESSAGES.FORM.MOMENT_TRANSFER_REQUEST,
},
},
[TRANSFER_STATES.POLLING_FOR_INVOCATION]: {
after: {
[IGNORE_ERRORS_DURATION]: {
actions: send('STOP', { to: 'pollForInvocation' }),
},
},
invoke: {
id: 'pollForInvocation',
src: 'pollForInvocationSuccess',
onError: {
target: '#transfer-form.error',
actions: 'setErrorMessage',
},
},
on: {
INVOCATION_POLL_ERROR: {
target: '#transfer-form.error',
actions: 'setErrorMessage',
},
INVOCATION_POLL_SUCCESS: '#transfer-form.success',
},
meta: {
message: MESSAGES.FORM.INVOCATION_REQUEST,
},
},
},
},
[TRANSFER_STATES.SUCCESS]: {
type: 'final',
entry: 'finish',
meta: {
message: MESSAGES.FORM.SUCCESS,
},
},
},
},
},
},
{
guards: {
isTransferBlocked: (context, event) => {
if (!context?.flags?.feature_transferFraudErrors) return false;
// @NOTE: if we don't receive an ID we can assume we're receiving a
// fraud type in the response from the API
return !event.data.ID;
},
areAllRequirementsMet: () => true,
isGiftingRequirementsEnabled: () => true,
},
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment