@midnames/sdk 0.2.1 → 1.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.
Files changed (55) hide show
  1. package/dist/controller-types.d.ts +104 -0
  2. package/dist/controller-types.js +16 -0
  3. package/dist/core.d.ts +13 -9
  4. package/dist/core.js +158 -67
  5. package/dist/errors.d.ts +20 -0
  6. package/dist/errors.js +39 -0
  7. package/dist/index.d.ts +5 -0
  8. package/dist/index.js +5 -0
  9. package/dist/managed/index.d.ts +3 -9
  10. package/dist/managed/index.js +3 -5
  11. package/dist/managed/index.js.map +1 -1
  12. package/dist/managed/leaf.compact +97 -65
  13. package/dist/managed/managed/leaf/contract/index.d.ts +197 -0
  14. package/dist/managed/managed/leaf/contract/index.js +3094 -0
  15. package/dist/managed/managed/leaf/contract/index.js.map +8 -0
  16. package/dist/managed/utils.d.ts +5 -0
  17. package/dist/managed/utils.js +19 -0
  18. package/dist/managed/utils.js.map +1 -0
  19. package/dist/operations.d.ts +49 -0
  20. package/dist/operations.js +137 -0
  21. package/dist/provider.d.ts +10 -4
  22. package/dist/provider.js +32 -8
  23. package/dist/react/DomainProfileWidget.d.ts +2 -2
  24. package/dist/react/DomainProfileWidget.js +11 -8
  25. package/dist/react/HolographicCard.d.ts +2 -2
  26. package/dist/react/HolographicCard.js +10 -7
  27. package/dist/react/index.d.ts +2 -2
  28. package/dist/react/index.js +1 -2
  29. package/dist/results.d.ts +38 -0
  30. package/dist/results.js +88 -0
  31. package/dist/types.d.ts +7 -41
  32. package/dist/types.js +1 -61
  33. package/dist/utils/address.js +6 -5
  34. package/dist/utils/domain.d.ts +6 -0
  35. package/dist/utils/domain.js +19 -1
  36. package/dist/utils/imageResolver.d.ts +8 -0
  37. package/dist/utils/imageResolver.js +89 -0
  38. package/dist/utils/sanitize.d.ts +6 -0
  39. package/dist/utils/sanitize.js +28 -0
  40. package/exported.md +1 -1
  41. package/managed/index.js +3 -5
  42. package/managed/index.js.map +1 -1
  43. package/managed/leaf.compact +97 -65
  44. package/managed/managed/leaf/contract/index.js +3094 -0
  45. package/managed/managed/leaf/contract/index.js.map +8 -0
  46. package/managed/utils.js +19 -0
  47. package/managed/utils.js.map +1 -0
  48. package/package.json +22 -11
  49. package/dist/managed/managed/leaf/contract/index.cjs +0 -2789
  50. package/dist/managed/managed/leaf/contract/index.cjs.map +0 -8
  51. package/dist/managed/managed/leaf/contract/index.d.cts +0 -146
  52. package/managed/managed/leaf/contract/index.cjs +0 -2789
  53. package/managed/managed/leaf/contract/index.cjs.map +0 -8
  54. package/managed/managed/leaf/contract/index.d.cts +0 -146
  55. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Controller Types for the Nameservice SDK
3
+ *
4
+ * These types define the interface for the LeafContractController
5
+ * which manages domain contract interactions with RxJS observable state.
6
+ *
7
+ * Note: The full LeafContractController implementation is in the frontend
8
+ * module at: modules/midnight/nameservice-sdk/api/leafContractController.ts
9
+ */
10
+ import type { Observable, Subject } from 'rxjs';
11
+ /**
12
+ * Target address - domains can point to either a wallet (CoinPublicKey) or another contract
13
+ */
14
+ export interface EitherTarget {
15
+ is_left: boolean;
16
+ left: {
17
+ bytes: Uint8Array;
18
+ };
19
+ right: {
20
+ bytes: Uint8Array;
21
+ };
22
+ }
23
+ /**
24
+ * Subdomain data stored in the parent contract
25
+ */
26
+ export interface SubdomainData {
27
+ owner: {
28
+ bytes: Uint8Array;
29
+ };
30
+ resolver: {
31
+ bytes: Uint8Array;
32
+ };
33
+ }
34
+ /**
35
+ * Observable state for a single domain contract
36
+ */
37
+ export interface DomainState {
38
+ contractAddress: string;
39
+ target: EitherTarget;
40
+ fields: Map<string, string>;
41
+ subdomains: Map<string, SubdomainData>;
42
+ coinColor: Uint8Array;
43
+ domainCost: bigint;
44
+ }
45
+ /**
46
+ * Operation status for tracking async operations
47
+ */
48
+ export type OperationStatus = {
49
+ type: 'idle';
50
+ } | {
51
+ type: 'proving';
52
+ message?: string;
53
+ } | {
54
+ type: 'signing';
55
+ message?: string;
56
+ } | {
57
+ type: 'submitting';
58
+ message?: string;
59
+ } | {
60
+ type: 'complete';
61
+ txHash?: string;
62
+ } | {
63
+ type: 'error';
64
+ error: Error;
65
+ };
66
+ /**
67
+ * Result of a transaction operation
68
+ */
69
+ export interface TxResult {
70
+ txHash: string;
71
+ blockHeight?: bigint;
72
+ }
73
+ /**
74
+ * Derived state combining contract state with operation status
75
+ */
76
+ export interface DerivedDomainState {
77
+ domain: DomainState | null;
78
+ operationStatus: OperationStatus;
79
+ }
80
+ /**
81
+ * Interface for the LeafContractController
82
+ *
83
+ * This interface defines the contract for managing domain operations.
84
+ * The implementation uses RxJS observables for reactive state updates.
85
+ */
86
+ export interface LeafContractControllerInterface {
87
+ /** The contract address this controller is connected to */
88
+ readonly contractAddress: string;
89
+ /** Observable stream of domain state */
90
+ readonly state$: Observable<DerivedDomainState>;
91
+ /** Subject for operation status updates */
92
+ readonly operations$: Subject<OperationStatus>;
93
+ updateTarget(target: EitherTarget): Promise<TxResult>;
94
+ insertField(key: string, value: string): Promise<TxResult>;
95
+ clearField(key: string): Promise<TxResult>;
96
+ clearAllFields(): Promise<TxResult>;
97
+ addMultipleFields(kvs: Array<[string, string]>): Promise<TxResult>;
98
+ registerDomainFor(ownerCoinPublicKey: Uint8Array, domainName: string, resolverAddress: string): Promise<TxResult>;
99
+ transferDomain(domainName: string, newOwnerCoinPublicKey: Uint8Array): Promise<TxResult>;
100
+ }
101
+ /**
102
+ * Empty initial state constant
103
+ */
104
+ export declare const emptyDomainState: DerivedDomainState;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Controller Types for the Nameservice SDK
3
+ *
4
+ * These types define the interface for the LeafContractController
5
+ * which manages domain contract interactions with RxJS observable state.
6
+ *
7
+ * Note: The full LeafContractController implementation is in the frontend
8
+ * module at: modules/midnight/nameservice-sdk/api/leafContractController.ts
9
+ */
10
+ /**
11
+ * Empty initial state constant
12
+ */
13
+ export const emptyDomainState = {
14
+ domain: null,
15
+ operationStatus: { type: 'idle' },
16
+ };
package/dist/core.d.ts CHANGED
@@ -1,22 +1,26 @@
1
- import type { PublicDataProvider } from '@midnight-ntwrk/midnight-js-types';
2
- import type { DomainInfo, DomainSettings, DomainProfileData, Result } from './types.js';
3
- export declare const TESTNET_TLD_ADDRESS = "0200c46ddd9a7fe134e7126132bf48d573e3e70a06fc2b82edb2c9f31584536efa01";
1
+ import type { PublicDataProvider } from "@midnight-ntwrk/midnight-js-types";
2
+ import { type DomainData } from "../managed/index.js";
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>>;
4
8
  export declare function resolveDomain(domain: string, options?: {
5
9
  provider?: PublicDataProvider;
6
10
  tldAddress?: string;
7
11
  }): Promise<Result<string>>;
8
- export declare function getDomainInfoInContract(contractAddress: string, domainName: string, options?: {
9
- provider?: PublicDataProvider;
10
- }): Promise<Result<DomainInfo>>;
11
12
  export declare function getDomainInfo(fullDomain: string, options?: {
12
13
  provider?: PublicDataProvider;
13
14
  }): Promise<Result<DomainInfo>>;
14
- export declare function getDomainFields(contractAddress: string, options?: {
15
+ export declare function getDomainFields(fullDomain: string, options?: {
15
16
  provider?: PublicDataProvider;
16
- }): Promise<Result<Array<[string, string]>>>;
17
- export declare function getDomainSettings(contractAddress: string, options?: {
17
+ }): Promise<Result<Map<string, string>>>;
18
+ export declare function getDomainSettings(fullDomain: string, options?: {
18
19
  provider?: PublicDataProvider;
19
20
  }): Promise<Result<DomainSettings>>;
20
21
  export declare function getDomainProfile(fullDomain: string, options?: {
21
22
  provider?: PublicDataProvider;
22
23
  }): Promise<Result<DomainProfileData>>;
24
+ export declare function getSubdomains(fullDomain: string, options?: {
25
+ provider?: PublicDataProvider;
26
+ }): Promise<Result<Map<string, DomainData>>>;
package/dist/core.js CHANGED
@@ -1,47 +1,42 @@
1
- import { getNetworkId, getZswapNetworkId, NetworkId } from '@midnight-ntwrk/midnight-js-network-id';
2
- import { ShieldedCoinPublicKey } from '@midnight-ntwrk/wallet-sdk-address-format';
3
- import { ledger } from './managed/index.js';
4
- import { formatContractAddress } from './utils/address.js';
5
- import { normalizeDomain, parseFullDomain } from './utils/domain.js';
6
- import { success, failure, NetworkError, ContractNotFoundError, DomainNotFoundError, InvalidDomainError, ProviderError } from './types.js';
7
- import { getDefaultProvider } from './provider.js';
8
- const TLD = 'night';
9
- export const TESTNET_TLD_ADDRESS = '0200c46ddd9a7fe134e7126132bf48d573e3e70a06fc2b82edb2c9f31584536efa01';
1
+ import { getNetworkId } from "@midnight-ntwrk/midnight-js-network-id";
2
+ import { ShieldedCoinPublicKey } from "@midnight-ntwrk/wallet-sdk-address-format";
3
+ import { ledger } from "./managed/index.js";
4
+ import { formatContractAddress, bytesToHex } from "./utils/address.js";
5
+ import { normalizeDomain, parseFullDomain, DEFAULT_TLD, isTLD, domainToKey, keyToDomain } from "./utils/domain.js";
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;
10
11
  function getDefaultTldAddress() {
11
12
  const currentNetwork = getNetworkId();
12
- switch (currentNetwork) {
13
- case NetworkId.TestNet:
14
- return TESTNET_TLD_ADDRESS;
15
- default:
16
- throw new Error('Provide an address to use the resolver on a Standalone Network.');
17
- }
13
+ return getNetworkConfig(currentNetwork).tldAddress;
18
14
  }
19
15
  function getTargetFromLedger(contractLedger) {
20
16
  const target = contractLedger.DOMAIN_TARGET;
21
17
  if (target.is_left) {
22
18
  const coinPublicKey = new ShieldedCoinPublicKey(Buffer.from(target.left.bytes));
23
- return ShieldedCoinPublicKey.codec.encode(getZswapNetworkId(), coinPublicKey).asString();
19
+ return ShieldedCoinPublicKey.codec
20
+ .encode(getNetworkId(), coinPublicKey)
21
+ .asString();
24
22
  }
25
23
  else {
26
24
  return formatContractAddress(target.right.bytes);
27
25
  }
28
26
  }
29
- async function queryContractStateSafely(publicDataProvider, contractAddress) {
30
- try {
27
+ export async function queryContractStateSafely(publicDataProvider, contractAddress) {
28
+ return wrapAsync(async () => {
31
29
  const contractState = await publicDataProvider.queryContractState(contractAddress);
32
30
  if (contractState == null) {
33
- return failure(new ContractNotFoundError(contractAddress));
31
+ throw new ContractNotFoundError(contractAddress, undefined);
34
32
  }
35
- return success(contractState);
36
- }
37
- catch (error) {
38
- return failure(new ProviderError(`Failed to query contract state: ${error instanceof Error ? error.message : String(error)}`, error));
39
- }
33
+ return contractState;
34
+ });
40
35
  }
41
36
  async function traverseDomainHierarchy(publicDataProvider, fullDomain, returnFinalTarget = false) {
42
37
  try {
43
38
  const tldAddress = getDefaultTldAddress();
44
- const domainParts = fullDomain.split('.');
39
+ const domainParts = fullDomain.split(".");
45
40
  const traversalParts = domainParts.slice(0, -1).reverse();
46
41
  let currentResolver = tldAddress;
47
42
  // If we're resolving the TLD itself and want the target
@@ -62,12 +57,13 @@ async function traverseDomainHierarchy(publicDataProvider, fullDomain, returnFin
62
57
  return failure(contractStateResult.error);
63
58
  }
64
59
  const contractLedger = ledger(contractStateResult.data.data);
65
- if (!contractLedger.domains.member(part)) {
60
+ if (!contractLedger.domains.member(domainToKey(part).key)) {
66
61
  return failure(new DomainNotFoundError(`${part} in ${fullDomain}`));
67
62
  }
68
- const domainData = contractLedger.domains.lookup(part);
63
+ const domainData = contractLedger.domains.lookup(domainToKey(part).key);
69
64
  const resolverBytes = domainData.resolver.bytes;
70
- currentResolver = formatContractAddress(resolverBytes);
65
+ // Use raw hex for queryContractState (no 0200 prefix)
66
+ currentResolver = bytesToHex(resolverBytes);
71
67
  }
72
68
  // Return either the final resolver address or the target it points to
73
69
  if (returnFinalTarget) {
@@ -87,29 +83,40 @@ async function getResolverAddress(publicDataProvider, fullDomain) {
87
83
  return traverseDomainHierarchy(publicDataProvider, fullDomain, false);
88
84
  }
89
85
  export async function resolveDomain(domain, options = {}) {
90
- const publicDataProvider = options.provider || getDefaultProvider();
91
- const fullDomain = normalizeDomain(domain);
92
- // Validate TLD
93
- const domainParts = fullDomain.split('.');
94
- if (domainParts[domainParts.length - 1] !== TLD) {
95
- return failure(new InvalidDomainError(fullDomain, `Domain must end with .${TLD}`));
86
+ // Simple validation
87
+ const normalized = normalizeDomain(domain);
88
+ if (!normalized.endsWith(`.${DEFAULT_TLD}`)) {
89
+ return failure(new InvalidDomainError(domain, "Domain must end with .night", undefined));
96
90
  }
97
- return traverseDomainHierarchy(publicDataProvider, fullDomain, true);
91
+ // Use the simple wrapper
92
+ 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;
98
+ });
98
99
  }
99
- export async function getDomainInfoInContract(contractAddress, domainName, options = {}) {
100
+ /** Looks up a subdomain's info (owner, resolver) within a specific parent contract. */
101
+ async function getDomainInfoInContract(contractAddress, domainName, options = {}) {
100
102
  const publicDataProvider = options.provider || getDefaultProvider();
101
103
  try {
102
104
  const contractStateResult = await queryContractStateSafely(publicDataProvider, contractAddress);
103
105
  if (!contractStateResult.success)
104
106
  return failure(contractStateResult.error);
105
107
  const contractLedger = ledger(contractStateResult.data.data);
106
- if (!contractLedger.domains.member(domainName)) {
108
+ if (!contractLedger.domains.member(domainToKey(domainName).key)) {
107
109
  return failure(new DomainNotFoundError(domainName));
108
110
  }
109
- const domainData = contractLedger.domains.lookup(domainName);
111
+ const domainData = contractLedger.domains.lookup(domainToKey(domainName).key);
110
112
  const ownerCoinPublicKey = new ShieldedCoinPublicKey(Buffer.from(domainData.owner.bytes));
111
- const ownerAddress = ShieldedCoinPublicKey.codec.encode(getZswapNetworkId(), ownerCoinPublicKey).asString();
112
- return success({ owner: ownerAddress, resolver: formatContractAddress(domainData.resolver.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
+ });
113
120
  }
114
121
  catch (error) {
115
122
  return failure(new NetworkError(`Failed to get domain info: ${error instanceof Error ? error.message : String(error)}`, error));
@@ -121,7 +128,7 @@ export async function getDomainInfo(fullDomain, options = {}) {
121
128
  const normalizedDomain = normalizeDomain(fullDomain);
122
129
  const parsed = parseFullDomain(normalizedDomain);
123
130
  if (!parsed.isValid) {
124
- return failure(new InvalidDomainError(fullDomain, 'Invalid domain format'));
131
+ return failure(new InvalidDomainError(fullDomain, "Invalid domain format"));
125
132
  }
126
133
  const parentContractAddressResult = await getResolverAddress(publicDataProvider, parsed.parentDomainPath);
127
134
  if (!parentContractAddressResult.success)
@@ -129,36 +136,78 @@ export async function getDomainInfo(fullDomain, options = {}) {
129
136
  const infoResult = await getDomainInfoInContract(parentContractAddressResult.data, parsed.domainName, { provider: publicDataProvider });
130
137
  if (!infoResult.success)
131
138
  return failure(infoResult.error);
132
- return success({ ...infoResult.data, contractAddress: parentContractAddressResult.data });
139
+ return success({
140
+ ...infoResult.data,
141
+ contractAddress: parentContractAddressResult.data,
142
+ });
133
143
  }
134
144
  catch (error) {
135
145
  return failure(new NetworkError(`Failed to get domain info by resolving: ${error instanceof Error ? error.message : String(error)}`, error));
136
146
  }
137
147
  }
138
- export async function getDomainFields(contractAddress, options = {}) {
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));
156
+ }
157
+ export async function getDomainFields(fullDomain, options = {}) {
139
158
  const publicDataProvider = options.provider || getDefaultProvider();
140
159
  try {
141
- const contractStateResult = await queryContractStateSafely(publicDataProvider, contractAddress);
142
- if (!contractStateResult.success)
143
- return failure(contractStateResult.error);
144
- const contractLedger = ledger(contractStateResult.data.data);
145
- const fields = [];
146
- for (const [key, value] of contractLedger.fields)
147
- fields.push([key, value]);
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);
165
+ if (!ledgerResult.success)
166
+ return failure(ledgerResult.error);
167
+ const fields = new Map();
168
+ for (const [key, value] of ledgerResult.data.fields)
169
+ fields.set(key, value);
148
170
  return success(fields);
149
171
  }
150
172
  catch (error) {
151
173
  return failure(new NetworkError(`Failed to get domain fields: ${error instanceof Error ? error.message : String(error)}`, error));
152
174
  }
153
175
  }
154
- export async function getDomainSettings(contractAddress, options = {}) {
176
+ export async function getDomainSettings(fullDomain, options = {}) {
155
177
  const publicDataProvider = options.provider || getDefaultProvider();
156
178
  try {
157
- const contractStateResult = await queryContractStateSafely(publicDataProvider, contractAddress);
158
- if (!contractStateResult.success)
159
- return failure(contractStateResult.error);
160
- const contractLedger = ledger(contractStateResult.data.data);
161
- return success({ coinColor: contractLedger.COIN_COLOR, domainCost: contractLedger.DOMAIN_COST });
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);
201
+ if (!ledgerResult.success)
202
+ return failure(ledgerResult.error);
203
+ return success({
204
+ coinColor: ledgerResult.data.COIN_COLOR,
205
+ costs: {
206
+ short: ledgerResult.data.COST_SHORT,
207
+ medium: ledgerResult.data.COST_MED,
208
+ long: ledgerResult.data.COST_LONG,
209
+ },
210
+ });
162
211
  }
163
212
  catch (error) {
164
213
  return failure(new NetworkError(`Failed to get domain settings: ${error instanceof Error ? error.message : String(error)}`, error));
@@ -170,22 +219,64 @@ export async function getDomainProfile(fullDomain, options = {}) {
170
219
  const normalized = normalizeDomain(fullDomain);
171
220
  const [resolvedTargetResult, infoResult] = await Promise.all([
172
221
  resolveDomain(normalized, { provider: publicDataProvider }),
173
- getDomainInfo(normalized, { provider: publicDataProvider })
222
+ getDomainInfo(normalized, { provider: publicDataProvider }),
174
223
  ]);
175
- const resolvedTarget = resolvedTargetResult.success ? resolvedTargetResult.data : null;
224
+ const resolvedTarget = resolvedTargetResult.success
225
+ ? resolvedTargetResult.data
226
+ : null;
176
227
  const info = infoResult.success ? infoResult.data : null;
177
- if (info && info.contractAddress) {
178
- const [fieldsResult, settingsResult] = await Promise.all([
179
- getDomainFields(info.resolver, { provider: publicDataProvider }),
180
- getDomainSettings(info.resolver, { provider: publicDataProvider })
181
- ]);
182
- const fields = fieldsResult.success ? fieldsResult.data : [];
183
- const settings = settingsResult.success ? settingsResult.data : null;
184
- return success({ fullDomain: normalized, resolvedTarget, info, fields, settings });
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
+ });
249
+ }
185
250
  }
186
- return success({ fullDomain: normalized, resolvedTarget, info, fields: [], settings: null });
251
+ return success({
252
+ fullDomain: normalized,
253
+ resolvedTarget,
254
+ info,
255
+ fields: new Map(),
256
+ settings: null,
257
+ });
187
258
  }
188
259
  catch (error) {
189
260
  return failure(new NetworkError(`Failed to get domain profile: ${error instanceof Error ? error.message : String(error)}`, error));
190
261
  }
191
262
  }
263
+ 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);
271
+ if (!ledgerResult.success)
272
+ return failure(ledgerResult.error);
273
+ const subdomains = new Map();
274
+ for (const [name, data] of ledgerResult.data.domains) {
275
+ subdomains.set(keyToDomain(name), data);
276
+ }
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
+ }
282
+ }
@@ -0,0 +1,20 @@
1
+ export declare class MidnamesError extends Error {
2
+ readonly code: string;
3
+ readonly details?: unknown | undefined;
4
+ constructor(message: string, code: string, details?: unknown | undefined);
5
+ }
6
+ export declare class NetworkError extends MidnamesError {
7
+ constructor(message: string, details?: unknown);
8
+ }
9
+ export declare class ContractNotFoundError extends MidnamesError {
10
+ constructor(contractAddress: string, details?: unknown);
11
+ }
12
+ export declare class DomainNotFoundError extends MidnamesError {
13
+ constructor(domain: string, details?: unknown);
14
+ }
15
+ export declare class InvalidDomainError extends MidnamesError {
16
+ constructor(domain: string, reason: string, details?: unknown);
17
+ }
18
+ export declare class ProviderError extends MidnamesError {
19
+ constructor(message: string, details?: unknown);
20
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,39 @@
1
+ // Error handling types
2
+ export class MidnamesError extends Error {
3
+ constructor(message, code, details) {
4
+ super(message);
5
+ this.code = code;
6
+ this.details = details;
7
+ this.name = 'MidnamesError';
8
+ }
9
+ }
10
+ export class NetworkError extends MidnamesError {
11
+ constructor(message, details) {
12
+ super(message, 'NETWORK_ERROR', details);
13
+ this.name = 'NetworkError';
14
+ }
15
+ }
16
+ export class ContractNotFoundError extends MidnamesError {
17
+ constructor(contractAddress, details) {
18
+ super(`Contract not found: ${contractAddress}`, 'CONTRACT_NOT_FOUND', details);
19
+ this.name = 'ContractNotFoundError';
20
+ }
21
+ }
22
+ export class DomainNotFoundError extends MidnamesError {
23
+ constructor(domain, details) {
24
+ super(`Domain not found: ${domain}`, 'DOMAIN_NOT_FOUND', details);
25
+ this.name = 'DomainNotFoundError';
26
+ }
27
+ }
28
+ export class InvalidDomainError extends MidnamesError {
29
+ constructor(domain, reason, details) {
30
+ super(`Invalid domain "${domain}": ${reason}`, 'INVALID_DOMAIN', details);
31
+ this.name = 'InvalidDomainError';
32
+ }
33
+ }
34
+ export class ProviderError extends MidnamesError {
35
+ constructor(message, details) {
36
+ super(message, 'PROVIDER_ERROR', details);
37
+ this.name = 'ProviderError';
38
+ }
39
+ }
package/dist/index.d.ts CHANGED
@@ -3,3 +3,8 @@ export * from './utils/domain.js';
3
3
  export * from './utils/address.js';
4
4
  export * from './core.js';
5
5
  export * from './provider.js';
6
+ export { buildKvs, insertField, clearField, clearAllFields, addMultipleFields, updateDomainTarget, updateDomainColor, updateDomainCosts, transferDomainOwnership, setDomainResolver, registerDomainFor, buyDomainFor, changeDomainOwner, } from './operations.js';
7
+ export * from './results.js';
8
+ export * from './errors.js';
9
+ export * from './controller-types.js';
10
+ export { resolveImageUrl } from './utils/imageResolver.js';
package/dist/index.js CHANGED
@@ -3,3 +3,8 @@ export * from './utils/domain.js';
3
3
  export * from './utils/address.js';
4
4
  export * from './core.js';
5
5
  export * from './provider.js';
6
+ export { buildKvs, insertField, clearField, clearAllFields, addMultipleFields, updateDomainTarget, updateDomainColor, updateDomainCosts, transferDomainOwnership, setDomainResolver, registerDomainFor, buyDomainFor, changeDomainOwner, } from './operations.js';
7
+ export * from './results.js';
8
+ export * from './errors.js';
9
+ export * from './controller-types.js';
10
+ export { resolveImageUrl } from './utils/imageResolver.js';
@@ -1,9 +1,3 @@
1
- export { type DomainData as LeafDomainData } from "./managed/leaf/contract/index.cjs";
2
- export * as Leaf from "./managed/leaf/contract/index.cjs";
3
- import ContractModule from './managed/leaf/contract/index.cjs';
4
- import type { Contract as ContractType, Witnesses } from './managed/leaf/contract/index.cjs';
5
- export declare const ledger: typeof ContractModule.ledger;
6
- export declare const pureCircuits: ContractModule.PureCircuits;
7
- export declare const Contract: typeof ContractModule.Contract;
8
- export type Contract<T, W extends Witnesses<T> = Witnesses<T>> = ContractType<T, W>;
9
- export type Ledger = ContractModule.Ledger;
1
+ export * as Leaf from "./managed/leaf/contract/index.js";
2
+ export { type DomainData, type Either, type Maybe, type Witnesses, type Ledger, ledger, Contract } from "./managed/leaf/contract/index.js";
3
+ export { domainToKey, keyToDomain } from "./utils.js";
@@ -1,6 +1,4 @@
1
- export * as Leaf from "./managed/leaf/contract/index.cjs";
2
- import ContractModule from './managed/leaf/contract/index.cjs';
3
- export const ledger = ContractModule.ledger;
4
- export const pureCircuits = ContractModule.pureCircuits;
5
- export const { Contract } = ContractModule;
1
+ export * as Leaf from "./managed/leaf/contract/index.js";
2
+ export { ledger, Contract } from "./managed/leaf/contract/index.js";
3
+ export { domainToKey, keyToDomain } from "./utils.js";
6
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,IAAI,MAAM,mCAAmC,CAAC;AAE1D,OAAO,cAAc,MAAM,mCAAmC,CAAC;AAG/D,MAAM,CAAC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC;AACxD,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAML,MAAM,EACN,QAAQ,EACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}