Skip to content

Quick Start

This guide connects a browser app to MDS, obtains an app-owned lockbox, and stores an encrypted JSON document.

1. Register your app

Ask MDS to register your application and callback URLs. You will receive an appId, for example 01J2X….

Register the exact production HTTPS callback URL. A callback that differs by path, port, scheme, or trailing slash will be rejected.

2. SDK availability

@mds/sdk is not currently published to npm. There is no supported public installation command yet.

Installation instructions will be added when MDS has a supported package distribution and development environment. The remaining examples describe the intended TypeScript API so applications can plan their integration without relying on a package that does not yet exist publicly.

3. Configure MdsAppClient

Create one client for your registered app:

ts
import { MdsAppClient } from '@mds/sdk'

const mds = new MdsAppClient({
  appId: '01J2X…',
  managerUrl: 'https://manager.megadatasystems.com',
  authServiceUrl: 'https://auth.megadatasystems.com',
  vaultServiceUrl: 'https://vault.megadatasystems.com',
  redirectUri: `${window.location.origin}/callback`,
})

appId and redirectUri must match the MDS application registry. Do not put a client secret in your frontend; browser integrations do not have one.

4. Handle the callback

Call handleCallback() before rendering the disconnected state. It returns a pairwise identity when the current URL contains a valid authorization response, and null on an ordinary page load.

ts
async function boot() {
  const identity = await mds.handleCallback()

  if (identity) {
    console.log('Connected', identity.handle)
  }

  renderApp({ connected: mds.isConnected })
}

boot()

The handle identifies this user only inside your app. It is not their MDS account id and must not be used to correlate them with another app.

5. Add a Connect button

Start the consent flow in direct response to a user action:

ts
connectButton.addEventListener('click', () => {
  void mds.connect({
    action: 'read_write',
    reason: 'Save and sync your workout history',
  })
})

The browser goes to Vault Manager, where the user sees your registered app name, the requested access, and your reason. On approval, that reason becomes part of the user's signed consent receipt for later audit. Approval then redirects back to the registered callback URL. A denial is reported by handleCallback() as CONSENT_DENIED.

Use the narrowest action your app needs: read, write, or read_write.

6. Open your app lockbox

After a successful callback, select the grant marked as owned by your app and open its lockbox:

ts
const grant = await mds.appOwnedGrant()
if (!grant) throw new Error('MDS did not return an app lockbox grant')

const box = await mds.openAppLockbox(grant.lockbox_id)

Do not select the first item returned by listMyGrants(). Shared lockboxes may also be present; appOwnedGrant() uses the server-verified app_owned marker.

7. Store and read JSON

LockboxHandle reads and writes bytes. Encode JSON before writing and decode it after reading:

ts
const encoder = new TextEncoder()
const decoder = new TextDecoder()

try {
  const workout = {
    startedAt: new Date().toISOString(),
    activity: 'run',
    distanceMetres: 5000,
  }

  await box.putResource(
    'latest-workout.json',
    encoder.encode(JSON.stringify(workout)),
    { contentType: 'application/json' },
  )

  const stored = await box.getResource({ name: 'latest-workout.json' })
  const restored = JSON.parse(decoder.decode(stored.bytes))
  console.log(restored)
} finally {
  box.close()
}

Encryption, integrity checking, key unwrapping, and authenticated vault requests happen inside the SDK. Always close a handle when you finish so its unwrapped lockbox key is zeroed from memory.

8. Disconnect

ts
await mds.disconnect()

This revokes the current pairwise refresh token and clears the in-memory connection. It does not revoke the user's consent grant; the user controls that from Vault Manager.

Next steps

Third-party access is pairwise, consented, and encrypted by design.