Skip to content

Commit

Permalink
Enoki SDK improvements (MystenLabs#15050)
Browse files Browse the repository at this point in the history
## Description 

Some minor updates to the Enoki SDK that are needed after attempting to
integrate into the zkSend codebase:
- The session is currently not observable, which means there's no way to
get the users' JWT consistently in React. `getSession` _mostly_ works
but there is a timing issue if you call it before the `authCallback` has
processed. I updated this state to be observable (the API here is not
really ideal, but we kind of know that _all_ of theses APIs are weird
and will need to be rethought once we have more usage).
- `useAuthCallback` didn't expose the returned state parameter, which is
often used to track auth redirects. The hook now returns the state
parameter so that this functionality can be implemented.

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
Jordan-Mysten authored Nov 27, 2023
1 parent 5e8b5c2 commit 732fdbb
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-humans-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mysten/enoki': patch
---

Make enoki flow session observable. Expose state parameter on useAuthCallback.
24 changes: 10 additions & 14 deletions sdk/enoki/src/EnokiFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ export class EnokiFlow {
#encryptionKey: string;
#store: SyncStore;

#zkLoginSessionInitialized: boolean;
#zkLoginSession: ZkLoginSession | null;

$zkLoginSession: WritableAtom<{ initialized: boolean; value: ZkLoginSession | null }>;
$zkLoginState: WritableAtom<ZkLoginState>;

constructor(config: EnokiFlowConfig) {
Expand All @@ -89,9 +87,7 @@ export class EnokiFlow {
}

this.$zkLoginState = atom(storedState || {});

this.#zkLoginSessionInitialized = false;
this.#zkLoginSession = null;
this.$zkLoginSession = atom({ initialized: false, value: null });

onSet(this.$zkLoginState, ({ newValue }) => {
this.#store.set(this.#storageKeys.STATE, JSON.stringify(newValue));
Expand Down Expand Up @@ -215,12 +211,12 @@ export class EnokiFlow {
this.#store.delete(this.#storageKeys.SESSION);
}

this.#zkLoginSession = newValue;
this.$zkLoginSession.set({ initialized: true, value: newValue });
}

async getSession() {
if (this.#zkLoginSessionInitialized) {
return this.#zkLoginSession;
if (this.$zkLoginSession.get().initialized) {
return this.$zkLoginSession.get().value;
}

try {
Expand All @@ -236,13 +232,13 @@ export class EnokiFlow {
if (state?.expiresAt && Date.now() > state.expiresAt) {
await this.logout();
} else {
this.#zkLoginSession = state;
this.$zkLoginSession.set({ initialized: true, value: state });
}

return this.#zkLoginSession;
} finally {
this.#zkLoginSessionInitialized = true;
} catch {
this.$zkLoginSession.set({ initialized: true, value: null });
}

return this.$zkLoginSession.get().value;
}

async logout() {
Expand Down
10 changes: 8 additions & 2 deletions sdk/enoki/src/react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ export function useZkLogin() {
return useStore(flow.$zkLoginState);
}

export function useZkLoginSession() {
const flow = useEnokiFlow();
return useStore(flow.$zkLoginSession).value;
}

export function useAuthCallback() {
const flow = useEnokiFlow();
const [state, setState] = useState<string | null>(null);
const [handled, setHandled] = useState(false);
const [hash, setHash] = useState<string | null>(null);

Expand All @@ -50,7 +56,7 @@ export function useAuthCallback() {

(async () => {
try {
await flow.handleAuthCallback(hash);
setState(await flow.handleAuthCallback(hash));

window.location.hash = '';
} finally {
Expand All @@ -59,5 +65,5 @@ export function useAuthCallback() {
})();
}, [hash, flow]);

return handled;
return { handled, state };
}

0 comments on commit 732fdbb

Please sign in to comment.