@midnames/sdk 0.1.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/README.md +46 -0
- package/dist/core.d.ts +9 -0
- package/dist/core.js +204 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/managed/index.d.ts +9 -0
- package/dist/managed/index.js +6 -0
- package/dist/managed/leaf/contract/index.cjs +2739 -0
- package/dist/managed/leaf/contract/index.d.cts +142 -0
- package/dist/managed/witnesses.d.ts +4 -0
- package/dist/managed/witnesses.js +3 -0
- package/dist/react/DomainProfileWidget.d.ts +10 -0
- package/dist/react/DomainProfileWidget.js +100 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/styles.css +33 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.js +61 -0
- package/dist/utils/address.d.ts +3 -0
- package/dist/utils/address.js +24 -0
- package/dist/utils/domain.d.ts +15 -0
- package/dist/utils/domain.js +57 -0
- package/exported.md +116 -0
- package/exports.json +7717 -0
- package/package.json +53 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type * as __compactRuntime from '@midnight-ntwrk/compact-runtime';
|
|
2
|
+
|
|
3
|
+
export type DomainData = { owner: { bytes: Uint8Array };
|
|
4
|
+
resolver: { bytes: Uint8Array }
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export type Either<A, B> = { is_left: boolean; left: A; right: B };
|
|
8
|
+
|
|
9
|
+
export type Maybe<T> = { is_some: boolean; value: T };
|
|
10
|
+
|
|
11
|
+
export type CoinInfo = { nonce: Uint8Array; color: Uint8Array; value: bigint };
|
|
12
|
+
|
|
13
|
+
export type Witnesses<T> = {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ImpureCircuits<T> = {
|
|
17
|
+
update_color(context: __compactRuntime.CircuitContext<T>, c_0: Uint8Array): __compactRuntime.CircuitResults<T, []>;
|
|
18
|
+
update_cost(context: __compactRuntime.CircuitContext<T>, c_0: bigint): __compactRuntime.CircuitResults<T, []>;
|
|
19
|
+
update_target_and_fields(context: __compactRuntime.CircuitContext<T>,
|
|
20
|
+
new_target_0: Either<{ bytes: Uint8Array },
|
|
21
|
+
{ bytes: Uint8Array }>,
|
|
22
|
+
kvs_0: Maybe<[string, string]>[]): __compactRuntime.CircuitResults<T, []>;
|
|
23
|
+
buy_domain_for(context: __compactRuntime.CircuitContext<T>,
|
|
24
|
+
owner_0: { bytes: Uint8Array },
|
|
25
|
+
domain_0: string,
|
|
26
|
+
resolver_0: { bytes: Uint8Array },
|
|
27
|
+
payment_0: CoinInfo): __compactRuntime.CircuitResults<T, []>;
|
|
28
|
+
add_multiple_fields(context: __compactRuntime.CircuitContext<T>,
|
|
29
|
+
kvs_0: Maybe<[string, string]>[]): __compactRuntime.CircuitResults<T, []>;
|
|
30
|
+
insert_field(context: __compactRuntime.CircuitContext<T>,
|
|
31
|
+
k_0: string,
|
|
32
|
+
v_0: string): __compactRuntime.CircuitResults<T, []>;
|
|
33
|
+
clear_field(context: __compactRuntime.CircuitContext<T>, k_0: string): __compactRuntime.CircuitResults<T, []>;
|
|
34
|
+
clear_all_fields(context: __compactRuntime.CircuitContext<T>, domain_0: string): __compactRuntime.CircuitResults<T, []>;
|
|
35
|
+
register_domain_for(context: __compactRuntime.CircuitContext<T>,
|
|
36
|
+
owner_0: { bytes: Uint8Array },
|
|
37
|
+
domain_0: string,
|
|
38
|
+
resolver_0: { bytes: Uint8Array }): __compactRuntime.CircuitResults<T, []>;
|
|
39
|
+
set_resolver(context: __compactRuntime.CircuitContext<T>,
|
|
40
|
+
domain_0: string,
|
|
41
|
+
resolver_0: { bytes: Uint8Array }): __compactRuntime.CircuitResults<T, []>;
|
|
42
|
+
update_domain_target(context: __compactRuntime.CircuitContext<T>,
|
|
43
|
+
new_target_0: Either<{ bytes: Uint8Array },
|
|
44
|
+
{ bytes: Uint8Array }>): __compactRuntime.CircuitResults<T, []>;
|
|
45
|
+
transfer_domain(context: __compactRuntime.CircuitContext<T>,
|
|
46
|
+
domain_0: string,
|
|
47
|
+
new_owner_0: { bytes: Uint8Array }): __compactRuntime.CircuitResults<T, []>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type PureCircuits = {
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type Circuits<T> = {
|
|
54
|
+
update_color(context: __compactRuntime.CircuitContext<T>, c_0: Uint8Array): __compactRuntime.CircuitResults<T, []>;
|
|
55
|
+
update_cost(context: __compactRuntime.CircuitContext<T>, c_0: bigint): __compactRuntime.CircuitResults<T, []>;
|
|
56
|
+
update_target_and_fields(context: __compactRuntime.CircuitContext<T>,
|
|
57
|
+
new_target_0: Either<{ bytes: Uint8Array },
|
|
58
|
+
{ bytes: Uint8Array }>,
|
|
59
|
+
kvs_0: Maybe<[string, string]>[]): __compactRuntime.CircuitResults<T, []>;
|
|
60
|
+
buy_domain_for(context: __compactRuntime.CircuitContext<T>,
|
|
61
|
+
owner_0: { bytes: Uint8Array },
|
|
62
|
+
domain_0: string,
|
|
63
|
+
resolver_0: { bytes: Uint8Array },
|
|
64
|
+
payment_0: CoinInfo): __compactRuntime.CircuitResults<T, []>;
|
|
65
|
+
add_multiple_fields(context: __compactRuntime.CircuitContext<T>,
|
|
66
|
+
kvs_0: Maybe<[string, string]>[]): __compactRuntime.CircuitResults<T, []>;
|
|
67
|
+
insert_field(context: __compactRuntime.CircuitContext<T>,
|
|
68
|
+
k_0: string,
|
|
69
|
+
v_0: string): __compactRuntime.CircuitResults<T, []>;
|
|
70
|
+
clear_field(context: __compactRuntime.CircuitContext<T>, k_0: string): __compactRuntime.CircuitResults<T, []>;
|
|
71
|
+
clear_all_fields(context: __compactRuntime.CircuitContext<T>, domain_0: string): __compactRuntime.CircuitResults<T, []>;
|
|
72
|
+
register_domain_for(context: __compactRuntime.CircuitContext<T>,
|
|
73
|
+
owner_0: { bytes: Uint8Array },
|
|
74
|
+
domain_0: string,
|
|
75
|
+
resolver_0: { bytes: Uint8Array }): __compactRuntime.CircuitResults<T, []>;
|
|
76
|
+
set_resolver(context: __compactRuntime.CircuitContext<T>,
|
|
77
|
+
domain_0: string,
|
|
78
|
+
resolver_0: { bytes: Uint8Array }): __compactRuntime.CircuitResults<T, []>;
|
|
79
|
+
update_domain_target(context: __compactRuntime.CircuitContext<T>,
|
|
80
|
+
new_target_0: Either<{ bytes: Uint8Array },
|
|
81
|
+
{ bytes: Uint8Array }>): __compactRuntime.CircuitResults<T, []>;
|
|
82
|
+
transfer_domain(context: __compactRuntime.CircuitContext<T>,
|
|
83
|
+
domain_0: string,
|
|
84
|
+
new_owner_0: { bytes: Uint8Array }): __compactRuntime.CircuitResults<T, []>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type Ledger = {
|
|
88
|
+
readonly PARENT_DOMAIN: Maybe<string>;
|
|
89
|
+
readonly PARENT_RESOLVER: { bytes: Uint8Array };
|
|
90
|
+
readonly DOMAIN_OWNER: { bytes: Uint8Array };
|
|
91
|
+
readonly DOMAIN: Maybe<string>;
|
|
92
|
+
readonly DOMAIN_TARGET: Either<{ bytes: Uint8Array }, { bytes: Uint8Array }>;
|
|
93
|
+
domains: {
|
|
94
|
+
isEmpty(): boolean;
|
|
95
|
+
size(): bigint;
|
|
96
|
+
member(key_0: string): boolean;
|
|
97
|
+
lookup(key_0: string): DomainData;
|
|
98
|
+
[Symbol.iterator](): Iterator<[string, DomainData]>
|
|
99
|
+
};
|
|
100
|
+
domains_owned: {
|
|
101
|
+
isEmpty(): boolean;
|
|
102
|
+
size(): bigint;
|
|
103
|
+
member(key_0: { bytes: Uint8Array }): boolean;
|
|
104
|
+
lookup(key_0: { bytes: Uint8Array }): {
|
|
105
|
+
isEmpty(): boolean;
|
|
106
|
+
size(): bigint;
|
|
107
|
+
member(elem_0: string): boolean;
|
|
108
|
+
[Symbol.iterator](): Iterator<string>
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
fields: {
|
|
112
|
+
isEmpty(): boolean;
|
|
113
|
+
size(): bigint;
|
|
114
|
+
member(key_0: string): boolean;
|
|
115
|
+
lookup(key_0: string): string;
|
|
116
|
+
[Symbol.iterator](): Iterator<[string, string]>
|
|
117
|
+
};
|
|
118
|
+
readonly COIN_COLOR: Uint8Array;
|
|
119
|
+
readonly DOMAIN_COST: bigint;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export type ContractReferenceLocations = any;
|
|
123
|
+
|
|
124
|
+
export declare const contractReferenceLocations : ContractReferenceLocations;
|
|
125
|
+
|
|
126
|
+
export declare class Contract<T, W extends Witnesses<T> = Witnesses<T>> {
|
|
127
|
+
witnesses: W;
|
|
128
|
+
circuits: Circuits<T>;
|
|
129
|
+
impureCircuits: ImpureCircuits<T>;
|
|
130
|
+
constructor(witnesses: W);
|
|
131
|
+
initialState(context: __compactRuntime.ConstructorContext<T>,
|
|
132
|
+
parent_domain_0: Maybe<string>,
|
|
133
|
+
parent_resolver_0: { bytes: Uint8Array },
|
|
134
|
+
target_0: Either<{ bytes: Uint8Array }, { bytes: Uint8Array }>,
|
|
135
|
+
domain_0: Maybe<string>,
|
|
136
|
+
coin_color_0: Uint8Array,
|
|
137
|
+
domain_cost_0: bigint,
|
|
138
|
+
kvs_0: Maybe<[string, string]>[]): __compactRuntime.ConstructorResult<T>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export declare function ledger(state: __compactRuntime.StateValue): Ledger;
|
|
142
|
+
export declare const pureCircuits: PureCircuits;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PublicDataProvider } from '@midnight-ntwrk/midnight-js-types';
|
|
2
|
+
import { MidNamesError } from '../types.js';
|
|
3
|
+
export type DomainProfileWidgetProps = {
|
|
4
|
+
fullDomain: string;
|
|
5
|
+
publicDataProvider: PublicDataProvider;
|
|
6
|
+
className?: string;
|
|
7
|
+
showStatus?: boolean;
|
|
8
|
+
onError?: (error: MidNamesError) => void;
|
|
9
|
+
};
|
|
10
|
+
export declare function DomainProfileWidget({ fullDomain, publicDataProvider, className, showStatus, onError }: DomainProfileWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { MidNamesError } from '../types.js';
|
|
4
|
+
import { deriveShieldedAddress } from '../utils/address.js';
|
|
5
|
+
import { Copy, Check } from 'lucide-react';
|
|
6
|
+
import { getDomainProfile } from '../core.js';
|
|
7
|
+
function truncate(addr, head = 10, tail = 6) {
|
|
8
|
+
if (!addr)
|
|
9
|
+
return 'N/A';
|
|
10
|
+
if (addr.length <= head + tail + 3)
|
|
11
|
+
return addr;
|
|
12
|
+
return `${addr.slice(0, head)}…${addr.slice(-tail)}`;
|
|
13
|
+
}
|
|
14
|
+
function CopyableValue({ value, className }) {
|
|
15
|
+
const [copied, setCopied] = useState(false);
|
|
16
|
+
const [hovered, setHovered] = useState(false);
|
|
17
|
+
if (!value)
|
|
18
|
+
return _jsx("span", { className: className, children: "N/A" });
|
|
19
|
+
const copy = async () => {
|
|
20
|
+
try {
|
|
21
|
+
await navigator.clipboard.writeText(value);
|
|
22
|
+
setCopied(true);
|
|
23
|
+
setTimeout(() => setCopied(false), 1500);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Silently fail if clipboard API is not available
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return (_jsxs("span", { className: `${className} midnames-copyable`, onClick: copy, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), title: value, children: [truncate(value), _jsx("span", { className: "midnames-copy-icon-container", children: copied ? (_jsx(Check, { className: "midnames-copy-icon midnames-copy-success" })) : (_jsx(Copy, { className: `midnames-copy-icon midnames-copy-hover ${hovered ? 'midnames-copy-visible' : 'midnames-copy-invisible'}` })) })] }));
|
|
30
|
+
}
|
|
31
|
+
export function DomainProfileWidget({ fullDomain, publicDataProvider, className, showStatus = true, onError }) {
|
|
32
|
+
var _a, _b, _c, _d, _e;
|
|
33
|
+
const [loading, setLoading] = useState(false);
|
|
34
|
+
const [data, setData] = useState(null);
|
|
35
|
+
const [error, setError] = useState(null);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
let mounted = true;
|
|
38
|
+
setLoading(true);
|
|
39
|
+
setError(null);
|
|
40
|
+
getDomainProfile(publicDataProvider, fullDomain)
|
|
41
|
+
.then((d) => {
|
|
42
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
43
|
+
if (mounted) {
|
|
44
|
+
if (d.success) {
|
|
45
|
+
setData(d.data);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
setError(new MidNamesError((_b = (_a = d.error) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : 'Unknown error', (_d = (_c = d.error) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : 'UNKNOWN', d.error));
|
|
49
|
+
if (onError)
|
|
50
|
+
onError(new MidNamesError((_f = (_e = d.error) === null || _e === void 0 ? void 0 : _e.message) !== null && _f !== void 0 ? _f : 'Unknown error', (_h = (_g = d.error) === null || _g === void 0 ? void 0 : _g.code) !== null && _h !== void 0 ? _h : 'UNKNOWN', d.error));
|
|
51
|
+
setData(null);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.catch((err) => {
|
|
56
|
+
if (mounted) {
|
|
57
|
+
const midnamesError = err instanceof MidNamesError ? err : new MidNamesError('Unknown error', 'UNKNOWN', err);
|
|
58
|
+
setError(midnamesError);
|
|
59
|
+
if (onError)
|
|
60
|
+
onError(midnamesError);
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
.finally(() => mounted && setLoading(false));
|
|
64
|
+
return () => {
|
|
65
|
+
mounted = false;
|
|
66
|
+
};
|
|
67
|
+
}, [publicDataProvider, fullDomain, onError]);
|
|
68
|
+
const fieldsMap = useMemo(() => {
|
|
69
|
+
const m = {};
|
|
70
|
+
((data === null || data === void 0 ? void 0 : data.fields) || []).forEach(([k, v]) => (m[k.toLowerCase()] = v));
|
|
71
|
+
return m;
|
|
72
|
+
}, [data]);
|
|
73
|
+
const displayName = fieldsMap['name'] || fieldsMap['displayname'] || fieldsMap['handle'] || '';
|
|
74
|
+
const bio = fieldsMap['bio'] || fieldsMap['description'] || '';
|
|
75
|
+
const website = fieldsMap['website'] || fieldsMap['url'] || '';
|
|
76
|
+
const twitter = (fieldsMap['twitter'] || '').replace(/^@/, '');
|
|
77
|
+
const github = (fieldsMap['github'] || '').replace(/^@/, '');
|
|
78
|
+
const location = fieldsMap['location'] || '';
|
|
79
|
+
const avatarUrl = fieldsMap['avatar'] || fieldsMap['image'] || fieldsMap['pfp'] || '';
|
|
80
|
+
const bannerUrl = fieldsMap['banner'] || fieldsMap['header'] || '';
|
|
81
|
+
const epk = fieldsMap['epk'];
|
|
82
|
+
const resolvedTarget = useMemo(() => {
|
|
83
|
+
if (!(data === null || data === void 0 ? void 0 : data.resolvedTarget))
|
|
84
|
+
return null;
|
|
85
|
+
if (epk)
|
|
86
|
+
return deriveShieldedAddress(data.resolvedTarget, epk) || data.resolvedTarget;
|
|
87
|
+
return data.resolvedTarget;
|
|
88
|
+
}, [data === null || data === void 0 ? void 0 : data.resolvedTarget, epk]);
|
|
89
|
+
const status = useMemo(() => {
|
|
90
|
+
if (loading)
|
|
91
|
+
return 'unknown';
|
|
92
|
+
if (error)
|
|
93
|
+
return 'error';
|
|
94
|
+
return (data === null || data === void 0 ? void 0 : data.info) ? 'registered' : 'available';
|
|
95
|
+
}, [loading, data === null || data === void 0 ? void 0 : data.info, error]);
|
|
96
|
+
if (error && !loading) {
|
|
97
|
+
return (_jsx("div", { className: `midnames-card ${className !== null && className !== void 0 ? className : ''}`, children: _jsxs("div", { className: "midnames-error", children: [_jsx("div", { className: "midnames-error-title", children: "Error loading domain" }), _jsx("div", { className: "midnames-error-message", children: error.message }), _jsxs("div", { className: "midnames-error-code", children: ["Code: ", error.code] })] }) }));
|
|
98
|
+
}
|
|
99
|
+
return (_jsxs("div", { className: `midnames-card ${className !== null && className !== void 0 ? className : ''}`, children: [bannerUrl && _jsx("img", { src: bannerUrl, alt: "", className: "midnames-banner" }), _jsxs("div", { className: "midnames-header", children: [_jsx("div", { className: "midnames-avatar", children: avatarUrl ? (_jsx("img", { src: avatarUrl, alt: "", onError: (e) => (e.currentTarget.style.display = 'none') })) : (_jsx("span", { children: (_c = (_b = (_a = (displayName || (data === null || data === void 0 ? void 0 : data.fullDomain) || '?')[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : '?' })) }), _jsxs("div", { className: "midnames-ident", children: [_jsx("div", { className: "midnames-name", children: displayName || (data === null || data === void 0 ? void 0 : data.fullDomain) || fullDomain }), _jsx("div", { className: "midnames-domain", children: (data === null || data === void 0 ? void 0 : data.fullDomain) || fullDomain })] }), showStatus && (_jsx("div", { className: `midnames-status midnames-status-${status}`, children: loading ? 'Checking…' : status === 'registered' ? 'Registered' : status === 'available' ? 'Available' : status === 'error' ? 'Error' : 'Unknown' }))] }), bio && _jsx("p", { className: "midnames-bio", children: bio }), _jsxs("div", { className: "midnames-grid", children: [_jsxs("div", { className: "midnames-box", children: [_jsx("div", { className: "midnames-box-label", children: "Resolved Target" }), _jsx(CopyableValue, { value: resolvedTarget, className: "midnames-box-value" })] }), _jsxs("div", { className: "midnames-box", children: [_jsx("div", { className: "midnames-box-label", children: "Owner" }), _jsx(CopyableValue, { value: (_d = data === null || data === void 0 ? void 0 : data.info) === null || _d === void 0 ? void 0 : _d.owner, className: "midnames-box-value" })] }), _jsxs("div", { className: "midnames-box", children: [_jsx("div", { className: "midnames-box-label", children: "Resolver" }), _jsx(CopyableValue, { value: (_e = data === null || data === void 0 ? void 0 : data.info) === null || _e === void 0 ? void 0 : _e.resolver, className: "midnames-box-value" })] })] }), _jsxs("div", { className: "midnames-links", children: [website && (_jsx("a", { className: "midnames-chip", href: website.startsWith('http') ? website : `https://${website}`, target: "_blank", rel: "noreferrer", children: website.replace(/^https?:\/\//, '') })), twitter && (_jsxs("a", { className: "midnames-chip", href: `https://x.com/${twitter}`, target: "_blank", rel: "noreferrer", children: ["@", twitter] })), github && (_jsx("a", { className: "midnames-chip", href: `https://github.com/${github}`, target: "_blank", rel: "noreferrer", children: github })), location && _jsx("span", { className: "midnames-chip", children: location })] })] }));
|
|
100
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DomainProfileWidget.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DomainProfileWidget.js';
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
.midnames-card{border:1px solid rgba(255,255,255,.12);background:transparent;border-radius:12px;padding:12px;max-width:640px}
|
|
2
|
+
.midnames-banner{width:100%;height:120px;object-fit:cover;border-radius:8px}
|
|
3
|
+
.midnames-header{display:flex;gap:12px;align-items:center;margin-top:8px}
|
|
4
|
+
.midnames-avatar{height:64px;width:64px;border-radius:9999px;background:rgba(0,170,255,.1);color:#0af;display:flex;align-items:center;justify-content:center;font-weight:600;overflow:hidden}
|
|
5
|
+
.midnames-avatar img{width:100%;height:100%;object-fit:cover}
|
|
6
|
+
.midnames-ident{flex:1 1 auto;min-width:0}
|
|
7
|
+
.midnames-name{font-size:20px;font-weight:600;line-height:1.2}
|
|
8
|
+
.midnames-domain{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;opacity:.7}
|
|
9
|
+
.midnames-status{font-size:12px;border-radius:9999px;padding:4px 8px;border:1px solid rgba(255,255,255,.2)}
|
|
10
|
+
.midnames-status-registered{border-color:#1fbf75;color:#1fbf75}
|
|
11
|
+
.midnames-status-available{border-color:#f0b429;color:#f0b429}
|
|
12
|
+
.midnames-bio{margin:8px 2px 0 2px;font-size:14px;opacity:.85}
|
|
13
|
+
.midnames-grid{display:grid;grid-template-columns:repeat(1,minmax(0,1fr));gap:8px;margin-top:12px}
|
|
14
|
+
@media(min-width:720px){.midnames-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
|
|
15
|
+
.midnames-box{border:1px solid rgba(255,255,255,.12);border-radius:8px;padding:8px}
|
|
16
|
+
.midnames-box-label{font-size:11px;opacity:.7}
|
|
17
|
+
.midnames-box-value{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:13px;margin-top:4px}
|
|
18
|
+
.midnames-links{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
|
|
19
|
+
.midnames-chip{border:1px solid rgba(255,255,255,.12);border-radius:9999px;padding:6px 10px;font-size:12px;text-decoration:none;color:inherit}
|
|
20
|
+
.midnames-status-error{border-color:#ef4444;color:#ef4444}
|
|
21
|
+
.midnames-error{padding:16px;text-align:center}
|
|
22
|
+
.midnames-error-title{font-size:16px;font-weight:600;color:#ef4444;margin-bottom:8px}
|
|
23
|
+
.midnames-error-message{font-size:14px;opacity:.85;margin-bottom:4px}
|
|
24
|
+
.midnames-error-code{font-size:12px;opacity:.7;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}
|
|
25
|
+
.midnames-copyable{cursor:pointer;display:inline-flex;align-items:center;gap:4px}
|
|
26
|
+
.midnames-copy-icon-container{width:16px;display:inline-flex;justify-content:center;align-items:center}
|
|
27
|
+
.midnames-copy-icon{width:12px;height:12px;transition:opacity 0.2s ease}
|
|
28
|
+
.midnames-copy-hover{opacity:.8}
|
|
29
|
+
.midnames-copy-hover:hover{opacity:1}
|
|
30
|
+
.midnames-copy-success{color:#22c55e;opacity:1}
|
|
31
|
+
.midnames-copy-visible{opacity:.8}
|
|
32
|
+
.midnames-copy-invisible{opacity:0}
|
|
33
|
+
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface DomainInfo {
|
|
2
|
+
owner: string;
|
|
3
|
+
resolver: string;
|
|
4
|
+
contractAddress?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DomainSettings {
|
|
7
|
+
coinColor: Uint8Array;
|
|
8
|
+
domainCost: bigint;
|
|
9
|
+
}
|
|
10
|
+
export interface DomainProfileData {
|
|
11
|
+
fullDomain: string;
|
|
12
|
+
resolvedTarget: string | null;
|
|
13
|
+
info: DomainInfo | null;
|
|
14
|
+
fields: Array<[string, string]>;
|
|
15
|
+
settings: DomainSettings | null;
|
|
16
|
+
}
|
|
17
|
+
export declare class MidNamesError extends Error {
|
|
18
|
+
readonly code: string;
|
|
19
|
+
readonly details?: unknown | undefined;
|
|
20
|
+
constructor(message: string, code: string, details?: unknown | undefined);
|
|
21
|
+
}
|
|
22
|
+
export declare class NetworkError extends MidNamesError {
|
|
23
|
+
constructor(message: string, details?: unknown);
|
|
24
|
+
}
|
|
25
|
+
export declare class ContractNotFoundError extends MidNamesError {
|
|
26
|
+
constructor(contractAddress: string, details?: unknown);
|
|
27
|
+
}
|
|
28
|
+
export declare class DomainNotFoundError extends MidNamesError {
|
|
29
|
+
constructor(domain: string, details?: unknown);
|
|
30
|
+
}
|
|
31
|
+
export declare class InvalidDomainError extends MidNamesError {
|
|
32
|
+
constructor(domain: string, reason: string, details?: unknown);
|
|
33
|
+
}
|
|
34
|
+
export declare class ProviderError extends MidNamesError {
|
|
35
|
+
constructor(message: string, details?: unknown);
|
|
36
|
+
}
|
|
37
|
+
export type Result<T, E = MidNamesError> = {
|
|
38
|
+
success: true;
|
|
39
|
+
data: T;
|
|
40
|
+
} | {
|
|
41
|
+
success: false;
|
|
42
|
+
error: E;
|
|
43
|
+
};
|
|
44
|
+
export declare function success<T>(data: T): Result<T>;
|
|
45
|
+
export declare function failure<E = MidNamesError>(error: E): Result<never, E>;
|
|
46
|
+
export declare function isSuccess<T, E>(result: Result<T, E>): result is {
|
|
47
|
+
success: true;
|
|
48
|
+
data: T;
|
|
49
|
+
};
|
|
50
|
+
export declare function isError<T, E>(result: Result<T, E>): result is {
|
|
51
|
+
success: false;
|
|
52
|
+
error: E;
|
|
53
|
+
};
|
|
54
|
+
export declare function unwrap<T>(result: Result<T>): T;
|
|
55
|
+
export declare function unwrapOr<T>(result: Result<T>, defaultValue: T): T;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
}
|
|
40
|
+
// Helper functions for Result type
|
|
41
|
+
export function success(data) {
|
|
42
|
+
return { success: true, data };
|
|
43
|
+
}
|
|
44
|
+
export function failure(error) {
|
|
45
|
+
return { success: false, error };
|
|
46
|
+
}
|
|
47
|
+
export function isSuccess(result) {
|
|
48
|
+
return result.success;
|
|
49
|
+
}
|
|
50
|
+
export function isError(result) {
|
|
51
|
+
return !result.success;
|
|
52
|
+
}
|
|
53
|
+
export function unwrap(result) {
|
|
54
|
+
if (isSuccess(result)) {
|
|
55
|
+
return result.data;
|
|
56
|
+
}
|
|
57
|
+
throw result.error;
|
|
58
|
+
}
|
|
59
|
+
export function unwrapOr(result, defaultValue) {
|
|
60
|
+
return isSuccess(result) ? result.data : defaultValue;
|
|
61
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MidnightBech32m, ShieldedCoinPublicKey, ShieldedAddress } from "@midnight-ntwrk/wallet-sdk-address-format";
|
|
2
|
+
import { getZswapNetworkId } from "@midnight-ntwrk/midnight-js-network-id";
|
|
3
|
+
export function bytesToHex(bytes) {
|
|
4
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
5
|
+
}
|
|
6
|
+
export function formatContractAddress(bytes) {
|
|
7
|
+
return '0200' + bytesToHex(bytes);
|
|
8
|
+
}
|
|
9
|
+
export function deriveShieldedAddress(coinPublicKeyAddress, encryptionPublicKey) {
|
|
10
|
+
try {
|
|
11
|
+
const cpkParsed = MidnightBech32m.parse(coinPublicKeyAddress);
|
|
12
|
+
if (cpkParsed.type !== 'shield-cpk')
|
|
13
|
+
return null;
|
|
14
|
+
const coinPublicKey = ShieldedCoinPublicKey.codec.decode(getZswapNetworkId(), cpkParsed);
|
|
15
|
+
const epkParsed = MidnightBech32m.parse(encryptionPublicKey);
|
|
16
|
+
if (epkParsed.type !== 'shield-epk')
|
|
17
|
+
return null;
|
|
18
|
+
const shieldedAddress = new ShieldedAddress(coinPublicKey, epkParsed);
|
|
19
|
+
return ShieldedAddress.codec.encode(getZswapNetworkId(), shieldedAddress).asString();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function normalizeDomain(input: string, assumeTld?: boolean): string;
|
|
2
|
+
export interface ParsedDomain {
|
|
3
|
+
isValid: boolean;
|
|
4
|
+
domainName: string;
|
|
5
|
+
parentDomainPath: string;
|
|
6
|
+
fullDomain: string;
|
|
7
|
+
depth: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseFullDomain(fullDomain: string, tld?: string): ParsedDomain;
|
|
10
|
+
export declare function buildTraversalPath(fullDomain: string, tld?: string): string[];
|
|
11
|
+
export declare function isValidDomainName(domainName: string): boolean;
|
|
12
|
+
export declare function getParentDomain(fullDomain: string): string | null;
|
|
13
|
+
export declare function getSubdomain(fullDomain: string): string;
|
|
14
|
+
export declare function isTLD(domain: string, tld?: string): boolean;
|
|
15
|
+
export declare function buildFullDomain(subdomain: string, parent: string): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const DEFAULT_TLD = 'night';
|
|
2
|
+
export function normalizeDomain(input, assumeTld = true) {
|
|
3
|
+
const trimmedInput = input.trim().toLowerCase();
|
|
4
|
+
const cleaned = trimmedInput.replace(/\.+/g, '.').replace(/\.$/, '');
|
|
5
|
+
if (!assumeTld)
|
|
6
|
+
return cleaned;
|
|
7
|
+
if (cleaned.endsWith(`.${DEFAULT_TLD}`))
|
|
8
|
+
return cleaned;
|
|
9
|
+
return `${cleaned}.${DEFAULT_TLD}`;
|
|
10
|
+
}
|
|
11
|
+
export function parseFullDomain(fullDomain, tld = DEFAULT_TLD) {
|
|
12
|
+
const normalized = normalizeDomain(fullDomain);
|
|
13
|
+
const parts = normalized.split('.');
|
|
14
|
+
if (parts[parts.length - 1] !== tld || parts.length < 2) {
|
|
15
|
+
return { isValid: false, domainName: '', parentDomainPath: '', fullDomain: normalized, depth: 0 };
|
|
16
|
+
}
|
|
17
|
+
const domainName = parts[0];
|
|
18
|
+
const parentDomainPath = parts.slice(1).join('.');
|
|
19
|
+
return { isValid: true, domainName, parentDomainPath, fullDomain: normalized, depth: parts.length - 1 };
|
|
20
|
+
}
|
|
21
|
+
export function buildTraversalPath(fullDomain, tld = DEFAULT_TLD) {
|
|
22
|
+
const parsed = parseFullDomain(fullDomain, tld);
|
|
23
|
+
if (!parsed.isValid)
|
|
24
|
+
return [];
|
|
25
|
+
const path = [tld];
|
|
26
|
+
if (parsed.depth === 0)
|
|
27
|
+
return path;
|
|
28
|
+
const parts = parsed.fullDomain.split('.');
|
|
29
|
+
for (let i = parts.length - 2; i >= 0; i--) {
|
|
30
|
+
path.push(parts.slice(i).join('.'));
|
|
31
|
+
}
|
|
32
|
+
return path;
|
|
33
|
+
}
|
|
34
|
+
export function isValidDomainName(domainName) {
|
|
35
|
+
if (!domainName || domainName.length === 0 || domainName.length > 63)
|
|
36
|
+
return false;
|
|
37
|
+
const regex = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
38
|
+
return regex.test(domainName.toLowerCase());
|
|
39
|
+
}
|
|
40
|
+
export function getParentDomain(fullDomain) {
|
|
41
|
+
const parts = fullDomain.split('.');
|
|
42
|
+
if (parts.length <= 1)
|
|
43
|
+
return null;
|
|
44
|
+
return parts.slice(1).join('.');
|
|
45
|
+
}
|
|
46
|
+
export function getSubdomain(fullDomain) {
|
|
47
|
+
const parts = fullDomain.split('.');
|
|
48
|
+
return parts[0] || '';
|
|
49
|
+
}
|
|
50
|
+
export function isTLD(domain, tld = DEFAULT_TLD) {
|
|
51
|
+
return normalizeDomain(domain, false) === tld;
|
|
52
|
+
}
|
|
53
|
+
export function buildFullDomain(subdomain, parent) {
|
|
54
|
+
if (!subdomain)
|
|
55
|
+
return parent;
|
|
56
|
+
return `${subdomain}.${parent}`;
|
|
57
|
+
}
|
package/exported.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# MidNames SDK - Exported Signatures
|
|
2
|
+
|
|
3
|
+
This document contains all exported functions, types, interfaces, classes, and components from the MidNames SDK.
|
|
4
|
+
|
|
5
|
+
## Functions
|
|
6
|
+
|
|
7
|
+
### Core
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export function resolveDomain(publicDataProvider: PublicDataProvider, domain: string, tldAddress?: string): Promise<Result<string>>
|
|
11
|
+
```
|
|
12
|
+
Resolves a domain name to its target address.
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
export function getDomainInfo(publicDataProvider: PublicDataProvider, contractAddress: string, domainName: string): Promise<Result<DomainInfo>>
|
|
16
|
+
```
|
|
17
|
+
Gets information about a domain from a specific contract.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
export function getDomainInfoByResolving(publicDataProvider: PublicDataProvider, fullDomain: string): Promise<Result<DomainInfo>>
|
|
21
|
+
```
|
|
22
|
+
Gets domain information by resolving the full domain path.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
export function getDomainFields(publicDataProvider: PublicDataProvider, contractAddress: string): Promise<Result<tuple[]>>
|
|
26
|
+
```
|
|
27
|
+
Gets all fields stored in a domain contract.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
export function getNamespacedDomainFields(publicDataProvider: PublicDataProvider, _parentContractAddress: string, fullDomainName: string): Promise<Result<tuple[]>>
|
|
31
|
+
```
|
|
32
|
+
Gets fields for a domain by resolving its full namespace path.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
export function getDomainSettings(publicDataProvider: PublicDataProvider, contractAddress: string): Promise<Result<DomainSettings>>
|
|
36
|
+
```
|
|
37
|
+
Gets the settings (coin color, domain cost) for a domain contract.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
export function getDomainProfile(publicDataProvider: PublicDataProvider, fullDomain: string): Promise<Result<DomainProfileData>>
|
|
41
|
+
```
|
|
42
|
+
Gets the complete profile data for a domain.
|
|
43
|
+
|
|
44
|
+
### Domain Utility Functions
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
export function normalizeDomain(input: string, assumeTld: boolean): string
|
|
48
|
+
```
|
|
49
|
+
Normalizes a domain string by cleaning and formatting it.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
export function parseFullDomain(fullDomain: string, tld: string): ParsedDomain
|
|
53
|
+
```
|
|
54
|
+
Parses a full domain string into its component parts.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
export function buildTraversalPath(fullDomain: string, tld: string): string[]
|
|
58
|
+
```
|
|
59
|
+
Builds the traversal path for resolving a domain.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
export function isValidDomainName(domainName: string): boolean
|
|
63
|
+
```
|
|
64
|
+
Validates if a domain name follows the correct format.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
export function getParentDomain(fullDomain: string): null | string
|
|
68
|
+
```
|
|
69
|
+
Gets the parent domain of a given domain.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
export function getSubdomain(fullDomain: string): string
|
|
73
|
+
```
|
|
74
|
+
Extracts the subdomain portion from a full domain.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
export function isTLD(domain: string, tld: string): boolean
|
|
78
|
+
```
|
|
79
|
+
Checks if a domain is a top-level domain.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
export function buildFullDomain(subdomain: string, parent: string): string
|
|
83
|
+
```
|
|
84
|
+
Builds a full domain from subdomain and parent parts.
|
|
85
|
+
|
|
86
|
+
### Address Utility Functions
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
export function bytesToHex(bytes: Uint8Array): string
|
|
90
|
+
```
|
|
91
|
+
Converts a byte array to a hexadecimal string.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
export function formatContractAddress(bytes: Uint8Array): string
|
|
95
|
+
```
|
|
96
|
+
Formats a contract address from bytes with proper prefix.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
export function deriveShieldedAddress(coinPublicKeyAddress: string, encryptionPublicKey: string): null | string
|
|
100
|
+
```
|
|
101
|
+
Derives a shielded address from coin public key and encryption key.
|
|
102
|
+
|
|
103
|
+
## React Components
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
export type DomainProfileWidgetProps = {
|
|
107
|
+
fullDomain: string;
|
|
108
|
+
publicDataProvider: PublicDataProvider;
|
|
109
|
+
className?: string;
|
|
110
|
+
showStatus?: boolean;
|
|
111
|
+
onError?: (error: MidNamesError) => void;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function DomainProfileWidget(props: DomainProfileWidgetProps): JSX.Element
|
|
115
|
+
```
|
|
116
|
+
React component for displaying domain profile information.
|