Skip to content

authVault documents fail to deserialize after backward-compatible authVaultAccess contract update #3515

@PastaPastaPasta

Description

@PastaPastaPasta

Summary

After submitting a backward-compatible DataContractUpdate for Yappr auth vault contract 64RTgHjGXhtiN9t5S4u6hVDps7oHuTBaaHrQEFYcxt9M, reads of authVault documents started failing with:

protocol: Corrupted Serialization: error reading string from serialized document

The update was accepted by Platform and the contract now reports version 2.

Expected

A contract update that only changes authVaultAccess should not break reads of existing authVault documents, especially because the authVault schema itself is unchanged.

Actual

After the update:

  • authVaultAccess queries still work
  • authVault queries fail
  • direct getDocument / sdk.documents.get(...) for an existing authVault also fails

This reproduces outside the app in a standalone Node script using @dashevo/evo-sdk@3.1.0-dev.1, so it does not appear to be an application-layer bug.

Contract

Contract ID:

64RTgHjGXhtiN9t5S4u6hVDps7oHuTBaaHrQEFYcxt9M

Contract version after update:

2

Schema delta

Only authVaultAccess changed. authVault did not.

Pre-update (v1)

{
  "authVault": {
    "properties": {
      "version": { "type": "integer", "position": 0 },
      "secretKind": { "type": "string", "enum": ["login-key", "auth-key"], "position": 1 },
      "ciphertext": { "type": "array", "byteArray": true, "position": 2 },
      "iv": { "type": "array", "byteArray": true, "position": 3 },
      "bundleHash": { "type": "array", "byteArray": true, "position": 4 },
      "updatedAt": { "type": "integer", "position": 5 },
      "active": { "type": "boolean", "position": 6 }
    }
  },
  "authVaultAccess": {
    "properties": {
      "vaultId": { "type": "array", "byteArray": true, "position": 0 },
      "kind": { "type": "string", "enum": ["password", "passkey-prf"], "position": 1 },
      "label": { "type": "string", "position": 2 },
      "status": { "type": "string", "enum": ["active", "revoked"], "position": 3 },
      "wrappedDek": { "type": "array", "byteArray": true, "position": 4 },
      "iv": { "type": "array", "byteArray": true, "position": 5 },
      "kdfType": { "type": "string", "position": 6 },
      "pbkdf2Salt": { "type": "array", "byteArray": true, "position": 7 },
      "pbkdf2Iterations": { "type": "integer", "position": 8 },
      "credentialId": { "type": "array", "byteArray": true, "position": 9 },
      "credentialIdHash": { "type": "array", "byteArray": true, "position": 10 },
      "prfInput": { "type": "array", "byteArray": true, "position": 11 },
      "rpId": { "type": "string", "position": 12 }
    }
  }
}

Post-update (v2)

{
  "authVault": {
    "properties": {
      "version": { "type": "integer", "position": 0 },
      "secretKind": { "type": "string", "enum": ["login-key", "auth-key"], "position": 1 },
      "ciphertext": { "type": "array", "byteArray": true, "position": 2 },
      "iv": { "type": "array", "byteArray": true, "position": 3 },
      "bundleHash": { "type": "array", "byteArray": true, "position": 4 },
      "updatedAt": { "type": "integer", "position": 5 },
      "active": { "type": "boolean", "position": 6 }
    }
  },
  "authVaultAccess": {
    "properties": {
      "vaultId": { "type": "array", "byteArray": true, "position": 0 },
      "kind": { "type": "string", "enum": ["password", "passkey-prf", "auth-key"], "position": 1 },
      "label": { "type": "string", "position": 2 },
      "status": { "type": "string", "enum": ["active", "revoked"], "position": 3 },
      "wrappedDek": { "type": "array", "byteArray": true, "position": 4 },
      "iv": { "type": "array", "byteArray": true, "position": 5 },
      "kdfType": { "type": "string", "position": 6 },
      "pbkdf2Salt": { "type": "array", "byteArray": true, "position": 7 },
      "pbkdf2Iterations": { "type": "integer", "position": 8 },
      "credentialId": { "type": "array", "byteArray": true, "position": 9 },
      "credentialIdHash": { "type": "array", "byteArray": true, "position": 10 },
      "prfInput": { "type": "array", "byteArray": true, "position": 11 },
      "rpId": { "type": "string", "position": 12 },
      "authKeyId": { "type": "integer", "minimum": 0, "maximum": 4294967295, "position": 13 }
    }
  }
}

Minimal repro

Using @dashevo/evo-sdk@3.1.0-dev.1 on testnet:

import { EvoSDK } from '@dashevo/evo-sdk';

const sdk = EvoSDK.testnetTrusted({ settings: { timeoutMs: 8000 } });
await sdk.connect();

const contractId = '64RTgHjGXhtiN9t5S4u6hVDps7oHuTBaaHrQEFYcxt9M';

const authVaultAccess = await sdk.documents.query({
  dataContractId: contractId,
  documentTypeName: 'authVaultAccess',
  limit: 1,
});
console.log('authVaultAccess ok', authVaultAccess.size);

const authVault = await sdk.documents.query({
  dataContractId: contractId,
  documentTypeName: 'authVault',
  limit: 1,
});
console.log('authVault ok', authVault.size);

Actual result:

authVaultAccess ok 1
protocol: Corrupted Serialization: error reading string from serialized document

Owner-filtered query also fails:

await sdk.documents.query({
  dataContractId: contractId,
  documentTypeName: 'authVault',
  where: [['$ownerId', '==', '3TvXzxbW2w2zeaTwXjXyLwjjN9M3UXzYy8d1w4Gv272x']],
  limit: 1,
});

Direct get for an existing vault id also fails:

await sdk.documents.get(
  contractId,
  'authVault',
  'GEcUCZVRbMng5ozZGcFAy5TPZMF5diN4Pm9o311PrC6t'
);

Notes

  • The contract fetch itself succeeds and reports version 2
  • authVaultAccess continues to deserialize correctly
  • authVault schema appears unchanged between v1 and v2
  • This suggests a regression in document decoding after contract update rather than a problem in the app query layer

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions