Skip to content

Building Holochain Apps

Let users prove their Flowsta identity on your Holochain app's DHT.

When users link their Flowsta identity to your app, a cryptographic attestation (IsSamePersonEntry) is committed to your DHT. Anyone on your network can verify the link using Ed25519 cryptography - no shared DNA or API dependency required.

Prerequisites

  1. A Holochain application with its own DNA
  2. A registered app at dev.flowsta.com (for client_id)
  3. Users have Flowsta Vault installed on their desktop

Step 1: Add Agent-Linking Zomes

Add the flowsta-agent-linking crate to your DNA:

toml
# integrity/Cargo.toml
[dependencies]
flowsta-agent-linking-integrity = { git = "https://github.com/WeAreFlowsta/flowsta-agent-linking" }
toml
# coordinator/Cargo.toml
[dependencies]
flowsta-agent-linking-coordinator = { git = "https://github.com/WeAreFlowsta/flowsta-agent-linking" }

Reference them in your dna.yaml:

yaml
integrity:
  zomes:
    - name: agent_linking_integrity
      bundled: ../../target/.../flowsta_agent_linking_integrity.wasm
coordinator:
  zomes:
    - name: agent_linking
      bundled: ../../target/.../flowsta_agent_linking_coordinator.wasm
      dependencies:
        - name: agent_linking_integrity

Step 2: Install the SDK

bash
npm install @flowsta/holochain

Step 3: Request Identity Linking

typescript
import { linkFlowstaIdentity } from '@flowsta/holochain';

// Request link from Vault
const result = await linkFlowstaIdentity({
  appName: 'ChessChain',
  clientId: 'flowsta_app_abc123', // from dev.flowsta.com
  localAgentPubKey: myAgentKey,   // uhCAk... format
});

// result.payload contains:
// - vaultAgentPubKey: the Vault's agent key
// - vaultSignature: Ed25519 signature of the 78-byte linking payload

Step 4: Commit to Your DHT

typescript
import { decodeHashFromBase64 } from '@holochain/client';

await appWebsocket.callZome({
  role_name: 'my-role',
  zome_name: 'agent_linking',
  fn_name: 'create_direct_link',
  payload: {
    other_agent: decodeHashFromBase64(result.payload.vaultAgentPubKey),
    other_signature: base64ToSignature(result.payload.vaultSignature),
  },
});

The create_direct_link function:

  1. Verifies the Vault's Ed25519 signature
  2. Creates a local signature from your app's agent key
  3. Commits an IsSamePersonEntry with both signatures
  4. Creates lookup links for querying

Step 5: Query Linked Agents

typescript
import { getFlowstaIdentity } from '@flowsta/holochain';

const linkedAgents = await getFlowstaIdentity({
  appWebsocket,
  roleName: 'my-role',
  agentPubKey: someAgentKey,
});

// linkedAgents is Uint8Array[] - array of linked agent public keys
if (linkedAgents.length > 0) {
  console.log(`Linked to ${linkedAgents.length} Flowsta identities`);
}

Or call the zome directly:

typescript
const linkedAgents = await appWebsocket.callZome({
  role_name: 'my-role',
  zome_name: 'agent_linking',
  fn_name: 'get_linked_agents',
  payload: myAgentKey,
});

Error Handling

Handle Vault availability gracefully:

typescript
import { getVaultStatus, linkFlowstaIdentity } from '@flowsta/holochain';

// Check if Vault is available first
const status = await getVaultStatus();

if (!status.running) {
  showMessage('Please install and start Flowsta Vault');
  return;
}

if (!status.unlocked) {
  showMessage('Please unlock your Flowsta Vault');
  return;
}

try {
  const result = await linkFlowstaIdentity({ /* ... */ });
} catch (error) {
  if (error.name === 'UserDeniedError') {
    showMessage('Identity linking was cancelled');
  } else if (error.name === 'InvalidClientIdError') {
    showMessage('App registration error');
  }
}

See the full error reference in Agent Linking.

User Data Backups

If your app stores user data on Holochain, you can integrate auto-backups to store data securely in users' Vaults.

Next Steps

Documentation licensed under CC BY-SA 4.0.