Wallet onboarding (SF-088, SF-101)

/get-started guides connection, deployment/network verification, gas funding, registration and recipient-confirmed fleet handover. The header wallet menu still supports installed Wallet Standard extensions. dApp Kit now also registers Slush web (default origin https://my.slush.app, metadata at https://api.slush.app/api/wallet/metadata). An installed Slush extension takes precedence over the web wallet according to the pinned SDK.

Google zkLogin configuration

The provider is Google only. The integration pins @mysten/enoki 1.3.0, with wallet-standard 0.21.34 and webcrypto-signer 0.2.34, compatible with the existing Sui 2.36.0 SDK. It uses the Wallet Standard initializer, Enoki’s hosted salt and proving service at https://api.enoki.mystenlabs.com, and Google OAuth at https://accounts.google.com/o/oauth2/v2/auth. No SuiFleet login server, private Enoki API key, OAuth client secret, custom prover or custom salt service is required. No transaction sponsorship is enabled by this integration.

Provision an Enoki app in the Enoki portal, enable its Google provider and obtain its public API key. Configure a Google web OAuth client with the deployment’s exact allowed origin and redirect URI ending in /get-started. SuiFleet pins that same-origin callback so login from the header on any page returns to the first-run route in the popup. Use a fixed HTTPS deployment origin for real acceptance; allow loopback development explicitly where supported. Enoki origin/network restrictions and Google redirect allowlists must match the chosen deployment. Review third-party service availability, billing/quota and privacy terms before enabling it.

Set these public build-time identifiers in the untracked dapp/.env.local or hosting build environment, then rebuild:

NEXT_PUBLIC_ENOKI_API_KEY=enoki_public_...
NEXT_PUBLIC_GOOGLE_CLIENT_ID=....apps.googleusercontent.com

Never put private keys, OAuth secrets, JWTs, proofs, device keys or recovery phrases in source, issue evidence or logs. The client rejects a private-key-shaped Enoki configuration and leaves Slush/extensions available when public configuration is missing. Google is enabled only on testnet/mainnet; Enoki does not support localnet. Localnet uses an appropriate extension/fixture wallet. Do not represent fixture tests as a real Google login on a local chain.

Sessions and recovery

The pinned Enoki Wallet Standard implementation generates non-extractable P-256 WebCrypto ephemeral keys and stores CryptoKey objects in IndexedDB, rather than serializing private key bytes into local/session storage. Enoki stores encrypted session data in IndexedDB; its public-app-key-based encryption is not a boundary against same-origin JavaScript. JWTs and proofs must remain private. Protect the origin against script injection, avoid untrusted third-party scripts and disconnect on shared devices. This is software browser custody, not hardware key isolation. SuiFleet adds no key or token persistence.

additionalEpochs: 0 limits a nonce to the current epoch. Before every fleet write, SuiFleet checks the Enoki session wall-clock expiry and maxEpoch against a fresh node service-info epoch, after deployment verification. Missing/expired/unverifiable sessions fail before signing and instruct the owner to disconnect and sign in again. Chain verification, account/network race checks and independent transaction effects confirmation apply equally to Google, Slush and extension wallets.

The address depends on the Google account, OAuth audience and Enoki app salt. Keep account recovery and MFA current. Losing the account or access to its salt service can prevent recovery; creating a different app/client/salt can produce a different address. SuiFleet cannot reset ownership. While access remains, use the Fleet handover (/handover) flow described in FLEET_HANDOVER.md to move to an extension wallet or native multisig. The recipient must sign its confirmation before the source executes any transfer; a typed address alone does not establish control. Verify signing and recovery first. Inventory device owner capabilities, group administration and retained native deployment creators together; pause rollouts/admission and follow the documented cutover order. Handover is resumable, not fleet-wide atomic: partial cutovers can prevent existing deployments from applying, and cancellation/expiry does not reverse completed steps. Catalog-bound deployments require replacement. Credentials, provider access, gas coins and other funds require separate cutover. Verify recipient authority and old-owner rejection before retiring the source. Existing contract revocation and old-package isolation protections remain unchanged. Recommend hardware-backed or multisig custody for business fleets before large deposits.

First run and SF-083 extension

SF-101 presents /get-started as four guided steps: sign in, add gas, register a device and deploy a first update. A progress list shows each step's state (done, current, blocked or upcoming) and one concise Next action. States are derived only from verified facts (onboardingProgress in lib/onboarding.ts): connected account, verified gas balance and on-chain inventory. A balance or inventory query failure shows the step as blocked and keeps registration disabled. Registration is reported as inventory only; the first-update step is never marked done and no step claims installation or online health.

The account step shows the wallet account label (or wallet name), a short address and the manifest network. Gas is shown as a readable SUI amount rounded down to four decimals (never rounding a nonzero balance to zero); Technical details discloses the network, full address and exact SUI/MIST balance. A zero balance shows the full funding address and network inline. The registration form always shows the full signing address and network beside the submit button. Essential custody guidance stays visible; longer zkLogin/session/business-custody text and faucet guidance are behind disclosures. Recipient-confirmed fleet handover moved to a collapsed Advanced: move fleet ownership section that keeps every recipient/authority/partial-cutover warning beside the /handover link.

A nonzero gas balance enables registration; it does not promise sufficient gas. The wallet estimates the actual cost. Fund using a same-network SUI transfer or a disposable localnet/testnet faucet.

When the deployment's package has the fleet budget, SF-083 fills the extension point in the gas step of FirstRun.tsx: the up-front estimate with its fees listed separately, optional card funding through a provider's hosted checkout, and the budget deposit. Registration then enrolls the device in the budget, with its own gas account and reserve, and sends its float in the same PTB. Network and account checks stay as above, and the page explains that wallet gas and the fleet budget differ. See FLEET_BUDGET.md. SF-100 address-free naming and bulk enrollment integrate at the marked point in the registration step once its API is merged; this page does not anticipate that API.

Registration uses the existing single PTB to register, issue the device cap and activate custody. Progress shows verification, wallet approval and network confirmation phases. A synchronous in-flight guard and the disabled button prevent duplicate submission; confirmed effects produce a digest, clear the form and refresh inventory, whose device names are listed. Daemon provisioning/online health remains separate. Errors explain gas charges and ambiguous submission: inspect wallet history and refresh inventory before retrying. Do not infer a healthy device from a successful registration.

Below the md breakpoint the application sidebar becomes a horizontally scrolling navigation bar so pages, including onboarding, fit 375 px screens.

Verification and outstanding acceptance

node scripts/test_onboarding.cjs
CHROME_EXECUTABLE=/usr/bin/google-chrome node scripts/test_onboarding_browser.cjs
FLEET_TEST_NETWORK=testnet CHROME_EXECUTABLE=/usr/bin/google-chrome node scripts/test_onboarding_browser.cjs
CHROME_EXECUTABLE=/usr/bin/google-chrome node scripts/test_wallet_browser.cjs
(cd dapp && pnpm typecheck && pnpm build)

The unit test is included in make test-manifest/make dapp-typecheck. Browser tests use actual dApp Kit and the production wallet initializer/page component, with fixture Wallet Standard signing, network responses and Enoki session metadata. They test localnet/testnet configuration, Google registration only on testnet, Slush registration, progress/next-action states, readable and exact balances, zero-gas gating, disclosed handover warnings, keyboard focus and disclosure, registration confirmation/rejection/inventory, duplicate-submission prevention, session wall-clock and epoch expiry, network mismatch, unavailable balance/inventory and disconnect. The onboarding run loads the application's compiled Tailwind stylesheet and checks 375/768/1280 px widths for horizontal overflow and WCAG AA text contrast; set SCREENSHOT_DIR to keep screenshots. They do not log into Google/Slush, operate an extension or submit to a chain.

The user-authorized implementation/acceptance split now covers SF-088; see the acceptance policy. Final provisioned Google/Enoki, real Slush web and extension acceptance remains unrun and tracked in SF-031/#32 and SF-087/#159. This includes rejection, expiry, mismatch, registration effects/inventory and owner transfer to the destination wallet or multisig. Record browser/wallet versions, origins, public network/package IDs and transaction digests without credentials in the final test phase. Source/security review, local failure-path/browser fixtures, normal automatic public-testnet validation and current CI remain implementation gates. Fixture evidence does not establish real provider or wallet acceptance.

References: Enoki registration, Enoki sign-in, dApp Kit configuration.

Optional organization action protection

The console's Settings → Organization security shows the policy for every fleet in the selected organization. The shared framework starts with all four options off. Multisig administrators, a passkey co-signature, approval from another credential, and a delay/cancel window are independent options; selected options combine, so every required protection must pass.

Until the corresponding verifier and enrollment feature is installed, its checkbox says Not available yet and cannot be enabled. Signing in with a passkey or multisig wallet alone does not activate an organization policy. The framework never reports an unavailable mechanism as working protection.

Changing administrators, weakening protection or handing over an organization requires the currently effective factors. Losing a required factor can lock administration; there is no support/email reset. Migration and complete managed custody are prerequisites to activation. See the approved design and recovery rules and operational steps. Manual real-wallet and outsider walkthroughs remain final acceptance in #32/#159; the automated public-chain query/effects evidence is separate.

Source: Edit this page