@enbox/agent 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +2215 -0
- package/dist/browser.js.map +7 -0
- package/dist/browser.mjs +2215 -0
- package/dist/browser.mjs.map +7 -0
- package/dist/cjs/index.js +8530 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/agent-did-resolver-cache.js +87 -0
- package/dist/esm/agent-did-resolver-cache.js.map +1 -0
- package/dist/esm/bearer-identity.js +41 -0
- package/dist/esm/bearer-identity.js.map +1 -0
- package/dist/esm/connect.js +191 -0
- package/dist/esm/connect.js.map +1 -0
- package/dist/esm/crypto-api.js +346 -0
- package/dist/esm/crypto-api.js.map +1 -0
- package/dist/esm/did-api.js +278 -0
- package/dist/esm/did-api.js.map +1 -0
- package/dist/esm/dwn-api.js +336 -0
- package/dist/esm/dwn-api.js.map +1 -0
- package/dist/esm/dwn-registrar.js +120 -0
- package/dist/esm/dwn-registrar.js.map +1 -0
- package/dist/esm/hd-identity-vault.js +729 -0
- package/dist/esm/hd-identity-vault.js.map +1 -0
- package/dist/esm/identity-api.js +262 -0
- package/dist/esm/identity-api.js.map +1 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/local-key-manager.js +498 -0
- package/dist/esm/local-key-manager.js.map +1 -0
- package/dist/esm/oidc.js +507 -0
- package/dist/esm/oidc.js.map +1 -0
- package/dist/esm/permissions-api.js +322 -0
- package/dist/esm/permissions-api.js.map +1 -0
- package/dist/esm/prototyping/clients/dwn-rpc-types.js +2 -0
- package/dist/esm/prototyping/clients/dwn-rpc-types.js.map +1 -0
- package/dist/esm/prototyping/clients/dwn-server-info-cache-memory.js +74 -0
- package/dist/esm/prototyping/clients/dwn-server-info-cache-memory.js.map +1 -0
- package/dist/esm/prototyping/clients/http-dwn-rpc-client.js +105 -0
- package/dist/esm/prototyping/clients/http-dwn-rpc-client.js.map +1 -0
- package/dist/esm/prototyping/clients/json-rpc-socket.js +150 -0
- package/dist/esm/prototyping/clients/json-rpc-socket.js.map +1 -0
- package/dist/esm/prototyping/clients/json-rpc.js +58 -0
- package/dist/esm/prototyping/clients/json-rpc.js.map +1 -0
- package/dist/esm/prototyping/clients/server-info-types.js +2 -0
- package/dist/esm/prototyping/clients/server-info-types.js.map +1 -0
- package/dist/esm/prototyping/clients/web-socket-clients.js +90 -0
- package/dist/esm/prototyping/clients/web-socket-clients.js.map +1 -0
- package/dist/esm/prototyping/common/object.js +14 -0
- package/dist/esm/prototyping/common/object.js.map +1 -0
- package/dist/esm/prototyping/common/type-utils.js +2 -0
- package/dist/esm/prototyping/common/type-utils.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-gcm.js +147 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-gcm.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-kw.js +137 -0
- package/dist/esm/prototyping/crypto/algorithms/aes-kw.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/ecdsa.js +307 -0
- package/dist/esm/prototyping/crypto/algorithms/ecdsa.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/eddsa.js +264 -0
- package/dist/esm/prototyping/crypto/algorithms/eddsa.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/hkdf.js +39 -0
- package/dist/esm/prototyping/crypto/algorithms/hkdf.js.map +1 -0
- package/dist/esm/prototyping/crypto/algorithms/pbkdf2.js +41 -0
- package/dist/esm/prototyping/crypto/algorithms/pbkdf2.js.map +1 -0
- package/dist/esm/prototyping/crypto/crypto-error.js +41 -0
- package/dist/esm/prototyping/crypto/crypto-error.js.map +1 -0
- package/dist/esm/prototyping/crypto/dsa.js +236 -0
- package/dist/esm/prototyping/crypto/dsa.js.map +1 -0
- package/dist/esm/prototyping/crypto/jose/jwe-compact.js +130 -0
- package/dist/esm/prototyping/crypto/jose/jwe-compact.js.map +1 -0
- package/dist/esm/prototyping/crypto/jose/jwe-flattened.js +294 -0
- package/dist/esm/prototyping/crypto/jose/jwe-flattened.js.map +1 -0
- package/dist/esm/prototyping/crypto/jose/jwe.js +308 -0
- package/dist/esm/prototyping/crypto/jose/jwe.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/aes-gcm.js +352 -0
- package/dist/esm/prototyping/crypto/primitives/aes-gcm.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/aes-kw.js +247 -0
- package/dist/esm/prototyping/crypto/primitives/aes-kw.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/hkdf.js +80 -0
- package/dist/esm/prototyping/crypto/primitives/hkdf.js.map +1 -0
- package/dist/esm/prototyping/crypto/primitives/pbkdf2.js +85 -0
- package/dist/esm/prototyping/crypto/primitives/pbkdf2.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/cipher.js +2 -0
- package/dist/esm/prototyping/crypto/types/cipher.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/crypto-api.js +2 -0
- package/dist/esm/prototyping/crypto/types/crypto-api.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-converter.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-converter.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-deriver.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-deriver.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-io.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-io.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-manager.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-manager.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/key-wrapper.js +2 -0
- package/dist/esm/prototyping/crypto/types/key-wrapper.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/params-direct.js +2 -0
- package/dist/esm/prototyping/crypto/types/params-direct.js.map +1 -0
- package/dist/esm/prototyping/crypto/types/params-kms.js +2 -0
- package/dist/esm/prototyping/crypto/types/params-kms.js.map +1 -0
- package/dist/esm/prototyping/crypto/utils.js +19 -0
- package/dist/esm/prototyping/crypto/utils.js.map +1 -0
- package/dist/esm/prototyping/dids/resolver-cache-memory.js +77 -0
- package/dist/esm/prototyping/dids/resolver-cache-memory.js.map +1 -0
- package/dist/esm/prototyping/dids/utils.js +9 -0
- package/dist/esm/prototyping/dids/utils.js.map +1 -0
- package/dist/esm/rpc-client.js +123 -0
- package/dist/esm/rpc-client.js.map +1 -0
- package/dist/esm/store-data-protocols.js +38 -0
- package/dist/esm/store-data-protocols.js.map +1 -0
- package/dist/esm/store-data.js +320 -0
- package/dist/esm/store-data.js.map +1 -0
- package/dist/esm/store-did.js +136 -0
- package/dist/esm/store-did.js.map +1 -0
- package/dist/esm/store-identity.js +140 -0
- package/dist/esm/store-identity.js.map +1 -0
- package/dist/esm/store-key.js +136 -0
- package/dist/esm/store-key.js.map +1 -0
- package/dist/esm/sync-api.js +61 -0
- package/dist/esm/sync-api.js.map +1 -0
- package/dist/esm/sync-engine-level.js +618 -0
- package/dist/esm/sync-engine-level.js.map +1 -0
- package/dist/esm/test-harness.js +239 -0
- package/dist/esm/test-harness.js.map +1 -0
- package/dist/esm/types/agent.js +2 -0
- package/dist/esm/types/agent.js.map +1 -0
- package/dist/esm/types/dwn.js +31 -0
- package/dist/esm/types/dwn.js.map +1 -0
- package/dist/esm/types/identity-vault.js +2 -0
- package/dist/esm/types/identity-vault.js.map +1 -0
- package/dist/esm/types/identity.js +2 -0
- package/dist/esm/types/identity.js.map +1 -0
- package/dist/esm/types/key-manager.js +2 -0
- package/dist/esm/types/key-manager.js.map +1 -0
- package/dist/esm/types/permissions.js +2 -0
- package/dist/esm/types/permissions.js.map +1 -0
- package/dist/esm/types/sync.js +2 -0
- package/dist/esm/types/sync.js.map +1 -0
- package/dist/esm/types/vc.js +5 -0
- package/dist/esm/types/vc.js.map +1 -0
- package/dist/esm/utils-internal.js +147 -0
- package/dist/esm/utils-internal.js.map +1 -0
- package/dist/esm/utils.js +161 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/types/agent-did-resolver-cache.d.ts +30 -0
- package/dist/types/agent-did-resolver-cache.d.ts.map +1 -0
- package/dist/types/bearer-identity.d.ts +31 -0
- package/dist/types/bearer-identity.d.ts.map +1 -0
- package/dist/types/connect.d.ts +88 -0
- package/dist/types/connect.d.ts.map +1 -0
- package/dist/types/crypto-api.d.ts +286 -0
- package/dist/types/crypto-api.d.ts.map +1 -0
- package/dist/types/did-api.d.ts +119 -0
- package/dist/types/did-api.d.ts.map +1 -0
- package/dist/types/dwn-api.d.ts +66 -0
- package/dist/types/dwn-api.d.ts.map +1 -0
- package/dist/types/dwn-registrar.d.ts +29 -0
- package/dist/types/dwn-registrar.d.ts.map +1 -0
- package/dist/types/hd-identity-vault.d.ts +306 -0
- package/dist/types/hd-identity-vault.d.ts.map +1 -0
- package/dist/types/identity-api.d.ts +107 -0
- package/dist/types/identity-api.d.ts.map +1 -0
- package/dist/types/index.d.ts +30 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/local-key-manager.d.ts +311 -0
- package/dist/types/local-key-manager.d.ts.map +1 -0
- package/dist/types/oidc.d.ts +247 -0
- package/dist/types/oidc.d.ts.map +1 -0
- package/dist/types/permissions-api.d.ts +35 -0
- package/dist/types/permissions-api.d.ts.map +1 -0
- package/dist/types/prototyping/clients/dwn-rpc-types.d.ts +45 -0
- package/dist/types/prototyping/clients/dwn-rpc-types.d.ts.map +1 -0
- package/dist/types/prototyping/clients/dwn-server-info-cache-memory.d.ts +57 -0
- package/dist/types/prototyping/clients/dwn-server-info-cache-memory.d.ts.map +1 -0
- package/dist/types/prototyping/clients/http-dwn-rpc-client.d.ts +13 -0
- package/dist/types/prototyping/clients/http-dwn-rpc-client.d.ts.map +1 -0
- package/dist/types/prototyping/clients/json-rpc-socket.d.ts +43 -0
- package/dist/types/prototyping/clients/json-rpc-socket.d.ts.map +1 -0
- package/dist/types/prototyping/clients/json-rpc.d.ts +49 -0
- package/dist/types/prototyping/clients/json-rpc.d.ts.map +1 -0
- package/dist/types/prototyping/clients/server-info-types.d.ts +20 -0
- package/dist/types/prototyping/clients/server-info-types.d.ts.map +1 -0
- package/dist/types/prototyping/clients/web-socket-clients.d.ts +10 -0
- package/dist/types/prototyping/clients/web-socket-clients.d.ts.map +1 -0
- package/dist/types/prototyping/common/object.d.ts +2 -0
- package/dist/types/prototyping/common/object.d.ts.map +1 -0
- package/dist/types/prototyping/common/type-utils.d.ts +7 -0
- package/dist/types/prototyping/common/type-utils.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/aes-gcm.d.ts +151 -0
- package/dist/types/prototyping/crypto/algorithms/aes-gcm.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/aes-kw.d.ts +109 -0
- package/dist/types/prototyping/crypto/algorithms/aes-kw.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/ecdsa.d.ts +160 -0
- package/dist/types/prototyping/crypto/algorithms/ecdsa.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/eddsa.d.ts +157 -0
- package/dist/types/prototyping/crypto/algorithms/eddsa.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/hkdf.d.ts +21 -0
- package/dist/types/prototyping/crypto/algorithms/hkdf.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/algorithms/pbkdf2.d.ts +21 -0
- package/dist/types/prototyping/crypto/algorithms/pbkdf2.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/crypto-error.d.ts +29 -0
- package/dist/types/prototyping/crypto/crypto-error.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/dsa.d.ts +169 -0
- package/dist/types/prototyping/crypto/dsa.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/jose/jwe-compact.d.ts +135 -0
- package/dist/types/prototyping/crypto/jose/jwe-compact.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/jose/jwe-flattened.d.ts +134 -0
- package/dist/types/prototyping/crypto/jose/jwe-flattened.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/jose/jwe.d.ts +378 -0
- package/dist/types/prototyping/crypto/jose/jwe.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/aes-gcm.d.ts +245 -0
- package/dist/types/prototyping/crypto/primitives/aes-gcm.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/aes-kw.d.ts +103 -0
- package/dist/types/prototyping/crypto/primitives/aes-kw.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/hkdf.d.ts +90 -0
- package/dist/types/prototyping/crypto/primitives/hkdf.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/primitives/pbkdf2.d.ts +84 -0
- package/dist/types/prototyping/crypto/primitives/pbkdf2.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/cipher.d.ts +14 -0
- package/dist/types/prototyping/crypto/types/cipher.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/crypto-api.d.ts +35 -0
- package/dist/types/prototyping/crypto/types/crypto-api.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-converter.d.ts +49 -0
- package/dist/types/prototyping/crypto/types/key-converter.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-deriver.d.ts +50 -0
- package/dist/types/prototyping/crypto/types/key-deriver.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-io.d.ts +49 -0
- package/dist/types/prototyping/crypto/types/key-io.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-manager.d.ts +69 -0
- package/dist/types/prototyping/crypto/types/key-manager.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/key-wrapper.d.ts +14 -0
- package/dist/types/prototyping/crypto/types/key-wrapper.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/params-direct.d.ts +75 -0
- package/dist/types/prototyping/crypto/types/params-direct.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/types/params-kms.d.ts +63 -0
- package/dist/types/prototyping/crypto/types/params-kms.d.ts.map +1 -0
- package/dist/types/prototyping/crypto/utils.d.ts +7 -0
- package/dist/types/prototyping/crypto/utils.d.ts.map +1 -0
- package/dist/types/prototyping/dids/resolver-cache-memory.d.ts +57 -0
- package/dist/types/prototyping/dids/resolver-cache-memory.d.ts.map +1 -0
- package/dist/types/prototyping/dids/utils.d.ts +3 -0
- package/dist/types/prototyping/dids/utils.d.ts.map +1 -0
- package/dist/types/rpc-client.d.ts +51 -0
- package/dist/types/rpc-client.d.ts.map +1 -0
- package/dist/types/store-data-protocols.d.ts +4 -0
- package/dist/types/store-data-protocols.d.ts.map +1 -0
- package/dist/types/store-data.d.ts +95 -0
- package/dist/types/store-data.d.ts.map +1 -0
- package/dist/types/store-did.d.ts +33 -0
- package/dist/types/store-did.d.ts.map +1 -0
- package/dist/types/store-identity.d.ts +34 -0
- package/dist/types/store-identity.d.ts.map +1 -0
- package/dist/types/store-key.d.ts +32 -0
- package/dist/types/store-key.d.ts.map +1 -0
- package/dist/types/sync-api.d.ts +41 -0
- package/dist/types/sync-api.d.ts.map +1 -0
- package/dist/types/sync-engine-level.d.ts +85 -0
- package/dist/types/sync-engine-level.d.ts.map +1 -0
- package/dist/types/test-harness.d.ts +69 -0
- package/dist/types/test-harness.d.ts.map +1 -0
- package/dist/types/types/agent.d.ts +172 -0
- package/dist/types/types/agent.d.ts.map +1 -0
- package/dist/types/types/dwn.d.ts +178 -0
- package/dist/types/types/dwn.d.ts.map +1 -0
- package/dist/types/types/identity-vault.d.ts +129 -0
- package/dist/types/types/identity-vault.d.ts.map +1 -0
- package/dist/types/types/identity.d.ts +16 -0
- package/dist/types/types/identity.d.ts.map +1 -0
- package/dist/types/types/key-manager.d.ts +9 -0
- package/dist/types/types/key-manager.d.ts.map +1 -0
- package/dist/types/types/permissions.d.ts +98 -0
- package/dist/types/types/permissions.d.ts.map +1 -0
- package/dist/types/types/sync.d.ts +66 -0
- package/dist/types/types/sync.d.ts.map +1 -0
- package/dist/types/types/vc.d.ts +7 -0
- package/dist/types/types/vc.d.ts.map +1 -0
- package/dist/types/utils-internal.d.ts +50 -0
- package/dist/types/utils-internal.d.ts.map +1 -0
- package/dist/types/utils.d.ts +37 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +112 -0
- package/src/agent-did-resolver-cache.ts +95 -0
- package/src/bearer-identity.ts +42 -0
- package/src/connect.ts +296 -0
- package/src/crypto-api.ts +593 -0
- package/src/did-api.ts +429 -0
- package/src/dwn-api.ts +462 -0
- package/src/dwn-registrar.ts +127 -0
- package/src/hd-identity-vault.ts +853 -0
- package/src/identity-api.ts +324 -0
- package/src/index.ts +30 -0
- package/src/local-key-manager.ts +672 -0
- package/src/oidc.ts +857 -0
- package/src/permissions-api.ts +408 -0
- package/src/prototyping/clients/dwn-rpc-types.ts +55 -0
- package/src/prototyping/clients/dwn-server-info-cache-memory.ts +79 -0
- package/src/prototyping/clients/http-dwn-rpc-client.ts +110 -0
- package/src/prototyping/clients/json-rpc-socket.ts +169 -0
- package/src/prototyping/clients/json-rpc.ts +113 -0
- package/src/prototyping/clients/server-info-types.ts +21 -0
- package/src/prototyping/clients/web-socket-clients.ts +100 -0
- package/src/prototyping/common/object.ts +15 -0
- package/src/prototyping/common/type-utils.ts +6 -0
- package/src/prototyping/crypto/algorithms/aes-gcm.ts +211 -0
- package/src/prototyping/crypto/algorithms/aes-kw.ts +164 -0
- package/src/prototyping/crypto/algorithms/ecdsa.ts +365 -0
- package/src/prototyping/crypto/algorithms/eddsa.ts +310 -0
- package/src/prototyping/crypto/algorithms/hkdf.ts +40 -0
- package/src/prototyping/crypto/algorithms/pbkdf2.ts +44 -0
- package/src/prototyping/crypto/crypto-error.ts +45 -0
- package/src/prototyping/crypto/dsa.ts +367 -0
- package/src/prototyping/crypto/jose/jwe-compact.ts +225 -0
- package/src/prototyping/crypto/jose/jwe-flattened.ts +459 -0
- package/src/prototyping/crypto/jose/jwe.ts +653 -0
- package/src/prototyping/crypto/primitives/aes-gcm.ts +374 -0
- package/src/prototyping/crypto/primitives/aes-kw.ts +271 -0
- package/src/prototyping/crypto/primitives/hkdf.ts +121 -0
- package/src/prototyping/crypto/primitives/pbkdf2.ts +116 -0
- package/src/prototyping/crypto/types/cipher.ts +17 -0
- package/src/prototyping/crypto/types/crypto-api.ts +78 -0
- package/src/prototyping/crypto/types/key-converter.ts +53 -0
- package/src/prototyping/crypto/types/key-deriver.ts +56 -0
- package/src/prototyping/crypto/types/key-io.ts +51 -0
- package/src/prototyping/crypto/types/key-manager.ts +83 -0
- package/src/prototyping/crypto/types/key-wrapper.ts +17 -0
- package/src/prototyping/crypto/types/params-direct.ts +95 -0
- package/src/prototyping/crypto/types/params-kms.ts +76 -0
- package/src/prototyping/crypto/utils.ts +41 -0
- package/src/prototyping/dids/resolver-cache-memory.ts +83 -0
- package/src/prototyping/dids/utils.ts +10 -0
- package/src/rpc-client.ts +162 -0
- package/src/store-data-protocols.ts +40 -0
- package/src/store-data.ts +400 -0
- package/src/store-did.ts +105 -0
- package/src/store-identity.ts +109 -0
- package/src/store-key.ts +104 -0
- package/src/sync-api.ts +71 -0
- package/src/sync-engine-level.ts +714 -0
- package/src/test-harness.ts +330 -0
- package/src/types/agent.ts +195 -0
- package/src/types/dwn.ts +278 -0
- package/src/types/identity-vault.ts +137 -0
- package/src/types/identity.ts +18 -0
- package/src/types/key-manager.ts +15 -0
- package/src/types/permissions.ts +115 -0
- package/src/types/sync.ts +58 -0
- package/src/types/vc.ts +7 -0
- package/src/utils-internal.ts +157 -0
- package/src/utils.ts +181 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import type { Jwk } from '@enbox/crypto';
|
|
2
|
+
|
|
3
|
+
import ms from 'ms';
|
|
4
|
+
import { Convert, NodeStream, TtlCache } from '@enbox/common';
|
|
5
|
+
|
|
6
|
+
import type { Web5PlatformAgent } from './types/agent.js';
|
|
7
|
+
|
|
8
|
+
import { TENANT_SEPARATOR } from './utils-internal.js';
|
|
9
|
+
import { getDataStoreTenant } from './utils-internal.js';
|
|
10
|
+
import { DwnInterface, DwnMessageParams } from './types/dwn.js';
|
|
11
|
+
import { ProtocolDefinition, RecordsReadReplyEntry } from '@enbox/dwn-sdk-js';
|
|
12
|
+
|
|
13
|
+
export type DataStoreTenantParams = {
|
|
14
|
+
agent: Web5PlatformAgent;
|
|
15
|
+
tenant?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type DataStoreListParams = DataStoreTenantParams;
|
|
19
|
+
|
|
20
|
+
export type DataStoreGetParams = DataStoreTenantParams & {
|
|
21
|
+
id: string;
|
|
22
|
+
useCache?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type DataStoreSetParams<TStoreObject> = DataStoreTenantParams & {
|
|
26
|
+
id: string;
|
|
27
|
+
data: TStoreObject;
|
|
28
|
+
preventDuplicates?: boolean;
|
|
29
|
+
updateExisting?: boolean;
|
|
30
|
+
useCache?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type DataStoreDeleteParams = DataStoreTenantParams & {
|
|
34
|
+
id: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface AgentDataStore<TStoreObject> {
|
|
38
|
+
delete(params: DataStoreDeleteParams): Promise<boolean>;
|
|
39
|
+
|
|
40
|
+
get(params: DataStoreGetParams): Promise<TStoreObject | undefined>;
|
|
41
|
+
|
|
42
|
+
list(params: DataStoreTenantParams): Promise<TStoreObject[]>;
|
|
43
|
+
|
|
44
|
+
set(params: DataStoreSetParams<TStoreObject>): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class DwnDataStore<TStoreObject extends Record<string, any> = Jwk> implements AgentDataStore<TStoreObject> {
|
|
48
|
+
protected name = 'DwnDataStore';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Cache of Store Objects referenced by DWN record ID to Store Objects.
|
|
52
|
+
*
|
|
53
|
+
* Up to 100 entries are retained for 15 minutes.
|
|
54
|
+
*/
|
|
55
|
+
protected _cache = new TtlCache<string, TStoreObject>({ ttl: ms('15 minutes'), max: 100 });
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Index for mappings from Store Identifier to DWN record ID.
|
|
59
|
+
* Since these values don't change, we can use a long TTL.
|
|
60
|
+
*
|
|
61
|
+
* Up to 1,000 entries are retained for 21 days.
|
|
62
|
+
* NOTE: The maximum number for the ttl is 2^31 - 1 milliseconds (24.8 days), setting to 21 days to be safe.
|
|
63
|
+
*/
|
|
64
|
+
protected _index = new TtlCache<string, string>({ ttl: ms('21 days'), max: 1000 });
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Cache of tenant DIDs that have been initialized with the protocol.
|
|
68
|
+
* This is used to avoid redundant protocol initialization requests.
|
|
69
|
+
*
|
|
70
|
+
* Since these are default protocols and unlikely to change, we can use a long TTL.
|
|
71
|
+
*/
|
|
72
|
+
protected _protocolInitializedCache: TtlCache<string, boolean> = new TtlCache({ ttl: ms('21 days'), max: 1000 });
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The protocol assigned to this storage instance.
|
|
76
|
+
*/
|
|
77
|
+
protected _recordProtocolDefinition!: ProtocolDefinition;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Properties to use when writing and querying records with the DWN store.
|
|
81
|
+
*/
|
|
82
|
+
protected _recordProperties = {
|
|
83
|
+
dataFormat: 'application/json',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
public async delete({ id, agent, tenant }: DataStoreDeleteParams): Promise<boolean> {
|
|
87
|
+
// Determine the tenant identifier (DID) for the delete operation.
|
|
88
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant, didUri: id });
|
|
89
|
+
|
|
90
|
+
// Look up the DWN record ID of the object in the store with the given `id`.
|
|
91
|
+
let matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
|
|
92
|
+
|
|
93
|
+
// Return false if the given ID was not found in the store.
|
|
94
|
+
if (!matchingRecordId) return false;
|
|
95
|
+
|
|
96
|
+
// If a record for the given ID was found, attempt to delete it.
|
|
97
|
+
const { reply: { status } } = await agent.dwn.processRequest({
|
|
98
|
+
author : tenantDid,
|
|
99
|
+
target : tenantDid,
|
|
100
|
+
messageType : DwnInterface.RecordsDelete,
|
|
101
|
+
messageParams : { recordId: matchingRecordId }
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// If the record was successfully deleted, update the index/cache and return true;
|
|
105
|
+
if (status.code === 202) {
|
|
106
|
+
this._index.delete(`${tenantDid}${TENANT_SEPARATOR}${id}`);
|
|
107
|
+
this._cache.delete(matchingRecordId);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// If the Delete operation failed, throw an error.
|
|
112
|
+
throw new Error(`${this.name}: Failed to delete '${id}' from store: (${status.code}) ${status.detail}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public async get({ id, agent, tenant, useCache = false }:
|
|
116
|
+
DataStoreGetParams
|
|
117
|
+
): Promise<TStoreObject | undefined> {
|
|
118
|
+
// Determine the tenant identifier (DID) for the list operation.
|
|
119
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant, didUri: id });
|
|
120
|
+
|
|
121
|
+
// Look up the DWN record ID of the object in the store with the given `id`.
|
|
122
|
+
let matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
|
|
123
|
+
|
|
124
|
+
// Return undefined if no matches were found.
|
|
125
|
+
if (!matchingRecordId) return undefined;
|
|
126
|
+
|
|
127
|
+
// Retrieve and return the stored object.
|
|
128
|
+
return await this.getRecord({ recordId: matchingRecordId, tenantDid, agent, useCache });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public async list({ agent, tenant}: DataStoreListParams): Promise<TStoreObject[]> {
|
|
132
|
+
// Determine the tenant identifier (DID) for the list operation.
|
|
133
|
+
const tenantDid = await getDataStoreTenant({ tenant, agent });
|
|
134
|
+
|
|
135
|
+
// Query the DWN for all stored record objects.
|
|
136
|
+
const storedRecords = await this.getAllRecords({ agent, tenantDid });
|
|
137
|
+
|
|
138
|
+
return storedRecords;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public async set({ id, data, tenant, agent, preventDuplicates = true, updateExisting = false, useCache = false }:
|
|
142
|
+
DataStoreSetParams<TStoreObject>
|
|
143
|
+
): Promise<void> {
|
|
144
|
+
// Determine the tenant identifier (DID) for the set operation.
|
|
145
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant, didUri: id });
|
|
146
|
+
|
|
147
|
+
// initialize the storage protocol if not already done
|
|
148
|
+
await this.initialize({ tenant: tenantDid, agent });
|
|
149
|
+
|
|
150
|
+
const messageParams: DwnMessageParams[DwnInterface.RecordsWrite] = { ...this._recordProperties };
|
|
151
|
+
|
|
152
|
+
if (updateExisting) {
|
|
153
|
+
// Look up the DWN record ID of the object in the store with the given `id`.
|
|
154
|
+
const matchingRecordEntry = await this.getExistingRecordEntry({ id, tenantDid, agent });
|
|
155
|
+
if (!matchingRecordEntry) {
|
|
156
|
+
throw new Error(`${this.name}: Update failed due to missing entry for: ${id}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// set the recordId in the messageParams to update the existing record
|
|
160
|
+
// set the dateCreated to the existing dateCreated as this is an immutable property
|
|
161
|
+
messageParams.recordId = matchingRecordEntry.recordsWrite!.recordId;
|
|
162
|
+
messageParams.dateCreated = matchingRecordEntry.recordsWrite!.descriptor.dateCreated;
|
|
163
|
+
} else if (preventDuplicates) {
|
|
164
|
+
// Look up the DWN record ID of the object in the store with the given `id`.
|
|
165
|
+
const matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
|
|
166
|
+
if (matchingRecordId) {
|
|
167
|
+
throw new Error(`${this.name}: Import failed due to duplicate entry for: ${id}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
// Convert the store object to a byte array, which will be the data payload of the DWN record.
|
|
173
|
+
const dataBytes = Convert.object(data).toUint8Array();
|
|
174
|
+
|
|
175
|
+
// Store the record in the DWN.
|
|
176
|
+
const { message, reply: { status } } = await agent.dwn.processRequest({
|
|
177
|
+
author : tenantDid,
|
|
178
|
+
target : tenantDid,
|
|
179
|
+
messageType : DwnInterface.RecordsWrite,
|
|
180
|
+
messageParams : { ...this._recordProperties, ...messageParams },
|
|
181
|
+
dataStream : new Blob([dataBytes], { type: 'application/json' })
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// If the write fails, throw an error.
|
|
185
|
+
if (!(message && status.code === 202)) {
|
|
186
|
+
throw new Error(`${this.name}: Failed to write data to store for ${id}: ${status.detail}`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Add the ID of the newly created record to the index.
|
|
190
|
+
this._index.set(`${tenantDid}${TENANT_SEPARATOR}${id}`, message.recordId);
|
|
191
|
+
|
|
192
|
+
// If caching is enabled, add the store object to the cache.
|
|
193
|
+
if (useCache) {
|
|
194
|
+
this._cache.set(message.recordId, data);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Initialize the relevant protocol for the given tenant.
|
|
200
|
+
* This confirms that the storage protocol is configured, otherwise it will be installed.
|
|
201
|
+
*/
|
|
202
|
+
public async initialize({ tenant, agent }: DataStoreTenantParams) {
|
|
203
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant });
|
|
204
|
+
if (this._protocolInitializedCache.has(tenantDid)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const { reply: { status, entries }} = await agent.dwn.processRequest({
|
|
209
|
+
author : tenantDid,
|
|
210
|
+
target : tenantDid,
|
|
211
|
+
messageType : DwnInterface.ProtocolsQuery,
|
|
212
|
+
messageParams : {
|
|
213
|
+
filter: {
|
|
214
|
+
protocol: this._recordProtocolDefinition.protocol
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
if (status.code !== 200) {
|
|
220
|
+
throw new Error(`Failed to query for protocols: ${status.code} - ${status.detail}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (entries?.length === 0) {
|
|
224
|
+
// protocol is not installed, install it
|
|
225
|
+
await this.installProtocol(tenantDid, agent);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this._protocolInitializedCache.set(tenantDid, true);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
protected async getAllRecords(_params: {
|
|
232
|
+
agent: Web5PlatformAgent;
|
|
233
|
+
tenantDid: string;
|
|
234
|
+
}): Promise<TStoreObject[]> {
|
|
235
|
+
throw new Error('Not implemented: Classes extending DwnDataStore must implement getAllRecords()');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private async getRecord({ recordId, tenantDid, agent, useCache }: {
|
|
239
|
+
recordId: string;
|
|
240
|
+
tenantDid: string;
|
|
241
|
+
agent: Web5PlatformAgent;
|
|
242
|
+
useCache: boolean;
|
|
243
|
+
}): Promise<TStoreObject | undefined> {
|
|
244
|
+
// If caching is enabled, check the cache for the record ID.
|
|
245
|
+
if (useCache) {
|
|
246
|
+
const record = this._cache.get(recordId);
|
|
247
|
+
// If the record ID was present in the cache, return the associated store object.
|
|
248
|
+
if (record) return record;
|
|
249
|
+
// Otherwise, continue to read from the store.
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Read the record from the store.
|
|
253
|
+
const { reply: readReply } = await agent.dwn.processRequest({
|
|
254
|
+
author : tenantDid,
|
|
255
|
+
target : tenantDid,
|
|
256
|
+
messageType : DwnInterface.RecordsRead,
|
|
257
|
+
messageParams : { filter: { recordId } }
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
if (!readReply.entry?.data) {
|
|
261
|
+
throw new Error(`${this.name}: Failed to read data from DWN for: ${recordId}`);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// If the record was found, convert back to store object format.
|
|
265
|
+
const storeObject = await NodeStream.consumeToJson({ readable: readReply.entry.data }) as TStoreObject;
|
|
266
|
+
|
|
267
|
+
// If caching is enabled, add the store object to the cache.
|
|
268
|
+
if (useCache) {
|
|
269
|
+
this._cache.set(recordId, storeObject);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return storeObject;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Install the protocol for the given tenant using a `ProtocolsConfigure` message.
|
|
277
|
+
*/
|
|
278
|
+
private async installProtocol(tenant: string, agent: Web5PlatformAgent) {
|
|
279
|
+
const { reply : { status } } = await agent.dwn.processRequest({
|
|
280
|
+
author : tenant,
|
|
281
|
+
target : tenant,
|
|
282
|
+
messageType : DwnInterface.ProtocolsConfigure,
|
|
283
|
+
messageParams : {
|
|
284
|
+
definition: this._recordProtocolDefinition
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
if (status.code !== 202) {
|
|
289
|
+
throw new Error(`Failed to install protocol: ${status.code} - ${status.detail}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private async lookupRecordId({ id, tenantDid, agent }: {
|
|
294
|
+
id: string;
|
|
295
|
+
tenantDid: string;
|
|
296
|
+
agent: Web5PlatformAgent;
|
|
297
|
+
}): Promise<string | undefined> {
|
|
298
|
+
// Check the index for a matching ID and extend the index TTL.
|
|
299
|
+
let recordId = this._index.get(`${tenantDid}${TENANT_SEPARATOR}${id}`, { updateAgeOnGet: true });
|
|
300
|
+
|
|
301
|
+
// If no matching record ID was found in the index...
|
|
302
|
+
if (!recordId) {
|
|
303
|
+
// Query the DWN for all stored objects, which rebuilds the index.
|
|
304
|
+
await this.getAllRecords({ agent, tenantDid });
|
|
305
|
+
|
|
306
|
+
// Check the index again for a matching ID.
|
|
307
|
+
recordId = this._index.get(`${tenantDid}${TENANT_SEPARATOR}${id}`);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return recordId;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private async getExistingRecordEntry({ id, tenantDid, agent }: {
|
|
314
|
+
id: string;
|
|
315
|
+
tenantDid: string;
|
|
316
|
+
agent: Web5PlatformAgent;
|
|
317
|
+
}): Promise<RecordsReadReplyEntry | undefined> {
|
|
318
|
+
// Look up the DWN record ID of the object in the store with the given `id`.
|
|
319
|
+
const recordId = await this.lookupRecordId({ id, tenantDid, agent });
|
|
320
|
+
if (recordId) {
|
|
321
|
+
// Read the record from the store.
|
|
322
|
+
const { reply: readReply } = await agent.dwn.processRequest({
|
|
323
|
+
author : tenantDid,
|
|
324
|
+
target : tenantDid,
|
|
325
|
+
messageType : DwnInterface.RecordsRead,
|
|
326
|
+
messageParams : { filter: { recordId } }
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
return readReply.entry;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export class InMemoryDataStore<TStoreObject extends Record<string, any> = Jwk> implements AgentDataStore<TStoreObject> {
|
|
335
|
+
protected name = 'InMemoryDataStore';
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* A private field that contains the Map used as the in-memory data store.
|
|
339
|
+
*/
|
|
340
|
+
private store: Map<string, TStoreObject> = new Map();
|
|
341
|
+
|
|
342
|
+
public async delete({ id, agent, tenant }: DataStoreDeleteParams): Promise<boolean> {
|
|
343
|
+
// Determine the tenant identifier (DID) for the delete operation.
|
|
344
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant, didUri: id });
|
|
345
|
+
|
|
346
|
+
if (this.store.has(`${tenantDid}${TENANT_SEPARATOR}${id}`)) {
|
|
347
|
+
// Record with given identifier exists so proceed with delete.
|
|
348
|
+
this.store.delete(`${tenantDid}${TENANT_SEPARATOR}${id}`);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Record with given identifier not present so delete operation not possible.
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
public async get({ id, agent, tenant }: DataStoreGetParams): Promise<TStoreObject | undefined> {
|
|
357
|
+
// Determine the tenant identifier (DID) for the get operation.
|
|
358
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant, didUri: id });
|
|
359
|
+
|
|
360
|
+
return this.store.get(`${tenantDid}${TENANT_SEPARATOR}${id}`);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
public async list({ agent, tenant}: DataStoreListParams): Promise<TStoreObject[]> {
|
|
364
|
+
// Determine the tenant identifier (DID) for the list operation.
|
|
365
|
+
const tenantDid = await getDataStoreTenant({ tenant, agent });
|
|
366
|
+
|
|
367
|
+
const result: TStoreObject[] = [];
|
|
368
|
+
for (const [key, storedRecord] of this.store.entries()) {
|
|
369
|
+
if (key.startsWith(`${tenantDid}${TENANT_SEPARATOR}`)) {
|
|
370
|
+
result.push(storedRecord);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
public async set({ id, data, tenant, agent, preventDuplicates, updateExisting }: DataStoreSetParams<TStoreObject>): Promise<void> {
|
|
378
|
+
// Determine the tenant identifier (DID) for the set operation.
|
|
379
|
+
const tenantDid = await getDataStoreTenant({ agent, tenant, didUri: id });
|
|
380
|
+
|
|
381
|
+
// If enabled, check if a record with the given `id` is already present in the store.
|
|
382
|
+
if (updateExisting) {
|
|
383
|
+
// Look up the DWN record ID of the object in the store with the given `id`.
|
|
384
|
+
if (!this.store.has(`${tenantDid}${TENANT_SEPARATOR}${id}`)) {
|
|
385
|
+
throw new Error(`${this.name}: Update failed due to missing entry for: ${id}`);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// set the recordId in the messageParams to update the existing record
|
|
389
|
+
} else if (preventDuplicates) {
|
|
390
|
+
const duplicateFound = this.store.has(`${tenantDid}${TENANT_SEPARATOR}${id}`);
|
|
391
|
+
if (duplicateFound) {
|
|
392
|
+
throw new Error(`${this.name}: Import failed due to duplicate entry for: ${id}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Make a deep copy so that the object stored does not share the same references as the input.
|
|
397
|
+
const clonedData = structuredClone(data);
|
|
398
|
+
this.store.set(`${tenantDid}${TENANT_SEPARATOR}${id}`, clonedData);
|
|
399
|
+
}
|
|
400
|
+
}
|
package/src/store-did.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { PortableDid } from '@enbox/dids';
|
|
2
|
+
|
|
3
|
+
import { Convert } from '@enbox/common';
|
|
4
|
+
|
|
5
|
+
import type { Web5PlatformAgent } from './types/agent.js';
|
|
6
|
+
import type { AgentDataStore, DataStoreDeleteParams, DataStoreGetParams, DataStoreListParams, DataStoreSetParams } from './store-data.js';
|
|
7
|
+
|
|
8
|
+
import { DwnInterface } from './types/dwn.js';
|
|
9
|
+
import { IdentityProtocolDefinition } from './store-data-protocols.js';
|
|
10
|
+
import { isPortableDid } from './prototyping/dids/utils.js';
|
|
11
|
+
import { TENANT_SEPARATOR } from './utils-internal.js';
|
|
12
|
+
import { DwnDataStore, InMemoryDataStore } from './store-data.js';
|
|
13
|
+
|
|
14
|
+
export class DwnDidStore extends DwnDataStore<PortableDid> implements AgentDataStore<PortableDid> {
|
|
15
|
+
protected name = 'DwnDidStore';
|
|
16
|
+
|
|
17
|
+
protected _recordProtocolDefinition = IdentityProtocolDefinition;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Properties to use when writing and querying DID records with the DWN store.
|
|
21
|
+
*/
|
|
22
|
+
protected _recordProperties = {
|
|
23
|
+
dataFormat : 'application/json',
|
|
24
|
+
protocol : this._recordProtocolDefinition.protocol,
|
|
25
|
+
protocolPath : 'portableDid',
|
|
26
|
+
schema : this._recordProtocolDefinition.types.portableDid.schema,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
public async delete(params: DataStoreDeleteParams): Promise<boolean> {
|
|
30
|
+
return await super.delete(params);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async get(params: DataStoreGetParams): Promise<PortableDid | undefined> {
|
|
34
|
+
return await super.get(params);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public async list(params: DataStoreListParams): Promise<PortableDid[]> {
|
|
38
|
+
return await super.list(params);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public async set(params: DataStoreSetParams<PortableDid>): Promise<void> {
|
|
42
|
+
return await super.set(params);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected async getAllRecords({ agent, tenantDid }: {
|
|
46
|
+
agent: Web5PlatformAgent;
|
|
47
|
+
tenantDid: string;
|
|
48
|
+
}): Promise<PortableDid[]> {
|
|
49
|
+
// Clear the index since it will be rebuilt from the query results.
|
|
50
|
+
this._index.clear();
|
|
51
|
+
|
|
52
|
+
// Query the DWN for all stored PortableDid objects.
|
|
53
|
+
const { reply: queryReply } = await agent.dwn.processRequest({
|
|
54
|
+
author : tenantDid,
|
|
55
|
+
target : tenantDid,
|
|
56
|
+
messageType : DwnInterface.RecordsQuery,
|
|
57
|
+
messageParams : { filter: { ...this._recordProperties } }
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Loop through all of the stored DID records and accumulate the DID objects.
|
|
61
|
+
let storedDids: PortableDid[] = [];
|
|
62
|
+
for (const record of queryReply.entries ?? []) {
|
|
63
|
+
// All DID records are expected to be small enough such that the data is returned with the
|
|
64
|
+
// query results. If a record is returned without `encodedData` this is unexpected so throw
|
|
65
|
+
// an error.
|
|
66
|
+
if (!record.encodedData) {
|
|
67
|
+
throw new Error(`${this.name}: Expected 'encodedData' to be present in the DWN query result entry`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const storedDid = Convert.base64Url(record.encodedData).toObject() as PortableDid;
|
|
71
|
+
if (isPortableDid(storedDid)) {
|
|
72
|
+
// Update the index with the matching record ID.
|
|
73
|
+
const indexKey = `${tenantDid}${TENANT_SEPARATOR}${storedDid.uri}`;
|
|
74
|
+
this._index.set(indexKey, record.recordId);
|
|
75
|
+
|
|
76
|
+
// Add the stored DID to the cache.
|
|
77
|
+
this._cache.set(record.recordId, storedDid);
|
|
78
|
+
|
|
79
|
+
storedDids.push(storedDid);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return storedDids;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export class InMemoryDidStore extends InMemoryDataStore<PortableDid> implements AgentDataStore<PortableDid> {
|
|
88
|
+
protected name = 'InMemoryDidStore';
|
|
89
|
+
|
|
90
|
+
public async delete(params: DataStoreDeleteParams): Promise<boolean> {
|
|
91
|
+
return await super.delete(params);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async get(params: DataStoreGetParams): Promise<PortableDid | undefined> {
|
|
95
|
+
return await super.get(params);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public async list(params: DataStoreListParams): Promise<PortableDid[]> {
|
|
99
|
+
return await super.list(params);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public async set(params: DataStoreSetParams<PortableDid>): Promise<void> {
|
|
103
|
+
return await super.set(params);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Convert } from '@enbox/common';
|
|
2
|
+
|
|
3
|
+
import type { Web5PlatformAgent } from './types/agent.js';
|
|
4
|
+
import type { IdentityMetadata } from './types/identity.js';
|
|
5
|
+
import type { AgentDataStore, DataStoreDeleteParams, DataStoreGetParams, DataStoreListParams, DataStoreSetParams } from './store-data.js';
|
|
6
|
+
|
|
7
|
+
import { DwnInterface } from './types/dwn.js';
|
|
8
|
+
import { IdentityProtocolDefinition } from './store-data-protocols.js';
|
|
9
|
+
import { TENANT_SEPARATOR } from './utils-internal.js';
|
|
10
|
+
import { DwnDataStore, InMemoryDataStore } from './store-data.js';
|
|
11
|
+
|
|
12
|
+
export function isIdentityMetadata(obj: unknown): obj is IdentityMetadata {
|
|
13
|
+
// Validate that the given value is an object that has the necessary properties of IdentityMetadata.
|
|
14
|
+
return !(!obj || typeof obj !== 'object' || obj === null)
|
|
15
|
+
&& 'name' in obj;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class DwnIdentityStore extends DwnDataStore<IdentityMetadata> implements AgentDataStore<IdentityMetadata> {
|
|
19
|
+
protected name = 'DwnIdentityStore';
|
|
20
|
+
|
|
21
|
+
protected _recordProtocolDefinition = IdentityProtocolDefinition;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Properties to use when writing and querying Identity records with the DWN store.
|
|
25
|
+
*/
|
|
26
|
+
protected _recordProperties = {
|
|
27
|
+
dataFormat : 'application/json',
|
|
28
|
+
protocol : this._recordProtocolDefinition.protocol,
|
|
29
|
+
protocolPath : 'identityMetadata',
|
|
30
|
+
schema : this._recordProtocolDefinition.types.identityMetadata.schema,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
public async delete(params: DataStoreDeleteParams): Promise<boolean> {
|
|
34
|
+
return await super.delete(params);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public async get(params: DataStoreGetParams): Promise<IdentityMetadata | undefined> {
|
|
38
|
+
return await super.get(params);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public async set(params: DataStoreSetParams<IdentityMetadata>): Promise<void> {
|
|
42
|
+
return await super.set(params);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public async list(params: DataStoreListParams): Promise<IdentityMetadata[]> {
|
|
46
|
+
return await super.list(params);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected async getAllRecords({ agent, tenantDid }: {
|
|
50
|
+
agent: Web5PlatformAgent;
|
|
51
|
+
tenantDid: string;
|
|
52
|
+
}): Promise<IdentityMetadata[]> {
|
|
53
|
+
// Clear the index since it will be rebuilt from the query results.
|
|
54
|
+
this._index.clear();
|
|
55
|
+
|
|
56
|
+
// Query the DWN for all stored IdentityMetadata objects.
|
|
57
|
+
const { reply: queryReply } = await agent.dwn.processRequest({
|
|
58
|
+
author : tenantDid,
|
|
59
|
+
target : tenantDid,
|
|
60
|
+
messageType : DwnInterface.RecordsQuery,
|
|
61
|
+
messageParams : { filter: { ...this._recordProperties } }
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Loop through all of the stored IdentityMetadata records and accumulate the objects.
|
|
65
|
+
let storedIdentities: IdentityMetadata[] = [];
|
|
66
|
+
for (const record of queryReply.entries ?? []) {
|
|
67
|
+
// All IdentityMetadata records are expected to be small enough such that the data is returned
|
|
68
|
+
// with the query results. If a record is returned without `encodedData` this is unexpected so
|
|
69
|
+
// throw an error.
|
|
70
|
+
if (!record.encodedData) {
|
|
71
|
+
throw new Error(`${this.name}: Expected 'encodedData' to be present in the DWN query result entry`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const storedIdentity = Convert.base64Url(record.encodedData).toObject() as IdentityMetadata;
|
|
75
|
+
if (isIdentityMetadata(storedIdentity)) {
|
|
76
|
+
// Update the index with the matching record ID.
|
|
77
|
+
const indexKey = `${tenantDid}${TENANT_SEPARATOR}${storedIdentity.uri}`;
|
|
78
|
+
this._index.set(indexKey, record.recordId);
|
|
79
|
+
|
|
80
|
+
// Add the stored Identity to the cache.
|
|
81
|
+
this._cache.set(record.recordId, storedIdentity);
|
|
82
|
+
|
|
83
|
+
storedIdentities.push(storedIdentity);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return storedIdentities;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export class InMemoryIdentityStore extends InMemoryDataStore<IdentityMetadata> implements AgentDataStore<IdentityMetadata> {
|
|
92
|
+
protected name = 'InMemoryIdentityStore';
|
|
93
|
+
|
|
94
|
+
public async delete(params: DataStoreDeleteParams): Promise<boolean> {
|
|
95
|
+
return await super.delete(params);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public async get(params: DataStoreGetParams): Promise<IdentityMetadata | undefined> {
|
|
99
|
+
return await super.get(params);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public async list(params: DataStoreListParams): Promise<IdentityMetadata[]> {
|
|
103
|
+
return await super.list(params);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public async set(params: DataStoreSetParams<IdentityMetadata>): Promise<void> {
|
|
107
|
+
return await super.set(params);
|
|
108
|
+
}
|
|
109
|
+
}
|