@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
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type { DomainData } from "../managed/index.js";
|
|
1
2
|
export interface DomainInfo {
|
|
2
3
|
owner: string;
|
|
3
4
|
resolver: string;
|
|
@@ -5,51 +6,16 @@ export interface DomainInfo {
|
|
|
5
6
|
}
|
|
6
7
|
export interface DomainSettings {
|
|
7
8
|
coinColor: Uint8Array;
|
|
8
|
-
|
|
9
|
+
costs: {
|
|
10
|
+
short: bigint;
|
|
11
|
+
medium: bigint;
|
|
12
|
+
long: bigint;
|
|
13
|
+
};
|
|
9
14
|
}
|
|
10
15
|
export interface DomainProfileData {
|
|
11
16
|
fullDomain: string;
|
|
12
17
|
resolvedTarget: string | null;
|
|
13
18
|
info: DomainInfo | null;
|
|
14
|
-
fields:
|
|
19
|
+
fields: Map<string, string>;
|
|
15
20
|
settings: DomainSettings | null;
|
|
16
21
|
}
|
|
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
CHANGED
|
@@ -1,61 +1 @@
|
|
|
1
|
-
|
|
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
|
-
}
|
|
1
|
+
export {};
|
package/dist/utils/address.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MidnightBech32m, ShieldedCoinPublicKey, ShieldedAddress } from "@midnight-ntwrk/wallet-sdk-address-format";
|
|
2
|
-
import {
|
|
1
|
+
import { MidnightBech32m, ShieldedCoinPublicKey, ShieldedAddress, ShieldedEncryptionPublicKey } from "@midnight-ntwrk/wallet-sdk-address-format";
|
|
2
|
+
import { getNetworkId } from "@midnight-ntwrk/midnight-js-network-id";
|
|
3
3
|
export function bytesToHex(bytes) {
|
|
4
4
|
return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
5
5
|
}
|
|
@@ -11,12 +11,13 @@ export function deriveShieldedAddress(coinPublicKeyAddress, encryptionPublicKey)
|
|
|
11
11
|
const cpkParsed = MidnightBech32m.parse(coinPublicKeyAddress);
|
|
12
12
|
if (cpkParsed.type !== 'shield-cpk')
|
|
13
13
|
return null;
|
|
14
|
-
const coinPublicKey = ShieldedCoinPublicKey.codec.decode(
|
|
14
|
+
const coinPublicKey = ShieldedCoinPublicKey.codec.decode(getNetworkId(), cpkParsed);
|
|
15
15
|
const epkParsed = MidnightBech32m.parse(encryptionPublicKey);
|
|
16
16
|
if (epkParsed.type !== 'shield-epk')
|
|
17
17
|
return null;
|
|
18
|
-
const
|
|
19
|
-
|
|
18
|
+
const encPubKey = ShieldedEncryptionPublicKey.codec.decode(getNetworkId(), epkParsed);
|
|
19
|
+
const shieldedAddress = new ShieldedAddress(coinPublicKey, encPubKey);
|
|
20
|
+
return ShieldedAddress.codec.encode(getNetworkId(), shieldedAddress).asString();
|
|
20
21
|
}
|
|
21
22
|
catch {
|
|
22
23
|
return null;
|
package/dist/utils/domain.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const DEFAULT_TLD = "night";
|
|
1
2
|
export declare function normalizeDomain(input: string, assumeTld?: boolean): string;
|
|
2
3
|
export interface ParsedDomain {
|
|
3
4
|
isValid: boolean;
|
|
@@ -13,3 +14,8 @@ export declare function getParentDomain(fullDomain: string): string | null;
|
|
|
13
14
|
export declare function getSubdomain(fullDomain: string): string;
|
|
14
15
|
export declare function isTLD(domain: string, tld?: string): boolean;
|
|
15
16
|
export declare function buildFullDomain(subdomain: string, parent: string): string;
|
|
17
|
+
export declare function domainToKey(name: string): {
|
|
18
|
+
key: Uint8Array;
|
|
19
|
+
len: bigint;
|
|
20
|
+
};
|
|
21
|
+
export declare function keyToDomain(key: Uint8Array): string;
|
package/dist/utils/domain.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const DEFAULT_TLD = 'night';
|
|
1
|
+
export const DEFAULT_TLD = 'night';
|
|
2
2
|
export function normalizeDomain(input, assumeTld = true) {
|
|
3
3
|
const trimmedInput = input.trim().toLowerCase();
|
|
4
4
|
const cleaned = trimmedInput.replace(/\.+/g, '.').replace(/\.$/, '');
|
|
@@ -55,3 +55,21 @@ export function buildFullDomain(subdomain, parent) {
|
|
|
55
55
|
return parent;
|
|
56
56
|
return `${subdomain}.${parent}`;
|
|
57
57
|
}
|
|
58
|
+
export function domainToKey(name) {
|
|
59
|
+
const bytes = new TextEncoder().encode(name);
|
|
60
|
+
if (bytes.length === 0 || bytes.length > 32)
|
|
61
|
+
throw new Error(`Domain name must be 1-32 bytes, got ${bytes.length}`);
|
|
62
|
+
const key = new Uint8Array(32).fill(255);
|
|
63
|
+
key.set(bytes);
|
|
64
|
+
return { key, len: BigInt(bytes.length) };
|
|
65
|
+
}
|
|
66
|
+
export function keyToDomain(key) {
|
|
67
|
+
let len = 32;
|
|
68
|
+
for (let i = 0; i < 32; i++) {
|
|
69
|
+
if (key[i] === 255) {
|
|
70
|
+
len = i;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return new TextDecoder().decode(key.subarray(0, len));
|
|
75
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a URL to an accessible HTTP(S) URL
|
|
3
|
+
* Handles IPFS URLs (ipfs://... and bare CIDs) by converting to gateway URLs
|
|
4
|
+
* Returns HTTP(S) URLs as-is
|
|
5
|
+
* @param url - The URL to resolve
|
|
6
|
+
* @returns Promise resolving to accessible URL
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveImageUrl(url: string): Promise<string>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image resolution utilities for midnames-sdk
|
|
3
|
+
* Handles IPFS URLs and converts them to accessible HTTP(S) gateway URLs
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULT_IPFS_GATEWAYS = [
|
|
6
|
+
"https://ipfs.io/ipfs",
|
|
7
|
+
"https://4everland.io/ipfs",
|
|
8
|
+
"https://dweb.link/ipfs",
|
|
9
|
+
];
|
|
10
|
+
/**
|
|
11
|
+
* Validates if a string is a valid IPFS CID
|
|
12
|
+
* @param cid - The string to validate
|
|
13
|
+
* @returns true if valid CID, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
function isValidIPFSCid(cid) {
|
|
16
|
+
if (!cid || cid.length < 10)
|
|
17
|
+
return false;
|
|
18
|
+
// Basic CIDv0 (Qm...) and CIDv1 (b...) validation
|
|
19
|
+
const cidv0Regex = /^Qm[1-9A-HJ-NP-Za-km-z]{44}$/;
|
|
20
|
+
const cidv1Regex = /^b[A-Za-z2-7]{58}$/;
|
|
21
|
+
return cidv0Regex.test(cid) || cidv1Regex.test(cid);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolves an IPFS CID to an accessible gateway URL
|
|
25
|
+
* Tests multiple gateways concurrently and returns the first working one
|
|
26
|
+
* @param cid - The IPFS CID to resolve
|
|
27
|
+
* @returns Promise resolving to gateway URL
|
|
28
|
+
*/
|
|
29
|
+
async function resolveIPFS(cid) {
|
|
30
|
+
const controllers = DEFAULT_IPFS_GATEWAYS.map(() => new AbortController());
|
|
31
|
+
// Race all gateways — first successful response wins
|
|
32
|
+
const racePromise = new Promise((resolve, reject) => {
|
|
33
|
+
let pending = DEFAULT_IPFS_GATEWAYS.length;
|
|
34
|
+
DEFAULT_IPFS_GATEWAYS.forEach(async (gateway, i) => {
|
|
35
|
+
const timeoutId = setTimeout(() => controllers[i].abort(), 3000);
|
|
36
|
+
try {
|
|
37
|
+
const res = await fetch(`${gateway}/${cid}`, {
|
|
38
|
+
method: "HEAD",
|
|
39
|
+
signal: controllers[i].signal,
|
|
40
|
+
});
|
|
41
|
+
clearTimeout(timeoutId);
|
|
42
|
+
if (res.ok) {
|
|
43
|
+
controllers.forEach((c) => c.abort());
|
|
44
|
+
resolve(`${gateway}/${cid}`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
clearTimeout(timeoutId);
|
|
50
|
+
}
|
|
51
|
+
if (--pending === 0)
|
|
52
|
+
reject();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
try {
|
|
56
|
+
return await racePromise;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return `${DEFAULT_IPFS_GATEWAYS[0]}/${cid}`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolves a URL to an accessible HTTP(S) URL
|
|
64
|
+
* Handles IPFS URLs (ipfs://... and bare CIDs) by converting to gateway URLs
|
|
65
|
+
* Returns HTTP(S) URLs as-is
|
|
66
|
+
* @param url - The URL to resolve
|
|
67
|
+
* @returns Promise resolving to accessible URL
|
|
68
|
+
*/
|
|
69
|
+
export async function resolveImageUrl(url) {
|
|
70
|
+
if (!url || !url.trim()) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
const trimmedUrl = url.trim();
|
|
74
|
+
// Return HTTP(S) URLs as-is
|
|
75
|
+
if (/^https?:\/\//i.test(trimmedUrl)) {
|
|
76
|
+
return trimmedUrl;
|
|
77
|
+
}
|
|
78
|
+
// Handle IPFS protocol URLs
|
|
79
|
+
if (trimmedUrl.startsWith("ipfs://")) {
|
|
80
|
+
const cid = trimmedUrl.replace("ipfs://", "");
|
|
81
|
+
return resolveIPFS(cid);
|
|
82
|
+
}
|
|
83
|
+
// Handle bare IPFS CIDs
|
|
84
|
+
if (isValidIPFSCid(trimmedUrl)) {
|
|
85
|
+
return resolveIPFS(trimmedUrl);
|
|
86
|
+
}
|
|
87
|
+
// For other protocols or invalid formats, return as-is
|
|
88
|
+
return trimmedUrl;
|
|
89
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes a URL to prevent javascript: and other dangerous protocols.
|
|
3
|
+
* Returns empty string for disallowed protocols.
|
|
4
|
+
* Decodes URL-encoded characters before checking to prevent bypasses like java%73cript:
|
|
5
|
+
*/
|
|
6
|
+
export declare function sanitizeUrl(url: string | undefined | null): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const ALLOWED_PROTOCOLS = /^(https?:\/\/|ipfs:\/\/|data:image\/)/i;
|
|
2
|
+
/**
|
|
3
|
+
* Sanitizes a URL to prevent javascript: and other dangerous protocols.
|
|
4
|
+
* Returns empty string for disallowed protocols.
|
|
5
|
+
* Decodes URL-encoded characters before checking to prevent bypasses like java%73cript:
|
|
6
|
+
*/
|
|
7
|
+
export function sanitizeUrl(url) {
|
|
8
|
+
if (!url)
|
|
9
|
+
return '';
|
|
10
|
+
const trimmed = url.trim();
|
|
11
|
+
if (!trimmed)
|
|
12
|
+
return '';
|
|
13
|
+
// Decode URL-encoded characters to catch bypasses like java%73cript:
|
|
14
|
+
let decoded;
|
|
15
|
+
try {
|
|
16
|
+
decoded = decodeURIComponent(trimmed);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
decoded = trimmed;
|
|
20
|
+
}
|
|
21
|
+
// Relative URLs and protocol-relative are fine
|
|
22
|
+
if (decoded.startsWith('/') || decoded.startsWith('./'))
|
|
23
|
+
return trimmed;
|
|
24
|
+
// Allow only safe protocols (check decoded version)
|
|
25
|
+
if (ALLOWED_PROTOCOLS.test(decoded))
|
|
26
|
+
return trimmed;
|
|
27
|
+
return '';
|
|
28
|
+
}
|
package/exported.md
CHANGED
|
@@ -103,7 +103,7 @@ export type DomainProfileWidgetProps = {
|
|
|
103
103
|
publicDataProvider: PublicDataProvider;
|
|
104
104
|
className?: string;
|
|
105
105
|
showStatus?: boolean;
|
|
106
|
-
onError?: (error:
|
|
106
|
+
onError?: (error: MidnamesError) => void;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
export function DomainProfileWidget(props: DomainProfileWidgetProps): JSX.Element
|
package/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
|
package/managed/index.js.map
CHANGED
|
@@ -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"}
|