{"version":3,"file":"getSubdomains.mjs","sources":["../../../src/domain/getSubdomains.ts"],"sourcesContent":["import {\r\n  Address,\r\n  Base58EncodedBytes,\r\n  GetProgramAccountsApi,\r\n  GetSlotApi,\r\n  Rpc,\r\n} from \"@solana/kit\";\r\n\r\nimport { addressCodec, base64Codec } from \"../codecs\";\r\nimport {\r\n  NAME_PROGRAM_ADDRESS,\r\n  REVERSE_LOOKUP_CLASS,\r\n} from \"../constants/addresses\";\r\nimport { assertTldSupported } from \"../utils/assertTldSupported\";\r\nimport { deserializeReverse } from \"../utils/deserializers/deserializeReverse\";\r\nimport { getReverseAddressFromDomainAddress } from \"../utils/getReverseAddressFromDomainAddress\";\r\nimport { getSnsDomainAddress } from \"./getSnsDomainAddress\";\r\n\r\n/**\r\n * Parameters for retrieving subdomains under a parent domain.\r\n *\r\n * @example\r\n * ```ts\r\n * const params: GetSubdomainsParams = {\r\n *   rpc,\r\n *   domain: \"example.sns\",\r\n * };\r\n * ```\r\n */\r\nexport interface GetSubdomainsParams {\r\n  /** RPC client. */\r\n  rpc: Rpc<GetProgramAccountsApi & GetSlotApi>;\r\n  /** Full parent domain name, including its `.sns` or `.sol` suffix. */\r\n  domain: string;\r\n}\r\n\r\n/**\r\n * A subdomain and the owner recorded in its name registry.\r\n *\r\n * @example\r\n * ```ts\r\n * const subdomain: GetSubdomainsResult = {\r\n *   subdomain: \"blog\",\r\n *   owner: \"Fxuoy3gFjfJALhwkRcuKjRdechcgffUApeYAfMWck6w8\" as Address,\r\n * };\r\n * ```\r\n */\r\nexport interface GetSubdomainsResult {\r\n  /** TLD-less label recorded by the subdomain's reverse lookup account. */\r\n  subdomain: string;\r\n  /** Owner address stored in the subdomain's name registry account. */\r\n  owner: Address;\r\n}\r\n\r\n/**\r\n * Retrieves subdomains under a parent domain, including their owners.\r\n *\r\n * Entries without reverse lookup data are omitted. Passing a subdomain returns\r\n * an empty array.\r\n *\r\n * @param params Subdomain retrieval parameters\r\n * @param params.rpc RPC client implementing program account lookup\r\n * @param params.domain Full parent domain name including a `.sns` or `.sol` suffix\r\n * @returns Subdomain names and owner addresses.\r\n *\r\n * @example\r\n * ```ts\r\n * const subdomains = await getSubdomains({ rpc, domain: \"example.sns\" });\r\n * ```\r\n */\r\nexport const getSubdomains = async ({\r\n  rpc,\r\n  domain,\r\n}: GetSubdomainsParams): Promise<GetSubdomainsResult[]> => {\r\n  const [trimmedDomain] = await assertTldSupported({ rpc, domain });\r\n  const { domainAddress, isSub } = await getSnsDomainAddress({\r\n    domain: trimmedDomain,\r\n  });\r\n\r\n  if (isSub) return [];\r\n\r\n  const getReversesAsync = rpc\r\n    .getProgramAccounts(NAME_PROGRAM_ADDRESS, {\r\n      encoding: \"base64\",\r\n      filters: [\r\n        {\r\n          memcmp: {\r\n            offset: 0n,\r\n            bytes: domainAddress as string as Base58EncodedBytes,\r\n            encoding: \"base58\",\r\n          },\r\n        },\r\n        {\r\n          memcmp: {\r\n            offset: 64n,\r\n            bytes: REVERSE_LOOKUP_CLASS as string as Base58EncodedBytes,\r\n            encoding: \"base58\",\r\n          },\r\n        },\r\n      ],\r\n    })\r\n    .send();\r\n\r\n  const getSubsAsync = rpc\r\n    .getProgramAccounts(NAME_PROGRAM_ADDRESS, {\r\n      encoding: \"base64\",\r\n      filters: [\r\n        {\r\n          memcmp: {\r\n            offset: 0n,\r\n            bytes: domainAddress as string as Base58EncodedBytes,\r\n            encoding: \"base58\",\r\n          },\r\n        },\r\n      ],\r\n      dataSlice: { offset: 32, length: 32 },\r\n    })\r\n    .send();\r\n\r\n  const [reverses, subs] = await Promise.all([getReversesAsync, getSubsAsync]);\r\n\r\n  const map = new Map<string, string | undefined>(\r\n    reverses.map((e) => [\r\n      e.pubkey,\r\n      deserializeReverse({\r\n        data: base64Codec.encode(e.account.data[0]).slice(96),\r\n        trimFirstNullByte: true,\r\n      }),\r\n    ])\r\n  );\r\n\r\n  const result = await Promise.all(\r\n    subs.map((sub) =>\r\n      getReverseAddressFromDomainAddress({\r\n        domainAddress: sub.pubkey,\r\n        parentAddress: domainAddress,\r\n      }).then((revKey) => {\r\n        const subdomain = map.get(revKey);\r\n        return subdomain\r\n          ? {\r\n              subdomain,\r\n              owner: addressCodec.decode(\r\n                base64Codec.encode(sub.account.data[0])\r\n              ),\r\n            }\r\n          : undefined;\r\n      })\r\n    )\r\n  );\r\n\r\n  const filteredResult = result.filter((sub) => sub !== undefined);\r\n\r\n  return filteredResult;\r\n};\r\n"],"names":[],"mappings":";;;;;;;AAsDA;;;;;;;;;;;;;;;AAeG;AACI,MAAM,aAAa,GAAG,OAAO,EAClC,GAAG,EACH,MAAM,GACc,KAAoC;AACxD,IAAA,MAAM,CAAC,aAAa,CAAC,GAAG,MAAM,kBAAkB,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACjE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAmB,CAAC;AACzD,QAAA,MAAM,EAAE,aAAa;AACtB,KAAA,CAAC;AAEF,IAAA,IAAI,KAAK;AAAE,QAAA,OAAO,EAAE;IAEpB,MAAM,gBAAgB,GAAG;SACtB,kBAAkB,CAAC,oBAAoB,EAAE;AACxC,QAAA,QAAQ,EAAE,QAAQ;AAClB,QAAA,OAAO,EAAE;AACP,YAAA;AACE,gBAAA,MAAM,EAAE;AACN,oBAAA,MAAM,EAAE,EAAE;AACV,oBAAA,KAAK,EAAE,aAA6C;AACpD,oBAAA,QAAQ,EAAE,QAAQ;AACnB,iBAAA;AACF,aAAA;AACD,YAAA;AACE,gBAAA,MAAM,EAAE;AACN,oBAAA,MAAM,EAAE,GAAG;AACX,oBAAA,KAAK,EAAE,oBAAoD;AAC3D,oBAAA,QAAQ,EAAE,QAAQ;AACnB,iBAAA;AACF,aAAA;AACF,SAAA;KACF;AACA,SAAA,IAAI,EAAE;IAET,MAAM,YAAY,GAAG;SAClB,kBAAkB,CAAC,oBAAoB,EAAE;AACxC,QAAA,QAAQ,EAAE,QAAQ;AAClB,QAAA,OAAO,EAAE;AACP,YAAA;AACE,gBAAA,MAAM,EAAE;AACN,oBAAA,MAAM,EAAE,EAAE;AACV,oBAAA,KAAK,EAAE,aAA6C;AACpD,oBAAA,QAAQ,EAAE,QAAQ;AACnB,iBAAA;AACF,aAAA;AACF,SAAA;QACD,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;KACtC;AACA,SAAA,IAAI,EAAE;AAET,IAAA,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;AAE5E,IAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;AAClB,QAAA,CAAC,CAAC,MAAM;AACR,QAAA,kBAAkB,CAAC;AACjB,YAAA,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;AACrD,YAAA,iBAAiB,EAAE,IAAI;SACxB,CAAC;AACH,KAAA,CAAC,CACH;AAED,IAAA,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KACX,kCAAkC,CAAC;QACjC,aAAa,EAAE,GAAG,CAAC,MAAM;AACzB,QAAA,aAAa,EAAE,aAAa;AAC7B,KAAA,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAI;QACjB,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;AACjC,QAAA,OAAO;AACL,cAAE;gBACE,SAAS;AACT,gBAAA,KAAK,EAAE,YAAY,CAAC,MAAM,CACxB,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CACxC;AACF;cACD,SAAS;KACd,CAAC,CACH,CACF;AAED,IAAA,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,SAAS,CAAC;AAEhE,IAAA,OAAO,cAAc;AACvB;;;;"}