adam-sdk
    Preparing search index...

    adam-sdk

    adam-sdk

    A JavaScript SDK for integrating A.D.A.M. 3D avatars into your web applications.

    npm install adam-sdk
    
    import { AvatarSDK } from 'adam-sdk';

    // Get the iframe element from your page
    const avatarIframe = document.getElementById('avatar-iframe');

    // Instantiate the SDK
    const sdk = new AvatarSDK(avatarIframe);

    // Listen for the 'ready' event, which fires after a successful and secure connection
    sdk.on('ready', () => {
    console.log('SDK is ready! The avatar can now receive commands.');
    sdk.speak('Hello from the packaged SDK!');
    });

    // Always handle potential connection errors
    sdk.connect().catch(error => {
    console.error("Failed to connect to avatar:", error);
    });

    All SDK commands wait for handshake completion before sending messages to the avatar iframe. This ensures consistent behavior and reliable communication between the parent application and the avatar. All commands, including speak, playAnimation, and setExpression, follow the same pattern of verifying the connection before sending messages.

    Protecting user data and sensitive API keys is the most critical aspect of the A.D.A.M. platform. Our security model is designed to be robust and transparent, ensuring that your keys are never exposed to the client-side.

    The responsibility for security is intentionally separated between this SDK and the A.D.A.M. iframe application.

    • The SDK (adam-sdk): Acts as a well-behaved messenger. Its only job is to send commands and listen for events. It has no access to your configuration or API keys.
    • The A.D.A.M. Iframe (adam-speaks.com): Acts as the security gatekeeper. It is solely responsible for verifying the identity of the website it is embedded on before loading any sensitive data.

    When you call sdk.connect(), the following secure handshake takes place:

    1. SDK Sends Handshake Request: The SDK sends a non-sensitive CHECK_READY_STATUS message to the iframe.
    2. Iframe Receives Request: The iframe receives the message and inspects the event.origin property, which is a browser-verified value indicating the domain of your website.
    3. Origin Verification: The iframe's internal IframeSecurityService sends the origin to a secure backend Cloud Function. This function retrieves the Trusted Origins list associated with your avatar's configuration from Firestore.
    4. The Critical Check: The backend function compares the calling origin against your list of trusted domains.
      • If it matches: The function signals success to the iframe.
      • If it does not match: The process is immediately halted. The iframe remains silent and does not respond to the SDK.
    5. Secure Config Loading: Only after a successful origin check does the IframeSecurityService call a second, separate Cloud Function to fetch the sensitive configuration, including your API keys.
    6. Connection Complete: The iframe, now fully configured, sends the AVATAR_READY message back to the SDK. The ready event is fired, and your application can begin sending commands.

    To complete this security model, our Firestore database is locked down with the following rule, making it impossible for any client-side code to read or write to the avatar configuration collection. All data access is brokered through secure, server-side Cloud Functions.

    // firestore.rules
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    // Disallow ALL client-side reads/writes to the avatars collection.
    match /avatars/{avatarId} {
    allow read, write: if false;
    }
    }
    }

    If the sdk.connect() promise rejects with a timeout error, it is a direct result of the security model working as intended.

    This error means that the domain of the website where you are running the SDK has not been added to the "Trusted Origins" list in your A.D.A.M. admin console. To fix this, simply add the required domain (e.g., https://www.your-production-site.com or http://localhost:3000 for development) to the list.

    The SDK and example templates communicate with the avatar iframe using window.postMessage. Messages are simple JSON objects with a type and an optional payload.

    Security note: Always set the targetOrigin to your trusted iframe origin (e.g., https://your-avatar-host.example) instead of * in production.

    • speak
      {
      "type": "speak",
      "requestId": "optional-uuid",
      "payload": {
      "text": "Hello world",
      "animation": { "name": "wave" },
      "expression": { "name": "smile", "intensity": 0.8 },
      "voice": { "id": "en-US-JennyNeural" }
      }
      }
    • animation
      { "type": "animation", "payload": { "name": "wave" }, "requestId": "optional-uuid" }
      
    • expression
      { "type": "expression", "payload": { "name": "smile", "intensity": 0.8 }, "requestId": "optional-uuid" }
      

    Fields:

    • type: Command name.
    • payload: Command parameters (text is required; animation, expression, and voice are optional).
    • requestId (optional): Provide to correlate command responses.
    • Ready
      { "type": "ready" }
      
    • Speech start/end
      { "type": "speech:start", "payload": { "utteranceId": "u1" } }
      { "type": "speech:end", "payload": { "utteranceId": "u1" } }
    • Command success/error
      { "type": "command:success", "payload": { "requestId": "optional-uuid", "result": { } } }
      { "type": "command:error", "payload": { "requestId": "optional-uuid", "message": "details" } }

    Event notes:

    • Always validate event.origin against your trusted domain list before acting on events.
    • If you use requestId on commands, include it in success/error payloads for correlation.

    We include minimal, no-bloat starter templates under adam-sdk/examples/ that are ready to embed the avatar via an iframe and communicate using window.postMessage. Each template exposes simple placeholder methods and event handling:

    • speak(text)
    • animation(name)
    • expression(name, intensity)
    • onEvent(handler) for iframe-emitted events like ready, speech:start, speech:end, etc.

    Important: In the example bridges, the postMessage origin is * for convenience. For production, replace * with your real iframe origin (e.g., https://your-avatar-host.example).

    Directory: adam-sdk/examples/react/

    1. Install and run:
      cd adam-sdk/examples/react
      npm install
      npm run dev
    2. Edit src/avatarBridge.js to lock the origin and update the <iframe src> in src/App.jsx to your hosted avatar URL.

    Directory: adam-sdk/examples/angular/

    1. Install and run:
      cd adam-sdk/examples/angular
      npm install
      npm run start
    2. Edit src/app/avatar-bridge.ts to lock the origin and update the <iframe> src in src/app/app.component.html.
    3. Template is separate from the class, following the project guideline.

    Directory: adam-sdk/examples/vue/

    1. Install and run:
      cd adam-sdk/examples/vue
      npm install
      npm run dev
    2. Edit src/avatarBridge.js to lock the origin and update the <iframe src> in src/App.vue.

    All templates are intentionally small, with just enough structure to demonstrate:

    • Embedding the iframe and sending commands
    • Receiving events and basic logging
    • Where to securely configure origins and endpoints
    • Message Contract: docs/message-contract.html
    • Starter Templates: docs/examples-starters.html

    To view the full, detailed API documentation:

    1. Generate the docs:
      npm run docs
      
    2. Serve the docs locally:
      npm run docs:serve
      

    This will start a local web server and provide a URL to view the documentation in your browser.

    Listen for events using the sdk.on() method:

    • ready: Fired when the SDK has successfully and securely connected to the avatar iframe.
    • speech:start: Fired when the avatar starts speaking.
    • speech:end: Fired when the avatar finishes speaking.
    • command:success: Fired when a command is successfully executed.
    • command:error: Fired when a command fails.

    We include the built API docs (docs/) in the npm package alongside the compiled library (dist/). The publish flow automatically builds both via prepublishOnly.

    • Version: set in package.json (current: 1.0.3). For future releases: npm version patch|minor|major -m "chore(release): %s".
    • Build: npm run build (Vite)
    • Docs: npm run docs (TypeDoc → docs/)
    • Auto step on publish: prepublishOnly runs build and docs automatically.

    Run from adam-sdk/adam-sdk/:

    # 1) Verify npm login and access
    npm whoami

    # 2) Install clean deps
    npm ci

    # 3) (Optional) Test/build/docs locally
    npm test || true
    npm run build
    npm run docs

    # 4) Publish (triggers prepublishOnly: build + docs)
    npm publish --access public

    Notes:

    • If your npm account uses 2FA for publishing, be ready to enter your OTP.
    • The published tarball includes dist/ and docs/ (see the files field).