@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.
- package/dist/controller-types.d.ts +104 -0
- package/dist/controller-types.js +16 -0
- package/dist/core.d.ts +13 -9
- package/dist/core.js +158 -67
- package/dist/errors.d.ts +20 -0
- package/dist/errors.js +39 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/managed/index.d.ts +3 -9
- package/dist/managed/index.js +3 -5
- package/dist/managed/index.js.map +1 -1
- package/dist/managed/leaf.compact +97 -65
- package/dist/managed/managed/leaf/contract/index.d.ts +197 -0
- package/dist/managed/managed/leaf/contract/index.js +3094 -0
- package/dist/managed/managed/leaf/contract/index.js.map +8 -0
- package/dist/managed/utils.d.ts +5 -0
- package/dist/managed/utils.js +19 -0
- package/dist/managed/utils.js.map +1 -0
- package/dist/operations.d.ts +49 -0
- package/dist/operations.js +137 -0
- package/dist/provider.d.ts +10 -4
- package/dist/provider.js +32 -8
- package/dist/react/DomainProfileWidget.d.ts +2 -2
- package/dist/react/DomainProfileWidget.js +11 -8
- package/dist/react/HolographicCard.d.ts +2 -2
- package/dist/react/HolographicCard.js +10 -7
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -2
- package/dist/results.d.ts +38 -0
- package/dist/results.js +88 -0
- package/dist/types.d.ts +7 -41
- package/dist/types.js +1 -61
- package/dist/utils/address.js +6 -5
- package/dist/utils/domain.d.ts +6 -0
- package/dist/utils/domain.js +19 -1
- package/dist/utils/imageResolver.d.ts +8 -0
- package/dist/utils/imageResolver.js +89 -0
- package/dist/utils/sanitize.d.ts +6 -0
- package/dist/utils/sanitize.js +28 -0
- package/exported.md +1 -1
- package/managed/index.js +3 -5
- package/managed/index.js.map +1 -1
- package/managed/leaf.compact +97 -65
- package/managed/managed/leaf/contract/index.js +3094 -0
- package/managed/managed/leaf/contract/index.js.map +8 -0
- package/managed/utils.js +19 -0
- package/managed/utils.js.map +1 -0
- package/package.json +22 -11
- package/dist/managed/managed/leaf/contract/index.cjs +0 -2789
- package/dist/managed/managed/leaf/contract/index.cjs.map +0 -8
- package/dist/managed/managed/leaf/contract/index.d.cts +0 -146
- package/managed/managed/leaf/contract/index.cjs +0 -2789
- package/managed/managed/leaf/contract/index.cjs.map +0 -8
- package/managed/managed/leaf/contract/index.d.cts +0 -146
- 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
|
|
2
|
-
import
|
|
3
|
-
|
|
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(
|
|
15
|
+
export declare function getDomainFields(fullDomain: string, options?: {
|
|
15
16
|
provider?: PublicDataProvider;
|
|
16
|
-
}): Promise<Result<
|
|
17
|
-
export declare function getDomainSettings(
|
|
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
|
|
2
|
-
import { ShieldedCoinPublicKey } from
|
|
3
|
-
import { ledger } from
|
|
4
|
-
import { formatContractAddress } from
|
|
5
|
-
import { normalizeDomain, parseFullDomain } from
|
|
6
|
-
import { success, failure,
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
export const TESTNET_TLD_ADDRESS =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
31
|
+
throw new ContractNotFoundError(contractAddress, undefined);
|
|
34
32
|
}
|
|
35
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
112
|
-
|
|
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,
|
|
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({
|
|
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
|
-
|
|
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
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
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(
|
|
176
|
+
export async function getDomainSettings(fullDomain, options = {}) {
|
|
155
177
|
const publicDataProvider = options.provider || getDefaultProvider();
|
|
156
178
|
try {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
|
224
|
+
const resolvedTarget = resolvedTargetResult.success
|
|
225
|
+
? resolvedTargetResult.data
|
|
226
|
+
: null;
|
|
176
227
|
const info = infoResult.success ? infoResult.data : null;
|
|
177
|
-
if (info && info.
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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({
|
|
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
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -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';
|
package/dist/managed/index.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
|
|
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";
|
package/dist/managed/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export * as Leaf from "./managed/leaf/contract/index.
|
|
2
|
-
|
|
3
|
-
export
|
|
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":"
|
|
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"}
|