@midnames/sdk 1.0.5 → 2.0.0-rc1

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.
Files changed (142) hide show
  1. package/README.md +4 -43
  2. package/dist/contract.d.ts +5 -0
  3. package/dist/contract.js +5 -0
  4. package/dist/core.d.ts +27 -9
  5. package/dist/core.js +196 -233
  6. package/dist/errors.d.ts +0 -3
  7. package/dist/errors.js +9 -17
  8. package/dist/holographic-card.css +1 -1
  9. package/dist/index.d.ts +10 -10
  10. package/dist/index.js +15 -11
  11. package/{node_modules/@midnames/ns/dist/managed/leaf → dist/managed}/compiler/contract-info.json +298 -232
  12. package/dist/managed/contract/index.d.ts +237 -0
  13. package/{node_modules/@midnames/ns/dist/managed/leaf → dist/managed}/contract/index.js +2044 -1713
  14. package/dist/managed/keys/add_domain_field.prover +0 -0
  15. package/dist/managed/keys/add_multiple_fields.prover +0 -0
  16. package/dist/managed/keys/change_field_limit.prover +0 -0
  17. package/dist/managed/keys/change_root_enable_subdomains.prover +0 -0
  18. package/dist/managed/keys/clear_domain_fields.prover +0 -0
  19. package/dist/managed/keys/create_domain.prover +0 -0
  20. package/dist/managed/keys/lock_payment_config.prover +0 -0
  21. package/dist/managed/keys/lock_target.prover +0 -0
  22. package/dist/managed/keys/remove_domain_field.prover +0 -0
  23. package/dist/managed/keys/transfer_domain.prover +0 -0
  24. package/dist/managed/keys/update_domain_default_field.prover +0 -0
  25. package/dist/managed/keys/update_payment_config.prover +0 -0
  26. package/dist/managed/keys/update_target.prover +0 -0
  27. package/dist/operations.d.ts +32 -20
  28. package/dist/operations.js +86 -103
  29. package/dist/provider.d.ts +6 -7
  30. package/dist/provider.js +11 -7
  31. package/dist/react/DomainProfileWidget.d.ts +1 -1
  32. package/dist/react/DomainProfileWidget.js +14 -36
  33. package/dist/react/HolographicCard.d.ts +1 -17
  34. package/dist/react/HolographicCard.js +1 -6
  35. package/dist/results.d.ts +0 -25
  36. package/dist/results.js +2 -75
  37. package/dist/styles.css +0 -1
  38. package/dist/types.d.ts +19 -4
  39. package/dist/types.js +1 -2
  40. package/dist/utils/address.d.ts +6 -1
  41. package/dist/utils/address.js +23 -6
  42. package/dist/utils/domain.d.ts +0 -4
  43. package/dist/utils/domain.js +15 -40
  44. package/dist/utils/sanitize.js +0 -4
  45. package/dist/witnesses.d.ts +8 -0
  46. package/dist/witnesses.js +6 -0
  47. package/package.json +45 -83
  48. package/dist/controller-types.d.ts +0 -108
  49. package/dist/controller-types.js +0 -17
  50. package/dist/controller-types.js.map +0 -1
  51. package/dist/core.js.map +0 -1
  52. package/dist/errors.js.map +0 -1
  53. package/dist/index.js.map +0 -1
  54. package/dist/operations.js.map +0 -1
  55. package/dist/provider.js.map +0 -1
  56. package/dist/react/DomainProfileWidget/index.d.ts +0 -2
  57. package/dist/react/DomainProfileWidget/index.js +0 -2
  58. package/dist/react/DomainProfileWidget/index.js.map +0 -1
  59. package/dist/react/DomainProfileWidget.js.map +0 -1
  60. package/dist/react/HolographicCard/index.d.ts +0 -3
  61. package/dist/react/HolographicCard/index.js +0 -3
  62. package/dist/react/HolographicCard/index.js.map +0 -1
  63. package/dist/react/HolographicCard.js.map +0 -1
  64. package/dist/react/index.d.ts +0 -3
  65. package/dist/react/index.js +0 -3
  66. package/dist/react/index.js.map +0 -1
  67. package/dist/results.js.map +0 -1
  68. package/dist/types.js.map +0 -1
  69. package/dist/utils/address.js.map +0 -1
  70. package/dist/utils/domain.js.map +0 -1
  71. package/dist/utils/imageResolver.d.ts +0 -8
  72. package/dist/utils/imageResolver.js +0 -90
  73. package/dist/utils/imageResolver.js.map +0 -1
  74. package/dist/utils/index.d.ts +0 -2
  75. package/dist/utils/index.js +0 -3
  76. package/dist/utils/index.js.map +0 -1
  77. package/dist/utils/sanitize.js.map +0 -1
  78. package/node_modules/@midnames/ns/dist/index.d.ts +0 -5
  79. package/node_modules/@midnames/ns/dist/index.js +0 -6
  80. package/node_modules/@midnames/ns/dist/index.js.map +0 -1
  81. package/node_modules/@midnames/ns/dist/leaf.compact +0 -290
  82. package/node_modules/@midnames/ns/dist/managed/leaf/contract/index.d.ts +0 -197
  83. package/node_modules/@midnames/ns/dist/managed/leaf/contract/index.js.map +0 -8
  84. package/node_modules/@midnames/ns/dist/managed/leaf/keys/add_multiple_fields.prover +0 -0
  85. package/node_modules/@midnames/ns/dist/managed/leaf/keys/add_multiple_fields.verifier +0 -0
  86. package/node_modules/@midnames/ns/dist/managed/leaf/keys/buy_domain_for.prover +0 -0
  87. package/node_modules/@midnames/ns/dist/managed/leaf/keys/buy_domain_for.verifier +0 -0
  88. package/node_modules/@midnames/ns/dist/managed/leaf/keys/change_owner.prover +0 -0
  89. package/node_modules/@midnames/ns/dist/managed/leaf/keys/change_owner.verifier +0 -0
  90. package/node_modules/@midnames/ns/dist/managed/leaf/keys/clear_all_fields.prover +0 -0
  91. package/node_modules/@midnames/ns/dist/managed/leaf/keys/clear_all_fields.verifier +0 -0
  92. package/node_modules/@midnames/ns/dist/managed/leaf/keys/clear_field.prover +0 -0
  93. package/node_modules/@midnames/ns/dist/managed/leaf/keys/clear_field.verifier +0 -0
  94. package/node_modules/@midnames/ns/dist/managed/leaf/keys/insert_field.prover +0 -0
  95. package/node_modules/@midnames/ns/dist/managed/leaf/keys/insert_field.verifier +0 -0
  96. package/node_modules/@midnames/ns/dist/managed/leaf/keys/register_domain_for.prover +0 -0
  97. package/node_modules/@midnames/ns/dist/managed/leaf/keys/register_domain_for.verifier +0 -0
  98. package/node_modules/@midnames/ns/dist/managed/leaf/keys/set_resolver.prover +0 -0
  99. package/node_modules/@midnames/ns/dist/managed/leaf/keys/set_resolver.verifier +0 -0
  100. package/node_modules/@midnames/ns/dist/managed/leaf/keys/transfer_domain.prover +0 -0
  101. package/node_modules/@midnames/ns/dist/managed/leaf/keys/transfer_domain.verifier +0 -0
  102. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_color.prover +0 -0
  103. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_color.verifier +0 -0
  104. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_costs.prover +0 -0
  105. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_costs.verifier +0 -0
  106. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_domain_target.prover +0 -0
  107. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_domain_target.verifier +0 -0
  108. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_target_and_fields.prover +0 -0
  109. package/node_modules/@midnames/ns/dist/managed/leaf/keys/update_target_and_fields.verifier +0 -0
  110. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/add_multiple_fields.bzkir +0 -0
  111. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/add_multiple_fields.zkir +0 -424
  112. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/buy_domain_for.bzkir +0 -0
  113. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/buy_domain_for.zkir +0 -1456
  114. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/change_owner.bzkir +0 -0
  115. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/change_owner.zkir +0 -57
  116. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/clear_all_fields.bzkir +0 -0
  117. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/clear_all_fields.zkir +0 -53
  118. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/clear_field.bzkir +0 -0
  119. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/clear_field.zkir +0 -58
  120. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/insert_field.bzkir +0 -0
  121. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/insert_field.zkir +0 -65
  122. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/register_domain_for.bzkir +0 -0
  123. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/register_domain_for.zkir +0 -401
  124. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/set_resolver.bzkir +0 -0
  125. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/set_resolver.zkir +0 -109
  126. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/transfer_domain.bzkir +0 -0
  127. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/transfer_domain.zkir +0 -212
  128. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_color.bzkir +0 -0
  129. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_color.zkir +0 -58
  130. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_costs.bzkir +0 -0
  131. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_costs.zkir +0 -88
  132. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_domain_target.bzkir +0 -0
  133. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_domain_target.zkir +0 -66
  134. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_target_and_fields.bzkir +0 -0
  135. package/node_modules/@midnames/ns/dist/managed/leaf/zkir/update_target_and_fields.zkir +0 -450
  136. package/node_modules/@midnames/ns/dist/utils.d.ts +0 -5
  137. package/node_modules/@midnames/ns/dist/utils.js +0 -19
  138. package/node_modules/@midnames/ns/dist/utils.js.map +0 -1
  139. package/node_modules/@midnames/ns/dist/witnesses.d.ts +0 -4
  140. package/node_modules/@midnames/ns/dist/witnesses.js +0 -3
  141. package/node_modules/@midnames/ns/dist/witnesses.js.map +0 -1
  142. package/node_modules/@midnames/ns/package.json +0 -55
package/README.md CHANGED
@@ -1,46 +1,7 @@
1
- ># @midnames/sdk
1
+ # Midnames SDK
2
2
 
3
- SDK to resolve Midnames domains, and render a profile widget.
3
+ This project integrates with the Midnight Network.
4
4
 
5
- ## Build
6
-
7
- Run the `build` script with `npm`, `bun`, etc.
8
-
9
- ## Usage
10
-
11
- Resolve a domain:
12
-
13
- ```ts
14
- import { resolveDomain, getDomainProfile } from '@midnames/sdk';
15
- import type { PublicDataProvider } from '@midnight-ntwrk/midnight-js-types';
16
-
17
- async function demo(provider: PublicDataProvider) {
18
- const target = await resolveDomain(provider, 'alice.night');
19
- const profile = await getDomainProfile(provider, 'id.alice.night');
20
- console.log(target, profile.fields);
21
- }
22
- ```
23
-
24
- React widget:
25
-
26
- ```tsx
27
- import '@midnames/sdk/styles.css';
28
- import { DomainProfileWidget } from '@midnames/sdk/react';
29
-
30
- <DomainProfileWidget fullDomain="id.alice.night" publicDataProvider={provider} />
31
- ```
32
-
33
- Fields recognized for display: `name`, `bio`, `avatar`, `banner`, `website`, `twitter`, `github`, `location`, and `epk`.
34
-
35
- ## API
36
-
37
- - `resolveDomain(provider, domain): Promise<string|null>`
38
- - `getDomainProfile(provider, fullDomain): Promise<{ fullDomain, resolvedTarget, info, fields, settings }>`
39
-
40
- ```ts
41
- export interface DomainInfo { owner: string; resolver: string; contractAddress?: string; }
42
- export interface DomainSettings { coinColor: Uint8Array; costs: { short: bigint; medium: bigint; long: bigint }; }
43
- ```
44
-
45
- Notes: Uses TestNet TLD contract by default. Provide a custom TLD address in `resolveDomain` if needed.
5
+ Get your `name.night` and use it instead of your wallet address. Save your profile info, integrate with dApps, and share!
46
6
 
7
+ You can find the docs [here](https://docs.midnight.domains)
@@ -0,0 +1,5 @@
1
+ export * as NS from "./managed/contract/index.js";
2
+ export { type DomainData, type DomainReference, type Maybe, type PaymentConfig, type Witnesses, type Ledger, AddressType, ledger, Contract, } from "./managed/contract/index.js";
3
+ export { domainToKey, keyToDomain } from "./utils/domain.js";
4
+ export { witnesses, type DNSPrivateState } from "./witnesses.js";
5
+ export declare const MANAGED_DIR: string;
@@ -0,0 +1,5 @@
1
+ export * as NS from "./managed/contract/index.js";
2
+ export { AddressType, ledger, Contract, } from "./managed/contract/index.js";
3
+ export { domainToKey, keyToDomain } from "./utils/domain.js";
4
+ export { witnesses } from "./witnesses.js";
5
+ export const MANAGED_DIR = new URL("./managed", import.meta.url).href;
package/dist/core.d.ts CHANGED
@@ -1,26 +1,44 @@
1
1
  import type { PublicDataProvider } from "@midnight-ntwrk/midnight-js-types";
2
- import { type DomainData } from "@midnames/ns";
3
- import type { DomainInfo, DomainSettings, DomainProfileData } from "./types.js";
4
- import { Result } from "./results.js";
5
- export declare const TESTNET_TLD_ADDRESS: string;
6
- export declare const PREVIEW_TLD_ADDRESS: string;
7
- export declare function queryContractStateSafely(publicDataProvider: PublicDataProvider, contractAddress: string): Promise<Result<any>>;
2
+ import { AddressType } from "./contract.js";
3
+ import type { Ledger } from "./managed/contract/index.js";
4
+ import type { DomainInfo, DomainSettings, DomainProfileData, DomainTarget } from "./types.js";
5
+ import { type Result } from "./results.js";
6
+ export declare function getTargetFromDomainData(data: {
7
+ target: Uint8Array;
8
+ target_type: AddressType;
9
+ }): DomainTarget;
10
+ export declare function queryContractState(publicDataProvider: PublicDataProvider, contractAddress: string): Promise<Result<any>>;
11
+ export declare function getContractLedger(publicDataProvider: PublicDataProvider, contractAddress?: string): Promise<Result<Ledger>>;
12
+ /**
13
+ * Resolve a full domain string (e.g. "sub.example.night") to its numeric ID
14
+ * within the contract ledger. Returns null if any part of the path is not found.
15
+ */
16
+ export declare function resolveDomainIdInLedger(contractLedger: Ledger, fullDomain: string): bigint | null;
8
17
  export declare function resolveDomain(domain: string, options?: {
9
18
  provider?: PublicDataProvider;
10
- tldAddress?: string;
11
- }): Promise<Result<string>>;
19
+ contractAddress?: string;
20
+ }): Promise<Result<DomainTarget>>;
21
+ export declare function resolveDefault(domain: string, options?: {
22
+ provider?: PublicDataProvider;
23
+ contractAddress?: string;
24
+ }): Promise<Result<string | DomainTarget>>;
12
25
  export declare function getDomainInfo(fullDomain: string, options?: {
13
26
  provider?: PublicDataProvider;
27
+ contractAddress?: string;
14
28
  }): Promise<Result<DomainInfo>>;
15
29
  export declare function getDomainFields(fullDomain: string, options?: {
16
30
  provider?: PublicDataProvider;
31
+ contractAddress?: string;
17
32
  }): Promise<Result<Map<string, string>>>;
18
33
  export declare function getDomainSettings(fullDomain: string, options?: {
19
34
  provider?: PublicDataProvider;
35
+ contractAddress?: string;
20
36
  }): Promise<Result<DomainSettings>>;
21
37
  export declare function getDomainProfile(fullDomain: string, options?: {
22
38
  provider?: PublicDataProvider;
39
+ contractAddress?: string;
23
40
  }): Promise<Result<DomainProfileData>>;
24
41
  export declare function getSubdomains(fullDomain: string, options?: {
25
42
  provider?: PublicDataProvider;
26
- }): Promise<Result<Map<string, DomainData>>>;
43
+ contractAddress?: string;
44
+ }): Promise<Result<Map<string, DomainInfo>>>;
package/dist/core.js CHANGED
@@ -1,283 +1,246 @@
1
1
  import { getNetworkId } from "@midnight-ntwrk/midnight-js-network-id";
2
2
  import { ShieldedCoinPublicKey } from "@midnight-ntwrk/wallet-sdk-address-format";
3
- import { ledger } from "@midnames/ns";
4
- import { formatContractAddress, bytesToHex } from "./utils/address.js";
3
+ import { ledger, AddressType } from "./contract.js";
4
+ import { formatContractAddress, bytesToHex, formatUnshieldedAddress } from "./utils/address.js";
5
5
  import { normalizeDomain, parseFullDomain, DEFAULT_TLD, isTLD, domainToKey, keyToDomain } from "./utils/domain.js";
6
6
  import { success, failure, wrapAsync } from "./results.js";
7
- import { NetworkError, ContractNotFoundError, DomainNotFoundError, InvalidDomainError, } from "./errors.js";
8
- import { getDefaultProvider, getNetworkConfig, NETWORK_REGISTRY } from "./provider.js";
9
- export const TESTNET_TLD_ADDRESS = NETWORK_REGISTRY.preprod.tldAddress;
10
- export const PREVIEW_TLD_ADDRESS = NETWORK_REGISTRY.preview.tldAddress;
11
- function getDefaultTldAddress() {
7
+ import { ContractNotFoundError, DomainNotFoundError, InvalidDomainError, } from "./errors.js";
8
+ import { getDefaultProvider, getNetworkConfig } from "./provider.js";
9
+ function getDefaultContractAddress() {
12
10
  const currentNetwork = getNetworkId();
13
- return getNetworkConfig(currentNetwork).tldAddress;
11
+ return getNetworkConfig(currentNetwork).contractAddress;
14
12
  }
15
- function getTargetFromLedger(contractLedger) {
16
- const target = contractLedger.DOMAIN_TARGET;
17
- if (target.is_left) {
18
- const coinPublicKey = new ShieldedCoinPublicKey(Buffer.from(target.left.bytes));
19
- return ShieldedCoinPublicKey.codec
20
- .encode(getNetworkId(), coinPublicKey)
21
- .asString();
22
- }
23
- else {
24
- return formatContractAddress(target.right.bytes);
13
+ export function getTargetFromDomainData(data) {
14
+ switch (data.target_type) {
15
+ case AddressType.ContractAddr:
16
+ return { type: "contract", address: formatContractAddress(data.target) };
17
+ case AddressType.ZswapCPKAddr: {
18
+ const coinPublicKey = new ShieldedCoinPublicKey(Buffer.from(data.target));
19
+ const address = ShieldedCoinPublicKey.codec.encode(getNetworkId(), coinPublicKey).asString();
20
+ return { type: "shielded", address };
21
+ }
22
+ case AddressType.UnshieldedAddr:
23
+ return { type: "unshielded", address: bytesToHex(data.target) };
25
24
  }
26
25
  }
27
- export async function queryContractStateSafely(publicDataProvider, contractAddress) {
26
+ export async function queryContractState(publicDataProvider, contractAddress) {
28
27
  return wrapAsync(async () => {
29
28
  const contractState = await publicDataProvider.queryContractState(contractAddress);
30
29
  if (contractState == null) {
31
- throw new ContractNotFoundError(contractAddress, undefined);
30
+ throw new ContractNotFoundError(contractAddress);
32
31
  }
33
32
  return contractState;
34
33
  });
35
34
  }
36
- async function traverseDomainHierarchy(publicDataProvider, fullDomain, returnFinalTarget = false) {
37
- try {
38
- const tldAddress = getDefaultTldAddress();
39
- const domainParts = fullDomain.split(".");
40
- const traversalParts = domainParts.slice(0, -1).reverse();
41
- let currentResolver = tldAddress;
42
- // If we're resolving the TLD itself and want the target
43
- if (traversalParts.length === 0) {
44
- if (returnFinalTarget) {
45
- const contractStateResult = await queryContractStateSafely(publicDataProvider, currentResolver);
46
- if (!contractStateResult.success)
47
- return failure(contractStateResult.error);
48
- const contractLedger = ledger(contractStateResult.data.data);
49
- return success(getTargetFromLedger(contractLedger));
50
- }
51
- return success(tldAddress);
52
- }
53
- // Traverse the domain hierarchy
54
- for (const part of traversalParts) {
55
- const contractStateResult = await queryContractStateSafely(publicDataProvider, currentResolver);
56
- if (!contractStateResult.success) {
57
- return failure(contractStateResult.error);
58
- }
59
- const contractLedger = ledger(contractStateResult.data.data);
60
- if (!contractLedger.domains.member(domainToKey(part).key)) {
61
- return failure(new DomainNotFoundError(`${part} in ${fullDomain}`));
62
- }
63
- const domainData = contractLedger.domains.lookup(domainToKey(part).key);
64
- const resolverBytes = domainData.resolver.bytes;
65
- // Use raw hex for queryContractState (no 0200 prefix)
66
- currentResolver = bytesToHex(resolverBytes);
67
- }
68
- // Return either the final resolver address or the target it points to
69
- if (returnFinalTarget) {
70
- const finalContractStateResult = await queryContractStateSafely(publicDataProvider, currentResolver);
71
- if (!finalContractStateResult.success)
72
- return failure(finalContractStateResult.error);
73
- const finalLedger = ledger(finalContractStateResult.data.data);
74
- return success(getTargetFromLedger(finalLedger));
75
- }
76
- return success(currentResolver);
77
- }
78
- catch (error) {
79
- return failure(new NetworkError(`Failed to traverse domain hierarchy: ${error instanceof Error ? error.message : String(error)}`, error));
80
- }
35
+ export async function getContractLedger(publicDataProvider, contractAddress) {
36
+ const addr = contractAddress ?? getDefaultContractAddress();
37
+ const stateResult = await queryContractState(publicDataProvider, addr);
38
+ if (!stateResult.success)
39
+ return failure(stateResult.error);
40
+ return success(ledger(stateResult.data.data));
81
41
  }
82
- async function getResolverAddress(publicDataProvider, fullDomain) {
83
- return traverseDomainHierarchy(publicDataProvider, fullDomain, false);
42
+ /**
43
+ * Resolve a full domain string (e.g. "sub.example.night") to its numeric ID
44
+ * within the contract ledger. Returns null if any part of the path is not found.
45
+ */
46
+ export function resolveDomainIdInLedger(contractLedger, fullDomain) {
47
+ const parts = fullDomain.split(".");
48
+ // Remove TLD, reverse to walk from root
49
+ const traversalParts = parts.slice(0, -1).reverse();
50
+ if (traversalParts.length === 0) {
51
+ return contractLedger.ROOT_ZONE_ID;
52
+ }
53
+ let parentId = contractLedger.ROOT_ZONE_ID;
54
+ for (const part of traversalParts) {
55
+ const ref = { domain: domainToKey(part).key, parent_id: parentId };
56
+ if (!contractLedger.name_to_id.member(ref))
57
+ return null;
58
+ parentId = contractLedger.name_to_id.lookup(ref);
59
+ }
60
+ return parentId;
84
61
  }
62
+ // ---- Public read functions ----
85
63
  export async function resolveDomain(domain, options = {}) {
86
- // Simple validation
87
64
  const normalized = normalizeDomain(domain);
88
65
  if (!normalized.endsWith(`.${DEFAULT_TLD}`)) {
89
- return failure(new InvalidDomainError(domain, "Domain must end with .night", undefined));
66
+ return failure(new InvalidDomainError(domain, "Domain must end with .night"));
90
67
  }
91
- // Use the simple wrapper
92
68
  return wrapAsync(async () => {
93
- const result = await traverseDomainHierarchy(options.provider || getDefaultProvider(), normalized, true);
94
- if (!result.success) {
95
- throw result.error;
96
- }
97
- return result.data;
69
+ const provider = options.provider || getDefaultProvider();
70
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
71
+ if (!ledgerResult.success)
72
+ throw ledgerResult.error;
73
+ const contractLedger = ledgerResult.data;
74
+ const domainId = resolveDomainIdInLedger(contractLedger, normalized);
75
+ if (domainId === null)
76
+ throw new DomainNotFoundError(normalized);
77
+ const domainData = contractLedger.id_to_data.lookup(domainId);
78
+ return getTargetFromDomainData(domainData);
98
79
  });
99
80
  }
100
- /** Looks up a subdomain's info (owner, resolver) within a specific parent contract. */
101
- async function getDomainInfoInContract(contractAddress, domainName, options = {}) {
102
- const publicDataProvider = options.provider || getDefaultProvider();
103
- try {
104
- const contractStateResult = await queryContractStateSafely(publicDataProvider, contractAddress);
105
- if (!contractStateResult.success)
106
- return failure(contractStateResult.error);
107
- const contractLedger = ledger(contractStateResult.data.data);
108
- if (!contractLedger.domains.member(domainToKey(domainName).key)) {
109
- return failure(new DomainNotFoundError(domainName));
110
- }
111
- const domainData = contractLedger.domains.lookup(domainToKey(domainName).key);
112
- const ownerCoinPublicKey = new ShieldedCoinPublicKey(Buffer.from(domainData.owner.bytes));
113
- const ownerAddress = ShieldedCoinPublicKey.codec
114
- .encode(getNetworkId(), ownerCoinPublicKey)
115
- .asString();
116
- return success({
117
- owner: ownerAddress,
118
- resolver: formatContractAddress(domainData.resolver.bytes),
119
- });
120
- }
121
- catch (error) {
122
- return failure(new NetworkError(`Failed to get domain info: ${error instanceof Error ? error.message : String(error)}`, error));
81
+ export async function resolveDefault(domain, options = {}) {
82
+ const normalized = normalizeDomain(domain);
83
+ if (!normalized.endsWith(`.${DEFAULT_TLD}`)) {
84
+ return failure(new InvalidDomainError(domain, "Domain must end with .night"));
123
85
  }
86
+ return wrapAsync(async () => {
87
+ const provider = options.provider || getDefaultProvider();
88
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
89
+ if (!ledgerResult.success)
90
+ throw ledgerResult.error;
91
+ const contractLedger = ledgerResult.data;
92
+ const domainId = resolveDomainIdInLedger(contractLedger, normalized);
93
+ if (domainId === null)
94
+ throw new DomainNotFoundError(normalized);
95
+ const domainData = contractLedger.id_to_data.lookup(domainId);
96
+ // If there's a default field set, try to return its value
97
+ if (domainData.default_field.is_some) {
98
+ const fieldKey = domainData.default_field.value;
99
+ if (contractLedger.domain_fields.member(domainId) &&
100
+ contractLedger.domain_fields.lookup(domainId).member(fieldKey)) {
101
+ return contractLedger.domain_fields.lookup(domainId).lookup(fieldKey);
102
+ }
103
+ }
104
+ return getTargetFromDomainData(domainData);
105
+ });
124
106
  }
125
107
  export async function getDomainInfo(fullDomain, options = {}) {
126
- const publicDataProvider = options.provider || getDefaultProvider();
127
- try {
128
- const normalizedDomain = normalizeDomain(fullDomain);
129
- const parsed = parseFullDomain(normalizedDomain);
108
+ const normalized = normalizeDomain(fullDomain);
109
+ if (!isTLD(normalized)) {
110
+ const parsed = parseFullDomain(normalized);
130
111
  if (!parsed.isValid) {
131
112
  return failure(new InvalidDomainError(fullDomain, "Invalid domain format"));
132
113
  }
133
- const parentContractAddressResult = await getResolverAddress(publicDataProvider, parsed.parentDomainPath);
134
- if (!parentContractAddressResult.success)
135
- return failure(parentContractAddressResult.error);
136
- const infoResult = await getDomainInfoInContract(parentContractAddressResult.data, parsed.domainName, { provider: publicDataProvider });
137
- if (!infoResult.success)
138
- return failure(infoResult.error);
139
- return success({
140
- ...infoResult.data,
141
- contractAddress: parentContractAddressResult.data,
142
- });
143
- }
144
- catch (error) {
145
- return failure(new NetworkError(`Failed to get domain info by resolving: ${error instanceof Error ? error.message : String(error)}`, error));
146
114
  }
147
- }
148
- async function readContractLedger(publicDataProvider, resolverAddress) {
149
- const rawAddress = resolverAddress.startsWith('0200')
150
- ? resolverAddress.slice(4)
151
- : resolverAddress;
152
- const contractStateResult = await queryContractStateSafely(publicDataProvider, rawAddress);
153
- if (!contractStateResult.success)
154
- return failure(contractStateResult.error);
155
- return success(ledger(contractStateResult.data.data));
115
+ return wrapAsync(async () => {
116
+ const provider = options.provider || getDefaultProvider();
117
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
118
+ if (!ledgerResult.success)
119
+ throw ledgerResult.error;
120
+ const contractLedger = ledgerResult.data;
121
+ const domainId = resolveDomainIdInLedger(contractLedger, normalized);
122
+ if (domainId === null)
123
+ throw new DomainNotFoundError(normalized);
124
+ const domainData = contractLedger.id_to_data.lookup(domainId);
125
+ return {
126
+ id: domainId,
127
+ owner: bytesToHex(domainData.owner_public_key),
128
+ ownerAddress: formatUnshieldedAddress(domainData.owner_address.bytes),
129
+ target: getTargetFromDomainData(domainData),
130
+ targetLocked: domainData.target_locked,
131
+ };
132
+ });
156
133
  }
157
134
  export async function getDomainFields(fullDomain, options = {}) {
158
- const publicDataProvider = options.provider || getDefaultProvider();
159
- try {
160
- const normalized = normalizeDomain(fullDomain);
161
- const infoResult = await getDomainInfo(normalized, { provider: publicDataProvider });
162
- if (!infoResult.success)
163
- return failure(infoResult.error);
164
- const ledgerResult = await readContractLedger(publicDataProvider, infoResult.data.resolver);
135
+ const normalized = normalizeDomain(fullDomain);
136
+ return wrapAsync(async () => {
137
+ const provider = options.provider || getDefaultProvider();
138
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
165
139
  if (!ledgerResult.success)
166
- return failure(ledgerResult.error);
140
+ throw ledgerResult.error;
141
+ const contractLedger = ledgerResult.data;
142
+ const domainId = resolveDomainIdInLedger(contractLedger, normalized);
143
+ if (domainId === null)
144
+ throw new DomainNotFoundError(normalized);
167
145
  const fields = new Map();
168
- for (const [key, value] of ledgerResult.data.fields)
169
- fields.set(key, value);
170
- return success(fields);
171
- }
172
- catch (error) {
173
- return failure(new NetworkError(`Failed to get domain fields: ${error instanceof Error ? error.message : String(error)}`, error));
174
- }
146
+ if (contractLedger.domain_fields.member(domainId)) {
147
+ for (const [key, value] of contractLedger.domain_fields.lookup(domainId)) {
148
+ fields.set(key, value);
149
+ }
150
+ }
151
+ return fields;
152
+ });
175
153
  }
176
154
  export async function getDomainSettings(fullDomain, options = {}) {
177
- const publicDataProvider = options.provider || getDefaultProvider();
178
- try {
179
- const normalized = normalizeDomain(fullDomain, false);
180
- // Special case: TLD itself — read settings directly from TLD contract
181
- if (isTLD(normalized)) {
182
- const tldAddress = getDefaultTldAddress();
183
- const ledgerResult = await readContractLedger(publicDataProvider, tldAddress);
184
- if (!ledgerResult.success)
185
- return failure(ledgerResult.error);
186
- return success({
187
- coinColor: ledgerResult.data.COIN_COLOR,
188
- costs: {
189
- short: ledgerResult.data.COST_SHORT,
190
- medium: ledgerResult.data.COST_MED,
191
- long: ledgerResult.data.COST_LONG,
192
- },
193
- });
194
- }
195
- // Normal case: subdomain — resolve via getDomainInfo
196
- const normalizedFull = normalizeDomain(fullDomain);
197
- const infoResult = await getDomainInfo(normalizedFull, { provider: publicDataProvider });
198
- if (!infoResult.success)
199
- return failure(infoResult.error);
200
- const ledgerResult = await readContractLedger(publicDataProvider, infoResult.data.resolver);
155
+ const normalized = normalizeDomain(fullDomain);
156
+ return wrapAsync(async () => {
157
+ const provider = options.provider || getDefaultProvider();
158
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
201
159
  if (!ledgerResult.success)
202
- return failure(ledgerResult.error);
203
- return success({
204
- coinColor: ledgerResult.data.COIN_COLOR,
160
+ throw ledgerResult.error;
161
+ const contractLedger = ledgerResult.data;
162
+ const domainId = resolveDomainIdInLedger(contractLedger, normalized);
163
+ if (domainId === null)
164
+ throw new DomainNotFoundError(normalized);
165
+ const data = contractLedger.id_to_data.lookup(domainId);
166
+ return {
167
+ coinColor: data.payment_config.coin_color,
205
168
  costs: {
206
- short: ledgerResult.data.COST_SHORT,
207
- medium: ledgerResult.data.COST_MED,
208
- long: ledgerResult.data.COST_LONG,
169
+ short: data.payment_config.cost_short,
170
+ medium: data.payment_config.cost_med,
171
+ long: data.payment_config.cost_long,
209
172
  },
210
- });
211
- }
212
- catch (error) {
213
- return failure(new NetworkError(`Failed to get domain settings: ${error instanceof Error ? error.message : String(error)}`, error));
214
- }
173
+ buyEnabled: data.payment_config.buy_enabled,
174
+ defaultField: data.default_field.is_some ? data.default_field.value : null,
175
+ paymentConfigLocked: data.payment_config_locked,
176
+ };
177
+ });
215
178
  }
216
179
  export async function getDomainProfile(fullDomain, options = {}) {
217
- const publicDataProvider = options.provider || getDefaultProvider();
218
- try {
219
- const normalized = normalizeDomain(fullDomain);
220
- const [resolvedTargetResult, infoResult] = await Promise.all([
221
- resolveDomain(normalized, { provider: publicDataProvider }),
222
- getDomainInfo(normalized, { provider: publicDataProvider }),
223
- ]);
224
- const resolvedTarget = resolvedTargetResult.success
225
- ? resolvedTargetResult.data
226
- : null;
227
- const info = infoResult.success ? infoResult.data : null;
228
- if (info && info.resolver) {
229
- const ledgerResult = await readContractLedger(publicDataProvider, info.resolver);
230
- if (ledgerResult.success) {
231
- const fields = new Map();
232
- for (const [key, value] of ledgerResult.data.fields)
233
- fields.set(key, value);
234
- const settings = {
235
- coinColor: ledgerResult.data.COIN_COLOR,
236
- costs: {
237
- short: ledgerResult.data.COST_SHORT,
238
- medium: ledgerResult.data.COST_MED,
239
- long: ledgerResult.data.COST_LONG,
240
- },
241
- };
242
- return success({
243
- fullDomain: normalized,
244
- resolvedTarget,
245
- info,
246
- fields,
247
- settings,
248
- });
180
+ const normalized = normalizeDomain(fullDomain);
181
+ return wrapAsync(async () => {
182
+ const provider = options.provider || getDefaultProvider();
183
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
184
+ if (!ledgerResult.success)
185
+ throw ledgerResult.error;
186
+ const contractLedger = ledgerResult.data;
187
+ const domainId = resolveDomainIdInLedger(contractLedger, normalized);
188
+ if (domainId === null)
189
+ throw new DomainNotFoundError(normalized);
190
+ const domainData = contractLedger.id_to_data.lookup(domainId);
191
+ const info = {
192
+ id: domainId,
193
+ owner: bytesToHex(domainData.owner_public_key),
194
+ ownerAddress: formatUnshieldedAddress(domainData.owner_address.bytes),
195
+ target: getTargetFromDomainData(domainData),
196
+ targetLocked: domainData.target_locked,
197
+ };
198
+ const fields = new Map();
199
+ if (contractLedger.domain_fields.member(domainId)) {
200
+ for (const [key, value] of contractLedger.domain_fields.lookup(domainId)) {
201
+ fields.set(key, value);
249
202
  }
250
203
  }
251
- return success({
252
- fullDomain: normalized,
253
- resolvedTarget,
254
- info,
255
- fields: new Map(),
256
- settings: null,
257
- });
258
- }
259
- catch (error) {
260
- return failure(new NetworkError(`Failed to get domain profile: ${error instanceof Error ? error.message : String(error)}`, error));
261
- }
204
+ const settings = {
205
+ coinColor: domainData.payment_config.coin_color,
206
+ costs: {
207
+ short: domainData.payment_config.cost_short,
208
+ medium: domainData.payment_config.cost_med,
209
+ long: domainData.payment_config.cost_long,
210
+ },
211
+ buyEnabled: domainData.payment_config.buy_enabled,
212
+ defaultField: domainData.default_field.is_some
213
+ ? domainData.default_field.value
214
+ : null,
215
+ paymentConfigLocked: domainData.payment_config_locked,
216
+ };
217
+ return { fullDomain: normalized, info, fields, settings };
218
+ });
262
219
  }
263
220
  export async function getSubdomains(fullDomain, options = {}) {
264
- const publicDataProvider = options.provider || getDefaultProvider();
265
- try {
266
- const normalized = normalizeDomain(fullDomain);
267
- const infoResult = await getDomainInfo(normalized, { provider: publicDataProvider });
268
- if (!infoResult.success)
269
- return failure(infoResult.error);
270
- const ledgerResult = await readContractLedger(publicDataProvider, infoResult.data.resolver);
221
+ const normalized = normalizeDomain(fullDomain);
222
+ return wrapAsync(async () => {
223
+ const provider = options.provider || getDefaultProvider();
224
+ const ledgerResult = await getContractLedger(provider, options.contractAddress);
271
225
  if (!ledgerResult.success)
272
- return failure(ledgerResult.error);
226
+ throw ledgerResult.error;
227
+ const contractLedger = ledgerResult.data;
228
+ const parentId = resolveDomainIdInLedger(contractLedger, normalized);
229
+ if (parentId === null)
230
+ throw new DomainNotFoundError(normalized);
273
231
  const subdomains = new Map();
274
- for (const [name, data] of ledgerResult.data.domains) {
275
- subdomains.set(keyToDomain(name), data);
232
+ for (const [ref, id] of contractLedger.name_to_id) {
233
+ if (ref.parent_id === parentId) {
234
+ const data = contractLedger.id_to_data.lookup(id);
235
+ subdomains.set(keyToDomain(ref.domain), {
236
+ id,
237
+ owner: bytesToHex(data.owner_public_key),
238
+ ownerAddress: bytesToHex(data.owner_address.bytes),
239
+ target: getTargetFromDomainData(data),
240
+ targetLocked: data.target_locked,
241
+ });
242
+ }
276
243
  }
277
- return success(subdomains);
278
- }
279
- catch (error) {
280
- return failure(new NetworkError(`Failed to get subdomains: ${error instanceof Error ? error.message : String(error)}`, error));
281
- }
244
+ return subdomains;
245
+ });
282
246
  }
283
- //# sourceMappingURL=core.js.map
package/dist/errors.d.ts CHANGED
@@ -15,6 +15,3 @@ export declare class DomainNotFoundError extends MidnamesError {
15
15
  export declare class InvalidDomainError extends MidnamesError {
16
16
  constructor(domain: string, reason: string, details?: unknown);
17
17
  }
18
- export declare class ProviderError extends MidnamesError {
19
- constructor(message: string, details?: unknown);
20
- }