@metamask/ramps-controller 20.2.0 → 20.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -1
- package/dist/NeoBankService-method-action-types.cjs +7 -0
- package/dist/NeoBankService-method-action-types.cjs.map +1 -0
- package/dist/NeoBankService-method-action-types.d.cts +126 -0
- package/dist/NeoBankService-method-action-types.d.cts.map +1 -0
- package/dist/NeoBankService-method-action-types.d.mts +126 -0
- package/dist/NeoBankService-method-action-types.d.mts.map +1 -0
- package/dist/NeoBankService-method-action-types.mjs +6 -0
- package/dist/NeoBankService-method-action-types.mjs.map +1 -0
- package/dist/NeoBankService.cjs +387 -0
- package/dist/NeoBankService.cjs.map +1 -0
- package/dist/NeoBankService.d.cts +191 -0
- package/dist/NeoBankService.d.cts.map +1 -0
- package/dist/NeoBankService.d.mts +191 -0
- package/dist/NeoBankService.d.mts.map +1 -0
- package/dist/NeoBankService.mjs +379 -0
- package/dist/NeoBankService.mjs.map +1 -0
- package/dist/RampsController-method-action-types.cjs.map +1 -1
- package/dist/RampsController-method-action-types.d.cts +91 -1
- package/dist/RampsController-method-action-types.d.cts.map +1 -1
- package/dist/RampsController-method-action-types.d.mts +91 -1
- package/dist/RampsController-method-action-types.d.mts.map +1 -1
- package/dist/RampsController-method-action-types.mjs.map +1 -1
- package/dist/RampsController.cjs +372 -2
- package/dist/RampsController.cjs.map +1 -1
- package/dist/RampsController.d.cts +152 -5
- package/dist/RampsController.d.cts.map +1 -1
- package/dist/RampsController.d.mts +152 -5
- package/dist/RampsController.d.mts.map +1 -1
- package/dist/RampsController.mjs +371 -1
- package/dist/RampsController.mjs.map +1 -1
- package/dist/autoramp-types.cjs +3 -0
- package/dist/autoramp-types.cjs.map +1 -0
- package/dist/autoramp-types.d.cts +22 -0
- package/dist/autoramp-types.d.cts.map +1 -0
- package/dist/autoramp-types.d.mts +22 -0
- package/dist/autoramp-types.d.mts.map +1 -0
- package/dist/autoramp-types.mjs +2 -0
- package/dist/autoramp-types.mjs.map +1 -0
- package/dist/autorampAccount.cjs +155 -0
- package/dist/autorampAccount.cjs.map +1 -0
- package/dist/autorampAccount.d.cts +126 -0
- package/dist/autorampAccount.d.cts.map +1 -0
- package/dist/autorampAccount.d.mts +126 -0
- package/dist/autorampAccount.d.mts.map +1 -0
- package/dist/autorampAccount.mjs +147 -0
- package/dist/autorampAccount.mjs.map +1 -0
- package/dist/index.cjs +20 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +12 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/ownership-message.cjs +26 -0
- package/dist/ownership-message.cjs.map +1 -0
- package/dist/ownership-message.d.cts +22 -0
- package/dist/ownership-message.d.cts.map +1 -0
- package/dist/ownership-message.d.mts +22 -0
- package/dist/ownership-message.d.mts.map +1 -0
- package/dist/ownership-message.mjs +22 -0
- package/dist/ownership-message.mjs.map +1 -0
- package/dist/wallet-registration-machine.cjs +144 -0
- package/dist/wallet-registration-machine.cjs.map +1 -0
- package/dist/wallet-registration-machine.d.cts +81 -0
- package/dist/wallet-registration-machine.d.cts.map +1 -0
- package/dist/wallet-registration-machine.d.mts +81 -0
- package/dist/wallet-registration-machine.d.mts.map +1 -0
- package/dist/wallet-registration-machine.mjs +139 -0
- package/dist/wallet-registration-machine.mjs.map +1 -0
- package/dist/wallet-registration-service.cjs +351 -0
- package/dist/wallet-registration-service.cjs.map +1 -0
- package/dist/wallet-registration-service.d.cts +144 -0
- package/dist/wallet-registration-service.d.cts.map +1 -0
- package/dist/wallet-registration-service.d.mts +144 -0
- package/dist/wallet-registration-service.d.mts.map +1 -0
- package/dist/wallet-registration-service.mjs +344 -0
- package/dist/wallet-registration-service.mjs.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, hand-rolled finite state machine for the MoonPay Iron self-hosted
|
|
3
|
+
* wallet registration signing step. It follows the FSM convention used
|
|
4
|
+
* elsewhere in `core` (no XState dependency): a single pure `transition`
|
|
5
|
+
* reducer plus a data-driven transition table.
|
|
6
|
+
*
|
|
7
|
+
* Side effects (server lookups, signing, POSTing) live in the interpreter that
|
|
8
|
+
* drives this machine; every effect result is fed back in as an event, so the
|
|
9
|
+
* machine itself stays deterministic and trivially testable.
|
|
10
|
+
*/
|
|
11
|
+
/** Every state in the signing step. */
|
|
12
|
+
export type WalletRegistrationStatus = 'idle' | 'preparing' | 'awaitingUnlock' | 'signing' | 'submitting' | 'disambiguate409' | 'checkThenRetry' | 'lookupUnavailable' | 'registered' | 'alreadyRegistered' | 'registeredDisabled' | 'failedRetryable' | 'failedTerminal' | 'cancelled';
|
|
13
|
+
/** Machine context carried across transitions. */
|
|
14
|
+
export type WalletRegistrationContext = {
|
|
15
|
+
/** Number of sign attempts made so far (used for the retry ceiling). */
|
|
16
|
+
attempts: number;
|
|
17
|
+
/** Maximum number of sign attempts before a retryable failure is surfaced. */
|
|
18
|
+
maxAttempts: number;
|
|
19
|
+
};
|
|
20
|
+
export type WalletRegistrationState = {
|
|
21
|
+
status: WalletRegistrationStatus;
|
|
22
|
+
context: WalletRegistrationContext;
|
|
23
|
+
};
|
|
24
|
+
/** Events the interpreter dispatches into the machine. */
|
|
25
|
+
export type WalletRegistrationEvent = {
|
|
26
|
+
type: 'START';
|
|
27
|
+
} | {
|
|
28
|
+
type: 'WALLET_LOCKED';
|
|
29
|
+
} | {
|
|
30
|
+
type: 'WALLET_UNLOCKED';
|
|
31
|
+
} | {
|
|
32
|
+
type: 'LOOKUP_ACTIVE';
|
|
33
|
+
} | {
|
|
34
|
+
type: 'LOOKUP_DISABLED';
|
|
35
|
+
} | {
|
|
36
|
+
type: 'LOOKUP_ABSENT';
|
|
37
|
+
} | {
|
|
38
|
+
type: 'LOOKUP_FAILED';
|
|
39
|
+
} | {
|
|
40
|
+
type: 'SIGN_OK';
|
|
41
|
+
} | {
|
|
42
|
+
type: 'SIGN_REJECTED';
|
|
43
|
+
} | {
|
|
44
|
+
type: 'SIGN_FAILED';
|
|
45
|
+
retryable: boolean;
|
|
46
|
+
} | {
|
|
47
|
+
type: 'SUBMIT_OK';
|
|
48
|
+
} | {
|
|
49
|
+
type: 'SUBMIT_CONFLICT';
|
|
50
|
+
} | {
|
|
51
|
+
type: 'SUBMIT_TRANSIENT';
|
|
52
|
+
} | {
|
|
53
|
+
type: 'SUBMIT_VALIDATION';
|
|
54
|
+
utcRollover: boolean;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'SUBMIT_TERMINAL';
|
|
57
|
+
} | {
|
|
58
|
+
type: 'SUBMIT_RATE_LIMITED';
|
|
59
|
+
} | {
|
|
60
|
+
type: 'RETRY';
|
|
61
|
+
} | {
|
|
62
|
+
type: 'CANCEL';
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Creates the initial idle state.
|
|
66
|
+
*
|
|
67
|
+
* @param maxAttempts - Optional retry ceiling for sign attempts.
|
|
68
|
+
* @returns A fresh idle machine state.
|
|
69
|
+
*/
|
|
70
|
+
export declare function createInitialState(maxAttempts?: number): WalletRegistrationState;
|
|
71
|
+
/**
|
|
72
|
+
* Pure transition reducer. Unhandled (state, event) pairs are no-ops, which is
|
|
73
|
+
* how the machine enforces "one in-flight operation" (a second `START` while
|
|
74
|
+
* busy is ignored) and how terminal states stay put.
|
|
75
|
+
*
|
|
76
|
+
* @param state - Current machine state.
|
|
77
|
+
* @param event - Event to apply.
|
|
78
|
+
* @returns The next state (or the same state for unhandled events).
|
|
79
|
+
*/
|
|
80
|
+
export declare function transition(state: WalletRegistrationState, event: WalletRegistrationEvent): WalletRegistrationState;
|
|
81
|
+
//# sourceMappingURL=wallet-registration-machine.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-registration-machine.d.cts","sourceRoot":"","sources":["../src/wallet-registration-machine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,uCAAuC;AACvC,MAAM,MAAM,wBAAwB,GAChC,MAAM,GACN,WAAW,GACX,gBAAgB,GAChB,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,YAAY,GACZ,mBAAmB,GACnB,oBAAoB,GACpB,iBAAiB,GACjB,gBAAgB,GAChB,WAAW,CAAC;AAEhB,kDAAkD;AAClD,MAAM,MAAM,yBAAyB,GAAG;IACtC,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,wBAAwB,CAAC;IACjC,OAAO,EAAE,yBAAyB,CAAC;CACpC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAWvB;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,GAAE,MAA6B,GACzC,uBAAuB,CAEzB;AA4HD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,uBAAuB,EAC9B,KAAK,EAAE,uBAAuB,GAC7B,uBAAuB,CAGzB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, hand-rolled finite state machine for the MoonPay Iron self-hosted
|
|
3
|
+
* wallet registration signing step. It follows the FSM convention used
|
|
4
|
+
* elsewhere in `core` (no XState dependency): a single pure `transition`
|
|
5
|
+
* reducer plus a data-driven transition table.
|
|
6
|
+
*
|
|
7
|
+
* Side effects (server lookups, signing, POSTing) live in the interpreter that
|
|
8
|
+
* drives this machine; every effect result is fed back in as an event, so the
|
|
9
|
+
* machine itself stays deterministic and trivially testable.
|
|
10
|
+
*/
|
|
11
|
+
/** Every state in the signing step. */
|
|
12
|
+
export type WalletRegistrationStatus = 'idle' | 'preparing' | 'awaitingUnlock' | 'signing' | 'submitting' | 'disambiguate409' | 'checkThenRetry' | 'lookupUnavailable' | 'registered' | 'alreadyRegistered' | 'registeredDisabled' | 'failedRetryable' | 'failedTerminal' | 'cancelled';
|
|
13
|
+
/** Machine context carried across transitions. */
|
|
14
|
+
export type WalletRegistrationContext = {
|
|
15
|
+
/** Number of sign attempts made so far (used for the retry ceiling). */
|
|
16
|
+
attempts: number;
|
|
17
|
+
/** Maximum number of sign attempts before a retryable failure is surfaced. */
|
|
18
|
+
maxAttempts: number;
|
|
19
|
+
};
|
|
20
|
+
export type WalletRegistrationState = {
|
|
21
|
+
status: WalletRegistrationStatus;
|
|
22
|
+
context: WalletRegistrationContext;
|
|
23
|
+
};
|
|
24
|
+
/** Events the interpreter dispatches into the machine. */
|
|
25
|
+
export type WalletRegistrationEvent = {
|
|
26
|
+
type: 'START';
|
|
27
|
+
} | {
|
|
28
|
+
type: 'WALLET_LOCKED';
|
|
29
|
+
} | {
|
|
30
|
+
type: 'WALLET_UNLOCKED';
|
|
31
|
+
} | {
|
|
32
|
+
type: 'LOOKUP_ACTIVE';
|
|
33
|
+
} | {
|
|
34
|
+
type: 'LOOKUP_DISABLED';
|
|
35
|
+
} | {
|
|
36
|
+
type: 'LOOKUP_ABSENT';
|
|
37
|
+
} | {
|
|
38
|
+
type: 'LOOKUP_FAILED';
|
|
39
|
+
} | {
|
|
40
|
+
type: 'SIGN_OK';
|
|
41
|
+
} | {
|
|
42
|
+
type: 'SIGN_REJECTED';
|
|
43
|
+
} | {
|
|
44
|
+
type: 'SIGN_FAILED';
|
|
45
|
+
retryable: boolean;
|
|
46
|
+
} | {
|
|
47
|
+
type: 'SUBMIT_OK';
|
|
48
|
+
} | {
|
|
49
|
+
type: 'SUBMIT_CONFLICT';
|
|
50
|
+
} | {
|
|
51
|
+
type: 'SUBMIT_TRANSIENT';
|
|
52
|
+
} | {
|
|
53
|
+
type: 'SUBMIT_VALIDATION';
|
|
54
|
+
utcRollover: boolean;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'SUBMIT_TERMINAL';
|
|
57
|
+
} | {
|
|
58
|
+
type: 'SUBMIT_RATE_LIMITED';
|
|
59
|
+
} | {
|
|
60
|
+
type: 'RETRY';
|
|
61
|
+
} | {
|
|
62
|
+
type: 'CANCEL';
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Creates the initial idle state.
|
|
66
|
+
*
|
|
67
|
+
* @param maxAttempts - Optional retry ceiling for sign attempts.
|
|
68
|
+
* @returns A fresh idle machine state.
|
|
69
|
+
*/
|
|
70
|
+
export declare function createInitialState(maxAttempts?: number): WalletRegistrationState;
|
|
71
|
+
/**
|
|
72
|
+
* Pure transition reducer. Unhandled (state, event) pairs are no-ops, which is
|
|
73
|
+
* how the machine enforces "one in-flight operation" (a second `START` while
|
|
74
|
+
* busy is ignored) and how terminal states stay put.
|
|
75
|
+
*
|
|
76
|
+
* @param state - Current machine state.
|
|
77
|
+
* @param event - Event to apply.
|
|
78
|
+
* @returns The next state (or the same state for unhandled events).
|
|
79
|
+
*/
|
|
80
|
+
export declare function transition(state: WalletRegistrationState, event: WalletRegistrationEvent): WalletRegistrationState;
|
|
81
|
+
//# sourceMappingURL=wallet-registration-machine.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-registration-machine.d.mts","sourceRoot":"","sources":["../src/wallet-registration-machine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,uCAAuC;AACvC,MAAM,MAAM,wBAAwB,GAChC,MAAM,GACN,WAAW,GACX,gBAAgB,GAChB,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,YAAY,GACZ,mBAAmB,GACnB,oBAAoB,GACpB,iBAAiB,GACjB,gBAAgB,GAChB,WAAW,CAAC;AAEhB,kDAAkD;AAClD,MAAM,MAAM,yBAAyB,GAAG;IACtC,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,wBAAwB,CAAC;IACjC,OAAO,EAAE,yBAAyB,CAAC;CACpC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAWvB;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,GAAE,MAA6B,GACzC,uBAAuB,CAEzB;AA4HD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,uBAAuB,EAC9B,KAAK,EAAE,uBAAuB,GAC7B,uBAAuB,CAGzB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, hand-rolled finite state machine for the MoonPay Iron self-hosted
|
|
3
|
+
* wallet registration signing step. It follows the FSM convention used
|
|
4
|
+
* elsewhere in `core` (no XState dependency): a single pure `transition`
|
|
5
|
+
* reducer plus a data-driven transition table.
|
|
6
|
+
*
|
|
7
|
+
* Side effects (server lookups, signing, POSTing) live in the interpreter that
|
|
8
|
+
* drives this machine; every effect result is fed back in as an event, so the
|
|
9
|
+
* machine itself stays deterministic and trivially testable.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_MAX_ATTEMPTS = 3;
|
|
12
|
+
/**
|
|
13
|
+
* Creates the initial idle state.
|
|
14
|
+
*
|
|
15
|
+
* @param maxAttempts - Optional retry ceiling for sign attempts.
|
|
16
|
+
* @returns A fresh idle machine state.
|
|
17
|
+
*/
|
|
18
|
+
export function createInitialState(maxAttempts = DEFAULT_MAX_ATTEMPTS) {
|
|
19
|
+
return { status: 'idle', context: { attempts: 0, maxAttempts } };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Builds a handler that moves to a status while preserving context.
|
|
23
|
+
*
|
|
24
|
+
* @param status - Target status.
|
|
25
|
+
* @returns A handler transitioning to `status`.
|
|
26
|
+
*/
|
|
27
|
+
function keep(status) {
|
|
28
|
+
return (state) => ({ status, context: state.context });
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds a handler that moves to a status and resets the retry context. Used
|
|
32
|
+
* when the user (or app resume) starts a fresh attempt from scratch.
|
|
33
|
+
*
|
|
34
|
+
* @param status - Target status.
|
|
35
|
+
* @returns A handler transitioning to `status` with reset context.
|
|
36
|
+
*/
|
|
37
|
+
function reset(status) {
|
|
38
|
+
return (state) => ({
|
|
39
|
+
status,
|
|
40
|
+
context: { ...state.context, attempts: 0 },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Moves to `signing` and counts this as a new sign attempt.
|
|
45
|
+
*
|
|
46
|
+
* @param state - Current state.
|
|
47
|
+
* @returns The `signing` state with an incremented attempt count.
|
|
48
|
+
*/
|
|
49
|
+
const toSigning = (state) => ({
|
|
50
|
+
status: 'signing',
|
|
51
|
+
context: { ...state.context, attempts: state.context.attempts + 1 },
|
|
52
|
+
});
|
|
53
|
+
const toPreparing = reset('preparing');
|
|
54
|
+
const toAlreadyRegistered = keep('alreadyRegistered');
|
|
55
|
+
const toRegisteredDisabled = keep('registeredDisabled');
|
|
56
|
+
const toLookupUnavailable = keep('lookupUnavailable');
|
|
57
|
+
const toCancelled = keep('cancelled');
|
|
58
|
+
const signFailed = (state, event) => {
|
|
59
|
+
const { retryable } = event;
|
|
60
|
+
return retryable
|
|
61
|
+
? keep('failedRetryable')(state, event)
|
|
62
|
+
: keep('failedTerminal')(state, event);
|
|
63
|
+
};
|
|
64
|
+
const submitValidation = (state, event) => {
|
|
65
|
+
const { utcRollover } = event;
|
|
66
|
+
return utcRollover && state.context.attempts < state.context.maxAttempts
|
|
67
|
+
? toSigning(state, event)
|
|
68
|
+
: keep('failedTerminal')(state, event);
|
|
69
|
+
};
|
|
70
|
+
const checkThenRetryAbsent = (state, event) => state.context.attempts < state.context.maxAttempts
|
|
71
|
+
? toSigning(state, event)
|
|
72
|
+
: keep('failedRetryable')(state, event);
|
|
73
|
+
const TABLE = {
|
|
74
|
+
idle: {
|
|
75
|
+
START: toPreparing,
|
|
76
|
+
},
|
|
77
|
+
preparing: {
|
|
78
|
+
LOOKUP_ACTIVE: toAlreadyRegistered,
|
|
79
|
+
LOOKUP_DISABLED: toRegisteredDisabled,
|
|
80
|
+
LOOKUP_ABSENT: toSigning,
|
|
81
|
+
LOOKUP_FAILED: toLookupUnavailable,
|
|
82
|
+
},
|
|
83
|
+
awaitingUnlock: {
|
|
84
|
+
WALLET_UNLOCKED: keep('signing'),
|
|
85
|
+
},
|
|
86
|
+
signing: {
|
|
87
|
+
SIGN_OK: keep('submitting'),
|
|
88
|
+
SIGN_REJECTED: toCancelled,
|
|
89
|
+
SIGN_FAILED: signFailed,
|
|
90
|
+
WALLET_LOCKED: keep('awaitingUnlock'),
|
|
91
|
+
CANCEL: toCancelled,
|
|
92
|
+
},
|
|
93
|
+
submitting: {
|
|
94
|
+
SUBMIT_OK: keep('registered'),
|
|
95
|
+
SUBMIT_CONFLICT: keep('disambiguate409'),
|
|
96
|
+
SUBMIT_TRANSIENT: keep('checkThenRetry'),
|
|
97
|
+
SUBMIT_VALIDATION: submitValidation,
|
|
98
|
+
SUBMIT_TERMINAL: keep('failedTerminal'),
|
|
99
|
+
SUBMIT_RATE_LIMITED: keep('failedRetryable'),
|
|
100
|
+
CANCEL: toCancelled,
|
|
101
|
+
},
|
|
102
|
+
disambiguate409: {
|
|
103
|
+
LOOKUP_ACTIVE: toAlreadyRegistered,
|
|
104
|
+
LOOKUP_DISABLED: toRegisteredDisabled,
|
|
105
|
+
LOOKUP_ABSENT: keep('failedRetryable'),
|
|
106
|
+
LOOKUP_FAILED: toLookupUnavailable,
|
|
107
|
+
CANCEL: toCancelled,
|
|
108
|
+
},
|
|
109
|
+
checkThenRetry: {
|
|
110
|
+
LOOKUP_ACTIVE: toAlreadyRegistered,
|
|
111
|
+
LOOKUP_DISABLED: toRegisteredDisabled,
|
|
112
|
+
LOOKUP_ABSENT: checkThenRetryAbsent,
|
|
113
|
+
LOOKUP_FAILED: toLookupUnavailable,
|
|
114
|
+
CANCEL: toCancelled,
|
|
115
|
+
},
|
|
116
|
+
failedRetryable: {
|
|
117
|
+
RETRY: toPreparing,
|
|
118
|
+
},
|
|
119
|
+
lookupUnavailable: {
|
|
120
|
+
RETRY: toPreparing,
|
|
121
|
+
},
|
|
122
|
+
cancelled: {
|
|
123
|
+
RETRY: toPreparing,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Pure transition reducer. Unhandled (state, event) pairs are no-ops, which is
|
|
128
|
+
* how the machine enforces "one in-flight operation" (a second `START` while
|
|
129
|
+
* busy is ignored) and how terminal states stay put.
|
|
130
|
+
*
|
|
131
|
+
* @param state - Current machine state.
|
|
132
|
+
* @param event - Event to apply.
|
|
133
|
+
* @returns The next state (or the same state for unhandled events).
|
|
134
|
+
*/
|
|
135
|
+
export function transition(state, event) {
|
|
136
|
+
const handler = TABLE[state.status]?.[event.type];
|
|
137
|
+
return handler ? handler(state, event) : state;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=wallet-registration-machine.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-registration-machine.mjs","sourceRoot":"","sources":["../src/wallet-registration-machine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, hand-rolled finite state machine for the MoonPay Iron self-hosted\n * wallet registration signing step. It follows the FSM convention used\n * elsewhere in `core` (no XState dependency): a single pure `transition`\n * reducer plus a data-driven transition table.\n *\n * Side effects (server lookups, signing, POSTing) live in the interpreter that\n * drives this machine; every effect result is fed back in as an event, so the\n * machine itself stays deterministic and trivially testable.\n */\n\n/** Every state in the signing step. */\nexport type WalletRegistrationStatus =\n | 'idle'\n | 'preparing'\n | 'awaitingUnlock'\n | 'signing'\n | 'submitting'\n | 'disambiguate409'\n | 'checkThenRetry'\n | 'lookupUnavailable'\n | 'registered'\n | 'alreadyRegistered'\n | 'registeredDisabled'\n | 'failedRetryable'\n | 'failedTerminal'\n | 'cancelled';\n\n/** Machine context carried across transitions. */\nexport type WalletRegistrationContext = {\n /** Number of sign attempts made so far (used for the retry ceiling). */\n attempts: number;\n /** Maximum number of sign attempts before a retryable failure is surfaced. */\n maxAttempts: number;\n};\n\nexport type WalletRegistrationState = {\n status: WalletRegistrationStatus;\n context: WalletRegistrationContext;\n};\n\n/** Events the interpreter dispatches into the machine. */\nexport type WalletRegistrationEvent =\n | { type: 'START' }\n | { type: 'WALLET_LOCKED' }\n | { type: 'WALLET_UNLOCKED' }\n | { type: 'LOOKUP_ACTIVE' }\n | { type: 'LOOKUP_DISABLED' }\n | { type: 'LOOKUP_ABSENT' }\n | { type: 'LOOKUP_FAILED' }\n | { type: 'SIGN_OK' }\n | { type: 'SIGN_REJECTED' }\n | { type: 'SIGN_FAILED'; retryable: boolean }\n | { type: 'SUBMIT_OK' }\n | { type: 'SUBMIT_CONFLICT' }\n | { type: 'SUBMIT_TRANSIENT' }\n | { type: 'SUBMIT_VALIDATION'; utcRollover: boolean }\n | { type: 'SUBMIT_TERMINAL' }\n | { type: 'SUBMIT_RATE_LIMITED' }\n | { type: 'RETRY' }\n | { type: 'CANCEL' };\n\ntype EventType = WalletRegistrationEvent['type'];\n\ntype Handler = (\n state: WalletRegistrationState,\n event: WalletRegistrationEvent,\n) => WalletRegistrationState;\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\n\n/**\n * Creates the initial idle state.\n *\n * @param maxAttempts - Optional retry ceiling for sign attempts.\n * @returns A fresh idle machine state.\n */\nexport function createInitialState(\n maxAttempts: number = DEFAULT_MAX_ATTEMPTS,\n): WalletRegistrationState {\n return { status: 'idle', context: { attempts: 0, maxAttempts } };\n}\n\n/**\n * Builds a handler that moves to a status while preserving context.\n *\n * @param status - Target status.\n * @returns A handler transitioning to `status`.\n */\nfunction keep(status: WalletRegistrationStatus): Handler {\n return (state) => ({ status, context: state.context });\n}\n\n/**\n * Builds a handler that moves to a status and resets the retry context. Used\n * when the user (or app resume) starts a fresh attempt from scratch.\n *\n * @param status - Target status.\n * @returns A handler transitioning to `status` with reset context.\n */\nfunction reset(status: WalletRegistrationStatus): Handler {\n return (state) => ({\n status,\n context: { ...state.context, attempts: 0 },\n });\n}\n\n/**\n * Moves to `signing` and counts this as a new sign attempt.\n *\n * @param state - Current state.\n * @returns The `signing` state with an incremented attempt count.\n */\nconst toSigning: Handler = (state) => ({\n status: 'signing',\n context: { ...state.context, attempts: state.context.attempts + 1 },\n});\n\nconst toPreparing = reset('preparing');\nconst toAlreadyRegistered = keep('alreadyRegistered');\nconst toRegisteredDisabled = keep('registeredDisabled');\nconst toLookupUnavailable = keep('lookupUnavailable');\nconst toCancelled = keep('cancelled');\n\nconst signFailed: Handler = (state, event) => {\n const { retryable } = event as Extract<\n WalletRegistrationEvent,\n { type: 'SIGN_FAILED' }\n >;\n return retryable\n ? keep('failedRetryable')(state, event)\n : keep('failedTerminal')(state, event);\n};\n\nconst submitValidation: Handler = (state, event) => {\n const { utcRollover } = event as Extract<\n WalletRegistrationEvent,\n { type: 'SUBMIT_VALIDATION' }\n >;\n return utcRollover && state.context.attempts < state.context.maxAttempts\n ? toSigning(state, event)\n : keep('failedTerminal')(state, event);\n};\n\nconst checkThenRetryAbsent: Handler = (state, event) =>\n state.context.attempts < state.context.maxAttempts\n ? toSigning(state, event)\n : keep('failedRetryable')(state, event);\n\nconst TABLE: Partial<\n Record<WalletRegistrationStatus, Partial<Record<EventType, Handler>>>\n> = {\n idle: {\n START: toPreparing,\n },\n preparing: {\n LOOKUP_ACTIVE: toAlreadyRegistered,\n LOOKUP_DISABLED: toRegisteredDisabled,\n LOOKUP_ABSENT: toSigning,\n LOOKUP_FAILED: toLookupUnavailable,\n },\n awaitingUnlock: {\n WALLET_UNLOCKED: keep('signing'),\n },\n signing: {\n SIGN_OK: keep('submitting'),\n SIGN_REJECTED: toCancelled,\n SIGN_FAILED: signFailed,\n WALLET_LOCKED: keep('awaitingUnlock'),\n CANCEL: toCancelled,\n },\n submitting: {\n SUBMIT_OK: keep('registered'),\n SUBMIT_CONFLICT: keep('disambiguate409'),\n SUBMIT_TRANSIENT: keep('checkThenRetry'),\n SUBMIT_VALIDATION: submitValidation,\n SUBMIT_TERMINAL: keep('failedTerminal'),\n SUBMIT_RATE_LIMITED: keep('failedRetryable'),\n CANCEL: toCancelled,\n },\n disambiguate409: {\n LOOKUP_ACTIVE: toAlreadyRegistered,\n LOOKUP_DISABLED: toRegisteredDisabled,\n LOOKUP_ABSENT: keep('failedRetryable'),\n LOOKUP_FAILED: toLookupUnavailable,\n CANCEL: toCancelled,\n },\n checkThenRetry: {\n LOOKUP_ACTIVE: toAlreadyRegistered,\n LOOKUP_DISABLED: toRegisteredDisabled,\n LOOKUP_ABSENT: checkThenRetryAbsent,\n LOOKUP_FAILED: toLookupUnavailable,\n CANCEL: toCancelled,\n },\n failedRetryable: {\n RETRY: toPreparing,\n },\n lookupUnavailable: {\n RETRY: toPreparing,\n },\n cancelled: {\n RETRY: toPreparing,\n },\n};\n\n/**\n * Pure transition reducer. Unhandled (state, event) pairs are no-ops, which is\n * how the machine enforces \"one in-flight operation\" (a second `START` while\n * busy is ignored) and how terminal states stay put.\n *\n * @param state - Current machine state.\n * @param event - Event to apply.\n * @returns The next state (or the same state for unhandled events).\n */\nexport function transition(\n state: WalletRegistrationState,\n event: WalletRegistrationEvent,\n): WalletRegistrationState {\n const handler = TABLE[state.status]?.[event.type];\n return handler ? handler(state, event) : state;\n}\n"]}
|