@keetanetwork/anchor 0.0.41 → 0.0.42

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@keetanetwork/anchor",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@keetanetwork/anchor",
9
- "version": "0.0.41",
9
+ "version": "0.0.42",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "dependencies": {
12
12
  "@keetanetwork/currency-info": "1.2.5",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keetanetwork/anchor",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "KeetaNetwork Network Anchor",
5
5
  "main": "client/index.js",
6
6
  "scripts": {
@@ -1 +1 @@
1
- {"version":3,"file":"contacts.d.ts","sourceRoot":"","sources":["../../../../src/services/storage/clients/contacts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contacts.d.ts","sourceRoot":"","sources":["../../../../src/services/storage/clients/contacts.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
+ import { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';
1
2
  import { convertAssetLocationToString } from '../../asset-movement/lib/location.js';
2
- import { hash } from '../../../lib/utils/tests/hash.js';
3
3
  import { Errors } from '../common.js';
4
4
  import { Buffer } from '../../../lib/utils/buffer.js';
5
5
  import { assertContact } from './contacts.generated.js';
@@ -63,7 +63,10 @@ export class StorageContactsClient {
63
63
  this.#session = session;
64
64
  }
65
65
  deriveId(address) {
66
- return (hash(canonicalizeContactAddress(address)));
66
+ const data = Buffer.from(canonicalizeContactAddress(address));
67
+ const hash = KeetaNetLib.Utils.Hash.Hash(data);
68
+ const result = Buffer.from(hash).toString('hex');
69
+ return (result);
67
70
  }
68
71
  #serialize(contact) {
69
72
  return (Buffer.from(JSON.stringify(contact)));
@@ -1 +1 @@
1
- {"version":3,"file":"contacts.js","sourceRoot":"","sources":["../../../../src/services/storage/clients/contacts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,IAAI,EAAE,MAAM,kCAAkC,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAmGxD,aAAa;AAEb,iCAAiC;AAEjC;;GAEG;AACH,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAErC;;;;;;;GAOG;AACH,SAAS,0BAA0B,CAAC,OAAuB;IAC1D,MAAM,EAAE,mBAAmB,EAAE,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC,CAAC,wDAAwD;IACvI,OAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAS,IAAY,EAAE,KAAc;QACpE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1E,yEAAyE;YACzE,MAAM,GAAG,GAAG,KAAiC,CAAC;YAC9C,OAAM,CAAC,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAC1D,CAAC,CAAC;QACJ,CAAC;QAED,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,QAA2B;IACjD,MAAM,GAAG,GAAG,4BAA4B,CAAC,QAAQ,CAAC,CAAC;IAEnD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,OAAuB;IAC3C,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtB,OAAM,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAM,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IACxB,QAAQ,CAA4B;IAE7C,YAAY,OAAkC;QAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,QAAQ,CAAC,OAAuB;QAC/B,OAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,UAAU,CAAC,OAAgB;QAC1B,OAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,YAAY,CAAC,IAAY;QACxB,OAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAGZ;QACA,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAY;YACxB,EAAE;YACF,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO;SACxB,CAAC;QAEF,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;YACrD,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;SAClC,CAAC,CAAC;QAEH,OAAM,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAM,CAAC,IAAI,CAAC,CAAC;QACd,CAAC;QAED,OAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAGxB;QACA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAK,CAAC,IAAI,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAExC,MAAM,OAAO,GAAY;YACxB,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;YACtC,OAAO,EAAE,UAAU;SACnB,CAAC;QAEF,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;YACxD,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAClB,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACR,6CAA6C;YAC9C,CAAC;QACF,CAAC;QAED,OAAM,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACtB,OAAM,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAEV;QACA,MAAM,QAAQ,GAA4C;YACzD,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB;SAC1C,CAAC;QAEF,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE1D,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,QAAQ,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,MAAM,EAAE,CAAC;gBACZ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/C,CAAC;QACF,CAAC;QAED,OAAM,CAAC,QAAQ,CAAC,CAAC;IAClB,CAAC;CACD","sourcesContent":["import type { AssetTransferInstructions, RecipientResolved, KeetaNetAccount } from '../../asset-movement/common.js';\nimport type { AssetLocationLike, PickChainLocation } from '../../asset-movement/lib/location.js';\nimport type { KeetaStorageAnchorSession } from '../client.js';\nimport { convertAssetLocationToString } from '../../asset-movement/lib/location.js';\nimport { hash } from '../../../lib/utils/tests/hash.js';\nimport { Errors } from '../common.js';\nimport { Buffer } from '../../../lib/utils/buffer.js';\nimport { assertContact } from './contacts.generated.js';\n\n// #region Types\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\n/**\n * The structural shape of a transfer instruction, excluding transaction-specific fields.\n */\nexport type TransferInstructionShape = DistributiveOmit<\n\tAssetTransferInstructions,\n\t'value' | 'assetFee' | 'totalReceiveAmount' | 'persistentAddressId'\n>;\n\n/**\n * The type of provider information allowed for a contact address.\n */\nexport type ProviderInformationType = 'username' | 'template';\n\n/**\n * The type of recipient for a persistent address template.\n */\nexport type PersistentAddressTemplateRecipient = Extract<RecipientResolved, { type: 'persistent-address' }>;\n\n/**\n * Base interface for contact addresses with narrowed generic parameters.\n */\nexport interface ContactAddressBase<\n\tRecipientType extends RecipientResolved,\n\tLocation extends AssetLocationLike,\n\tProviderInformationAllowedTypes extends ProviderInformationType\n> {\n\trecipient: RecipientType;\n\tlocation?: Location;\n\tproviderInformation?: { [providerId: string]: ProviderInformationAllowedTypes[] };\n\tpastInstructions?: TransferInstructionShape[];\n}\n\nexport type KeetaAssetLocation = PickChainLocation<'keeta'> | `chain:keeta:${bigint}`;\n\n/**\n * A contact address for a Keeta account.\n */\nexport type KeetaContactAddress = ContactAddressBase<string, KeetaAssetLocation, 'username'>;\n\n/**\n * A contact address for a persistent address template.\n */\nexport type TemplateContactAddress = ContactAddressBase<PersistentAddressTemplateRecipient, AssetLocationLike, 'template'>;\n\n/**\n * A contact address for a non-Keeta, non-persistent-address recipient.\n */\nexport type OtherContactAddress = ContactAddressBase<\n\tExclude<RecipientResolved, KeetaNetAccount | PersistentAddressTemplateRecipient>,\n\tExclude<AssetLocationLike, KeetaAssetLocation>,\n\t'template'\n>;\n\nexport type ContactAddress = KeetaContactAddress | TemplateContactAddress | OtherContactAddress;\n\n/**\n * A stored contact with metadata and an address.\n */\nexport type Contact = {\n\tid: string;\n\tlabel: string;\n\taddress: ContactAddress;\n};\n\n// #endregion\n\n// #region Interface\n\n/**\n * Generic contacts client interface\n */\nexport interface ContactsClient {\n\tderiveId(address: ContactAddress): string;\n\n\tcreate(options: {\n\t\tlabel: string;\n\t\taddress: ContactAddress;\n\t}): Promise<Contact>;\n\n\tget(id: string): Promise<Contact | null>;\n\n\tupdate(id: string, options: {\n\t\tlabel?: string;\n\t\taddress?: ContactAddress;\n\t}): Promise<Contact>;\n\n\tdelete(id: string): Promise<boolean>;\n\n\tlist(options?: {\n\t\tlocation?: AssetLocationLike;\n\t}): Promise<Contact[]>;\n}\n\n// #endregion\n\n// #region Storage Implementation\n\n/**\n * MIME type for contact data.\n */\nconst MIME_TYPE = 'application/json';\n\n/**\n * Canonicalize a contact address for use in ID derivation.\n * Excludes metadata fields (`providerInformation`, `pastInstructions`) that are not part of contact identity.\n *\n * @param address - The contact address to canonicalize.\n *\n * @returns The canonicalized string representation of the contact address identity fields.\n */\nfunction canonicalizeContactAddress(address: ContactAddress): string {\n\tconst { providerInformation: _, pastInstructions: __, ...identity } = address; // eslint-disable-line @typescript-eslint/no-unused-vars\n\treturn(JSON.stringify(identity, function(_key: string, value: unknown): unknown {\n\t\tif (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tconst obj = value as { [k: string]: unknown };\n\t\t\treturn(Object.fromEntries(\n\t\t\t\tObject.entries(obj).sort(([a], [b]) => a.localeCompare(b))\n\t\t\t));\n\t\t}\n\n\t\treturn(value);\n\t}));\n}\n\n/**\n * Convert an asset location to a tag for use in storage.\n *\n * @param location - The asset location to convert to a tag.\n *\n * @returns The tag string.\n */\nfunction locationToTag(location: AssetLocationLike): string {\n\tconst str = convertAssetLocationToString(location);\n\n\tconst parts = str.split(':');\n\treturn(parts.join('-'));\n}\n\n/**\n * Convert a contact address to a list of tags for use in storage.\n *\n * @param address - The contact address to convert to tags.\n *\n * @returns The list of tags.\n */\nfunction contactTags(address: ContactAddress): string[] {\n\tif (address.location) {\n\t\treturn([locationToTag(address.location)]);\n\t}\n\n\treturn([]);\n}\n\n/**\n * Storage Anchor-backed implementation of `ContactsClient`.\n * Stores contacts as encrypted JSON objects via a `KeetaStorageAnchorSession`.\n */\nexport class StorageContactsClient implements ContactsClient {\n\treadonly #session: KeetaStorageAnchorSession;\n\n\tconstructor(session: KeetaStorageAnchorSession) {\n\t\tthis.#session = session;\n\t}\n\n\tderiveId(address: ContactAddress): string {\n\t\treturn(hash(canonicalizeContactAddress(address)));\n\t}\n\n\t#serialize(contact: Contact): Buffer {\n\t\treturn(Buffer.from(JSON.stringify(contact)));\n\t}\n\n\t#deserialize(data: Buffer): Contact {\n\t\treturn(assertContact(JSON.parse(data.toString())));\n\t}\n\n\tasync create(options: {\n\t\tlabel: string;\n\t\taddress: ContactAddress;\n\t}): Promise<Contact> {\n\t\tconst id = this.deriveId(options.address);\n\t\tconst contact: Contact = {\n\t\t\tid,\n\t\t\tlabel: options.label,\n\t\t\taddress: options.address\n\t\t};\n\n\t\tawait this.#session.put(id, this.#serialize(contact), {\n\t\t\tmimeType: MIME_TYPE,\n\t\t\ttags: contactTags(options.address)\n\t\t});\n\n\t\treturn(contact);\n\t}\n\n\tasync get(id: string): Promise<Contact | null> {\n\t\tconst result = await this.#session.get(id);\n\t\tif (!result) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn(this.#deserialize(result.data));\n\t}\n\n\tasync update(id: string, options: {\n\t\tlabel?: string;\n\t\taddress?: ContactAddress;\n\t}): Promise<Contact> {\n\t\tconst existing = await this.get(id);\n\t\tif (!existing) {\n\t\t\tthrow(new Errors.DocumentNotFound(`Contact not found: ${id}`));\n\t\t}\n\n\t\tconst newAddress = options.address ?? existing.address;\n\t\tconst newId = this.deriveId(newAddress);\n\n\t\tconst updated: Contact = {\n\t\t\tid: newId,\n\t\t\tlabel: options.label ?? existing.label,\n\t\t\taddress: newAddress\n\t\t};\n\n\t\tawait this.#session.put(newId, this.#serialize(updated), {\n\t\t\tmimeType: MIME_TYPE,\n\t\t\ttags: contactTags(updated.address)\n\t\t});\n\n\t\tif (newId !== id) {\n\t\t\ttry {\n\t\t\t\tawait this.#session.delete(id);\n\t\t\t} catch {\n\t\t\t\t// Put succeeded; old contact is now orphaned\n\t\t\t}\n\t\t}\n\n\t\treturn(updated);\n\t}\n\n\tasync delete(id: string): Promise<boolean> {\n\t\treturn(await this.#session.delete(id));\n\t}\n\n\tasync list(options?: {\n\t\tlocation?: AssetLocationLike;\n\t}): Promise<Contact[]> {\n\t\tconst criteria: { pathPrefix: string; tags?: string[] } = {\n\t\t\tpathPrefix: this.#session.workingDirectory\n\t\t};\n\n\t\tif (options?.location) {\n\t\t\tcriteria.tags = [locationToTag(options.location)];\n\t\t}\n\n\t\tconst searchResult = await this.#session.search(criteria);\n\n\t\tconst contacts: Contact[] = [];\n\t\tfor (const metadata of searchResult.results) {\n\t\t\tconst result = await this.#session.get(metadata.path);\n\t\t\tif (result) {\n\t\t\t\tcontacts.push(this.#deserialize(result.data));\n\t\t\t}\n\t\t}\n\n\t\treturn(contacts);\n\t}\n}\n\n// #endregion\n"]}
1
+ {"version":3,"file":"contacts.js","sourceRoot":"","sources":["../../../../src/services/storage/clients/contacts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssetTransferInstructions, RecipientResolved, KeetaNetAccount } from '../../asset-movement/common.js';\nimport type { AssetLocationLike, PickChainLocation } from '../../asset-movement/lib/location.js';\nimport type { KeetaStorageAnchorSession } from '../client.js';\nimport { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';\nimport { convertAssetLocationToString } from '../../asset-movement/lib/location.js';\nimport { Errors } from '../common.js';\nimport { Buffer } from '../../../lib/utils/buffer.js';\nimport { assertContact } from './contacts.generated.js';\n\n// #region Types\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\n/**\n * The structural shape of a transfer instruction, excluding transaction-specific fields.\n */\nexport type TransferInstructionShape = DistributiveOmit<\n\tAssetTransferInstructions,\n\t'value' | 'assetFee' | 'totalReceiveAmount' | 'persistentAddressId'\n>;\n\n/**\n * The type of provider information allowed for a contact address.\n */\nexport type ProviderInformationType = 'username' | 'template';\n\n/**\n * The type of recipient for a persistent address template.\n */\nexport type PersistentAddressTemplateRecipient = Extract<RecipientResolved, { type: 'persistent-address' }>;\n\n/**\n * Base interface for contact addresses with narrowed generic parameters.\n */\nexport interface ContactAddressBase<\n\tRecipientType extends RecipientResolved,\n\tLocation extends AssetLocationLike,\n\tProviderInformationAllowedTypes extends ProviderInformationType\n> {\n\trecipient: RecipientType;\n\tlocation?: Location;\n\tproviderInformation?: { [providerId: string]: ProviderInformationAllowedTypes[] };\n\tpastInstructions?: TransferInstructionShape[];\n}\n\nexport type KeetaAssetLocation = PickChainLocation<'keeta'> | `chain:keeta:${bigint}`;\n\n/**\n * A contact address for a Keeta account.\n */\nexport type KeetaContactAddress = ContactAddressBase<string, KeetaAssetLocation, 'username'>;\n\n/**\n * A contact address for a persistent address template.\n */\nexport type TemplateContactAddress = ContactAddressBase<PersistentAddressTemplateRecipient, AssetLocationLike, 'template'>;\n\n/**\n * A contact address for a non-Keeta, non-persistent-address recipient.\n */\nexport type OtherContactAddress = ContactAddressBase<\n\tExclude<RecipientResolved, KeetaNetAccount | PersistentAddressTemplateRecipient>,\n\tExclude<AssetLocationLike, KeetaAssetLocation>,\n\t'template'\n>;\n\nexport type ContactAddress = KeetaContactAddress | TemplateContactAddress | OtherContactAddress;\n\n/**\n * A stored contact with metadata and an address.\n */\nexport type Contact = {\n\tid: string;\n\tlabel: string;\n\taddress: ContactAddress;\n};\n\n// #endregion\n\n// #region Interface\n\n/**\n * Generic contacts client interface\n */\nexport interface ContactsClient {\n\tderiveId(address: ContactAddress): string;\n\n\tcreate(options: {\n\t\tlabel: string;\n\t\taddress: ContactAddress;\n\t}): Promise<Contact>;\n\n\tget(id: string): Promise<Contact | null>;\n\n\tupdate(id: string, options: {\n\t\tlabel?: string;\n\t\taddress?: ContactAddress;\n\t}): Promise<Contact>;\n\n\tdelete(id: string): Promise<boolean>;\n\n\tlist(options?: {\n\t\tlocation?: AssetLocationLike;\n\t}): Promise<Contact[]>;\n}\n\n// #endregion\n\n// #region Storage Implementation\n\n/**\n * MIME type for contact data.\n */\nconst MIME_TYPE = 'application/json';\n\n/**\n * Canonicalize a contact address for use in ID derivation.\n * Excludes metadata fields (`providerInformation`, `pastInstructions`) that are not part of contact identity.\n *\n * @param address - The contact address to canonicalize.\n *\n * @returns The canonicalized string representation of the contact address identity fields.\n */\nfunction canonicalizeContactAddress(address: ContactAddress): string {\n\tconst { providerInformation: _, pastInstructions: __, ...identity } = address; // eslint-disable-line @typescript-eslint/no-unused-vars\n\treturn(JSON.stringify(identity, function(_key: string, value: unknown): unknown {\n\t\tif (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tconst obj = value as { [k: string]: unknown };\n\t\t\treturn(Object.fromEntries(\n\t\t\t\tObject.entries(obj).sort(([a], [b]) => a.localeCompare(b))\n\t\t\t));\n\t\t}\n\n\t\treturn(value);\n\t}));\n}\n\n/**\n * Convert an asset location to a tag for use in storage.\n *\n * @param location - The asset location to convert to a tag.\n *\n * @returns The tag string.\n */\nfunction locationToTag(location: AssetLocationLike): string {\n\tconst str = convertAssetLocationToString(location);\n\n\tconst parts = str.split(':');\n\treturn(parts.join('-'));\n}\n\n/**\n * Convert a contact address to a list of tags for use in storage.\n *\n * @param address - The contact address to convert to tags.\n *\n * @returns The list of tags.\n */\nfunction contactTags(address: ContactAddress): string[] {\n\tif (address.location) {\n\t\treturn([locationToTag(address.location)]);\n\t}\n\n\treturn([]);\n}\n\n/**\n * Storage Anchor-backed implementation of `ContactsClient`.\n * Stores contacts as encrypted JSON objects via a `KeetaStorageAnchorSession`.\n */\nexport class StorageContactsClient implements ContactsClient {\n\treadonly #session: KeetaStorageAnchorSession;\n\n\tconstructor(session: KeetaStorageAnchorSession) {\n\t\tthis.#session = session;\n\t}\n\n\tderiveId(address: ContactAddress): string {\n\t\tconst data = Buffer.from(canonicalizeContactAddress(address));\n\t\tconst hash = KeetaNetLib.Utils.Hash.Hash(data);\n\n\t\tconst result = Buffer.from(hash).toString('hex');\n\t\treturn(result);\n\t}\n\n\t#serialize(contact: Contact): Buffer {\n\t\treturn(Buffer.from(JSON.stringify(contact)));\n\t}\n\n\t#deserialize(data: Buffer): Contact {\n\t\treturn(assertContact(JSON.parse(data.toString())));\n\t}\n\n\tasync create(options: {\n\t\tlabel: string;\n\t\taddress: ContactAddress;\n\t}): Promise<Contact> {\n\t\tconst id = this.deriveId(options.address);\n\t\tconst contact: Contact = {\n\t\t\tid,\n\t\t\tlabel: options.label,\n\t\t\taddress: options.address\n\t\t};\n\n\t\tawait this.#session.put(id, this.#serialize(contact), {\n\t\t\tmimeType: MIME_TYPE,\n\t\t\ttags: contactTags(options.address)\n\t\t});\n\n\t\treturn(contact);\n\t}\n\n\tasync get(id: string): Promise<Contact | null> {\n\t\tconst result = await this.#session.get(id);\n\t\tif (!result) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn(this.#deserialize(result.data));\n\t}\n\n\tasync update(id: string, options: {\n\t\tlabel?: string;\n\t\taddress?: ContactAddress;\n\t}): Promise<Contact> {\n\t\tconst existing = await this.get(id);\n\t\tif (!existing) {\n\t\t\tthrow(new Errors.DocumentNotFound(`Contact not found: ${id}`));\n\t\t}\n\n\t\tconst newAddress = options.address ?? existing.address;\n\t\tconst newId = this.deriveId(newAddress);\n\n\t\tconst updated: Contact = {\n\t\t\tid: newId,\n\t\t\tlabel: options.label ?? existing.label,\n\t\t\taddress: newAddress\n\t\t};\n\n\t\tawait this.#session.put(newId, this.#serialize(updated), {\n\t\t\tmimeType: MIME_TYPE,\n\t\t\ttags: contactTags(updated.address)\n\t\t});\n\n\t\tif (newId !== id) {\n\t\t\ttry {\n\t\t\t\tawait this.#session.delete(id);\n\t\t\t} catch {\n\t\t\t\t// Put succeeded; old contact is now orphaned\n\t\t\t}\n\t\t}\n\n\t\treturn(updated);\n\t}\n\n\tasync delete(id: string): Promise<boolean> {\n\t\treturn(await this.#session.delete(id));\n\t}\n\n\tasync list(options?: {\n\t\tlocation?: AssetLocationLike;\n\t}): Promise<Contact[]> {\n\t\tconst criteria: { pathPrefix: string; tags?: string[] } = {\n\t\t\tpathPrefix: this.#session.workingDirectory\n\t\t};\n\n\t\tif (options?.location) {\n\t\t\tcriteria.tags = [locationToTag(options.location)];\n\t\t}\n\n\t\tconst searchResult = await this.#session.search(criteria);\n\n\t\tconst contacts: Contact[] = [];\n\t\tfor (const metadata of searchResult.results) {\n\t\t\tconst result = await this.#session.get(metadata.path);\n\t\t\tif (result) {\n\t\t\t\tcontacts.push(this.#deserialize(result.data));\n\t\t\t}\n\t\t}\n\n\t\treturn(contacts);\n\t}\n}\n\n// #endregion\n"]}