chore(sdk): enable strict TypeScript and export all public types#213
chore(sdk): enable strict TypeScript and export all public types#213Aboyeji-Isaac wants to merge 5 commits into
Conversation
|
@aboyejiisaiah-commits is attempting to deploy a commit to the miracle656's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@Aboyeji-Isaac Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Miracle656
left a comment
There was a problem hiding this comment.
Thanks for the PR! Before merging there are a few things to address — the current state would publish types that don't match the SDK's actual API.
1. sdk/tsconfig.json isn't actually modified by this PR
The PR body says "Enabled strict: true in sdk/tsconfig.json" but tsconfig.json isn't in the changed files. Checking main directly, strict: true is already set there (it was tightened during the React Native PR #211). So the strict-mode part of issue #179 is already done — no action needed on your side, just remove that claim from the PR description.
2. The 4 new types in sdk/src/types.ts don't match the real hook API
The hook in sdk/src/useInvisibleWallet.ts exposes these (register, signAuthEntry, deploy) as positional-argument functions, not options-object functions. So:
RegisterOptions = { username?: string }—register(username?: string)takes a positional string, not an options object. Importing this type wouldn't help anyone callregister().SignOptions = { signaturePayload: Uint8Array }— same story;signAuthEntry(payload)is positional.SendOptions = { signerSecret, publicKeyBytes }— there is nosendfunction. The closest isdeploy(signerSecret, publicKeyBytes), also positional. Inventing a name that doesn't exist in the SDK will confuse integrators.WalletStateis closer to useful, but the hook returns these properties directly on theInvisibleWalletobject ({ address, isDeployed, isPending, error, register, deploy, ... }), not as a separateWalletStateaggregate.
Because none of these types are referenced inside the SDK, tsc --noEmit of course passes — they're decorative.
3. The actual fix is much simpler
useInvisibleWallet.ts already exports the real public types. Re-exporting these gives integrators exactly what they need:
// sdk/src/index.ts
export type {
WalletConfig,
WalletState, // see below — derive from InvisibleWallet
StorageAdapter,
RegisterResult,
DeployResult,
AddSignerResult,
SignerInfo,
InitiateRecoveryResult,
WebAuthnSignature,
} from './useInvisibleWallet';For WalletState specifically, since the hook returns these on its result object, the cleanest export is a Pick<> of the existing InvisibleWallet type:
import type { useInvisibleWallet } from './useInvisibleWallet';
export type WalletState = Pick<
ReturnType<typeof useInvisibleWallet>,
'address' | 'isDeployed' | 'isPending' | 'error'
>;That way WalletState cannot drift from the hook — it's derived.
Suggested revision
- Delete the invented
RegisterOptions,SignOptions,SendOptionsfromtypes.ts(or remove the file entirely) - In
sdk/src/index.ts, re-export the real types as shown above - Add
WalletStateas a derivedPick<>of the hook's return type - Remove the "Enabled
strict: true" line from the PR description (it's already on) - Verify
npm pack --dry-runshows the new type re-exports indist/index.d.ts
Once that's done, this will fully close #179.
Remove RegisterOptions, SignOptions, and SendOptions — they do not match the hook positional API and would mislead integrators. Replace the hand-written WalletState with a Pick derived from the hook return type so it cannot drift. Clean up index.ts to only re-export value exports from InvisibleWalletCore; all public types flow through useInvisibleWallet exports.
The Vue example app has its own tsconfig and its own devDependencies (vue, vite, @vitejs/plugin-vue). Including src/examples/** in the SDK tsconfig caused tsc --noEmit to fail with module-not-found errors for those packages. Excluding the examples dir keeps the SDK build clean without affecting the example app.
Summary
sdk/src/core/InvisibleWalletCore.tsso both React and Vue adapters share the same coresdk/vue/— a new@veil/invisible-wallet-vuepackage exportinguseInvisibleWalletas a Vue 3 Composition API composable (reactive refs,onMounted/onUnmountedlifecycle,readonlystate)sdk/src/examples/vue/demonstrating register, login, deploy, and sendRegisterOptions,SignOptions,SendOptions) with a derivedWalletStatetype that cannot drift from the hooksrc/examplesfrom the SDK tsconfig sotsc --noEmitpasses cleanly understrict: trueAcceptance criteria — #173
address,isDeployed,isPending,error) via readonly refsexamples/vue/— includesApp.vue,main.ts,tsconfig.json, and.env.examplevueand@stellar/stellar-sdk— no React dependencyAcceptance criteria — #179
tsc --noEmitpasses understrict: trueanyin public APIWalletStateimportable viaimport type { WalletState } from '@veil/invisible-wallet-sdk'Test plan
cd sdk/vue && npm install && npm run build— bundle compiles without errorscd sdk/src/examples/vue && npm install && npm run dev— dev server starts on port 5173Closes #173
Closes #179