@d9-network/spec 0.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 (36) hide show
  1. package/.papi/contracts/burnManager.json +1300 -0
  2. package/.papi/contracts/burnMining.json +1385 -0
  3. package/.papi/contracts/crossChainTransfer.json +1693 -0
  4. package/.papi/contracts/marketMaker.json +1470 -0
  5. package/.papi/contracts/merchantMining.json +1750 -0
  6. package/.papi/contracts/miningPool.json +1019 -0
  7. package/.papi/contracts/nodeReward.json +1214 -0
  8. package/.papi/contracts/usdt.json +1036 -0
  9. package/.papi/descriptors/.gitignore +3 -0
  10. package/.papi/descriptors/package.json +24 -0
  11. package/.papi/metadata/d9.scale +0 -0
  12. package/.papi/polkadot-api.json +22 -0
  13. package/assets/ABIs/burn-manager.json +1300 -0
  14. package/assets/ABIs/burn-mining.json +1385 -0
  15. package/assets/ABIs/cross-chain-transfer.json +1693 -0
  16. package/assets/ABIs/market-maker.json +1470 -0
  17. package/assets/ABIs/merchant-mining.json +1750 -0
  18. package/assets/ABIs/mining-pool.json +1019 -0
  19. package/assets/ABIs/node-reward.json +1214 -0
  20. package/assets/ABIs/usdt.json +1036 -0
  21. package/package.json +51 -0
  22. package/scripts/papi-add-ink.ts +104 -0
  23. package/src/client.ts +68 -0
  24. package/src/index.ts +17 -0
  25. package/src/wallet/account.ts +57 -0
  26. package/src/wallet/hex.ts +30 -0
  27. package/src/wallet/index.ts +6 -0
  28. package/src/wallet/mnemonic.ts +19 -0
  29. package/src/wallet/signer.ts +9 -0
  30. package/src/wallet/sr25519.ts +42 -0
  31. package/src/wallet/ss58.ts +14 -0
  32. package/test/client.test.ts +15 -0
  33. package/test/descriptors.test.ts +32 -0
  34. package/test/wallet.test.ts +65 -0
  35. package/tsconfig.json +13 -0
  36. package/tsdown.config.ts +13 -0
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@d9-network/spec",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "author": {
6
+ "email": "jgbingzi@outlook.com",
7
+ "name": "Cyenoch",
8
+ "url": "https://github.com/Cyenoch"
9
+ },
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.mjs",
14
+ "types": "./dist/index.d.cts",
15
+ "publishConfig": {
16
+ "exports": {
17
+ ".": {
18
+ "require": "./dist/index.cjs",
19
+ "import": "./dist/index.mjs"
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "access": "public"
24
+ },
25
+ "exports": {
26
+ ".": "./src/index.ts",
27
+ "./package.json": "./package.json"
28
+ },
29
+ "scripts": {
30
+ "test": "bun test",
31
+ "build": "papi && tsdown",
32
+ "typecheck": "tsc --noEmit -p tsconfig.json"
33
+ },
34
+ "dependencies": {
35
+ "@d9-network/ink": "0.0.1",
36
+ "@polkadot-labs/hdkd": "^0.0.11",
37
+ "@polkadot-labs/hdkd-helpers": "^0.0.11",
38
+ "@polkadot-api/descriptors": "file:.papi/descriptors",
39
+ "@polkadot-api/legacy-provider": "^0.3.6",
40
+ "@polkadot-api/signer": "^0.2.11",
41
+ "@polkadot-api/substrate-bindings": "^0.16.5",
42
+ "polkadot-api": "^1.23.1",
43
+ "zod": "^4.2.1"
44
+ },
45
+ "devDependencies": {
46
+ "@types/bun": "latest",
47
+ "@types/node": "latest",
48
+ "tsdown": "^0.18.1",
49
+ "typescript": "~5.9.3"
50
+ }
51
+ }
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Glob } from "bun";
4
+
5
+ /**
6
+ * Script to add all JSON files from assets/ABIs directory using papi ink add
7
+ */
8
+
9
+ const SCRIPT_DIR = import.meta.dir!;
10
+ const SDK_DIR = `${SCRIPT_DIR}/..`;
11
+
12
+ /**
13
+ * Convert filename to camelCase key
14
+ * Examples:
15
+ * - "d9-usdt.json" -> "d9Usdt"
16
+ * - "burn-manager.json" -> "burnManager"
17
+ * - "cross_chain_transfer.json" -> "crossChainTransfer"
18
+ * - "node_reward.json" -> "nodeReward"
19
+ */
20
+ function toCamelCase(filename: string): string {
21
+ // Remove .json extension
22
+ const name = filename.replace(/\.json$/, "");
23
+
24
+ // Split by hyphens, underscores, or camelCase boundaries
25
+ const parts = name.split(/[-_]/);
26
+
27
+ // Convert to camelCase
28
+ return parts
29
+ .map((part, index) => {
30
+ if (index === 0) {
31
+ // Keep first part as-is (could be lowercase or have numbers)
32
+ return part;
33
+ }
34
+ // Capitalize first letter of subsequent parts
35
+ return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
36
+ })
37
+ .join("");
38
+ }
39
+
40
+ async function main() {
41
+ try {
42
+ // Use Bun Glob to find all JSON files in assets/ABIs directory
43
+ const glob = new Glob("assets/ABIs/*.json");
44
+ const jsonFiles: string[] = [];
45
+
46
+ for await (const file of glob.scan({
47
+ cwd: SDK_DIR,
48
+ })) {
49
+ jsonFiles.push(file);
50
+ }
51
+
52
+ if (jsonFiles.length === 0) {
53
+ console.log("No JSON files found in assets/ABIs directory");
54
+ return;
55
+ }
56
+
57
+ console.log(`Found ${jsonFiles.length} JSON file(s) to process:\n`);
58
+ jsonFiles.forEach((file: string) => console.log(` - ${file}`));
59
+ console.log();
60
+
61
+ // Process each JSON file
62
+ for (const file of jsonFiles) {
63
+ const fileName = file.split("/").pop() || file;
64
+ const camelKey = toCamelCase(fileName);
65
+ console.log(`Processing: ${fileName} (key: ${camelKey})`);
66
+
67
+ try {
68
+ // Execute papi ink add command with -k parameter using Bun.$ from SDK directory
69
+ const result = await Bun.$`bun papi ink add ${file} -k ${camelKey} --skip-codegen`.cwd(SDK_DIR);
70
+
71
+ if (result.exitCode === 0) {
72
+ console.log(`✓ Successfully added: ${fileName}`);
73
+ const output = result.stdout.toString().trim();
74
+ if (output) {
75
+ console.log(` ${output}`);
76
+ }
77
+ console.log();
78
+ } else {
79
+ console.error(`✗ Failed to add: ${fileName}`);
80
+ const errorOutput = result.stderr.toString().trim();
81
+ if (errorOutput) {
82
+ console.error(` ${errorOutput}`);
83
+ }
84
+ const stdoutOutput = result.stdout.toString().trim();
85
+ if (stdoutOutput) {
86
+ console.error(` ${stdoutOutput}`);
87
+ }
88
+ console.log();
89
+ }
90
+ } catch (error) {
91
+ console.error(`✗ Error processing ${fileName}:`, error);
92
+ console.log();
93
+ }
94
+ }
95
+
96
+ Bun.$`bun papi`.cwd(SDK_DIR);
97
+ console.log("Done!");
98
+ } catch (error) {
99
+ console.error("Error processing files:", error);
100
+ process.exit(1);
101
+ }
102
+ }
103
+
104
+ main();
package/src/client.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { d9, getMetadata } from "@polkadot-api/descriptors";
2
+ import { createClient, type CreateClientOptions } from "polkadot-api";
3
+ import { getWsProvider } from "polkadot-api/ws-provider";
4
+ import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat";
5
+ import { withLegacy } from "@polkadot-api/legacy-provider";
6
+ import { createD9InkSdk } from "@d9-network/ink";
7
+
8
+ export type CreateD9SdkClientOptions = {
9
+ endpoint: string;
10
+ wsProvider?: Parameters<typeof getWsProvider>[1];
11
+ metadata?: CreateClientOptions;
12
+ };
13
+
14
+ /**
15
+ * Create a D9 SDK client with ink contract support.
16
+ *
17
+ * This client uses state_call + ContractsApi_call for contract interactions
18
+ * instead of ReviveApi, which is not supported on the D9 chain.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const d9Client = createD9SdkClient({
23
+ * endpoint: "wss://mainnet.d9network.com:40300",
24
+ * });
25
+ *
26
+ * // Query USDT balance
27
+ * const result = await d9Client.contracts.usdt.query("PSP22::balance_of", {
28
+ * origin: aliceAddress,
29
+ * args: { owner: aliceAddress },
30
+ * });
31
+ *
32
+ * if (result.success) {
33
+ * console.log("Balance:", result.value.response);
34
+ * }
35
+ * ```
36
+ */
37
+ export function createD9SdkClient(options: CreateD9SdkClientOptions) {
38
+ const provider = getWsProvider(options.endpoint, {
39
+ innerEnhancer: withLegacy(),
40
+ ...options.wsProvider,
41
+ });
42
+
43
+ const client = createClient(withPolkadotSdkCompat(provider), {
44
+ ...options.metadata,
45
+ async getMetadata(codeHash) {
46
+ // Prefer upstream metadata if present, otherwise fallback to embedded descriptors metadata.
47
+ const custom = options.metadata?.getMetadata
48
+ ? await options.metadata.getMetadata(codeHash)
49
+ : null;
50
+ if (custom) return custom;
51
+ const metadata = await getMetadata(codeHash);
52
+ return metadata ?? null;
53
+ },
54
+ });
55
+
56
+ const api = client.getTypedApi(d9);
57
+
58
+ // Create D9 Ink SDK with typedApi for transaction support
59
+ const inkSdk = createD9InkSdk(client, { typedApi: api });
60
+
61
+ return {
62
+ client,
63
+ api,
64
+ inkSdk,
65
+ };
66
+ }
67
+
68
+ export type D9SdkClientReturn = ReturnType<typeof createD9SdkClient>;
package/src/index.ts ADDED
@@ -0,0 +1,17 @@
1
+ export * from "./client";
2
+ export * from "./wallet";
3
+ export * from "@polkadot-api/descriptors";
4
+
5
+ // Re-export @d9-network/ink types and functions for use in @d9-network/app
6
+ export {
7
+ createPSP22TransferStream,
8
+ createNativeTransferStream,
9
+ createContractEventStream,
10
+ ContractEventParser,
11
+ } from "@d9-network/ink";
12
+ export type {
13
+ DecodedContractEvent,
14
+ RawContractEvent,
15
+ EventSubscriptionOptions,
16
+ EventFilterOptions,
17
+ } from "@d9-network/ink";
@@ -0,0 +1,57 @@
1
+ import type { SS58String } from "polkadot-api";
2
+
3
+ import { mnemonicToMiniSecret } from "./mnemonic";
4
+ import { hexToBytes, type HexString } from "./hex";
5
+ import {
6
+ sr25519DeriveFromMiniSecret,
7
+ sr25519KeypairFromMiniSecret,
8
+ sr25519AddressFromKeypair,
9
+ } from "./sr25519";
10
+ import {
11
+ createSr25519SignerFromKeypair,
12
+ } from "./signer";
13
+
14
+ export type WalletAccount = {
15
+ address: SS58String;
16
+ publicKey: Uint8Array;
17
+ /**
18
+ * Signer for polkadot-api transactions
19
+ */
20
+ signer: ReturnType<typeof createSr25519SignerFromKeypair>;
21
+ };
22
+
23
+ export function createAccountFromMnemonic(options: {
24
+ mnemonic: string;
25
+ ss58Format?: number;
26
+ password?: string;
27
+ derivationPath?: string;
28
+ keyType?: "sr25519" | "ed25519" | "secp256k1";
29
+ }): WalletAccount {
30
+ const miniSecret = mnemonicToMiniSecret(options.mnemonic, options.password);
31
+ const keypair = options.derivationPath
32
+ ? sr25519DeriveFromMiniSecret(miniSecret, options.derivationPath)
33
+ : sr25519KeypairFromMiniSecret(miniSecret);
34
+
35
+ return {
36
+ address: sr25519AddressFromKeypair(keypair, options.ss58Format),
37
+ publicKey: keypair.publicKey,
38
+ signer: createSr25519SignerFromKeypair(keypair),
39
+ };
40
+ }
41
+
42
+ export function createAccountFromPrivateKey(options: {
43
+ secretKeyHex: HexString;
44
+ ss58Format?: number;
45
+ keyType: "sr25519" | "ed25519" | "secp256k1";
46
+ }): WalletAccount {
47
+ const secretBytes = hexToBytes(options.secretKeyHex);
48
+ if (secretBytes.length !== 32) {
49
+ throw new Error("secret key must be 32 bytes");
50
+ }
51
+ const keypair = sr25519KeypairFromMiniSecret(secretBytes);
52
+ return {
53
+ address: sr25519AddressFromKeypair(keypair, options.ss58Format),
54
+ publicKey: keypair.publicKey,
55
+ signer: createSr25519SignerFromKeypair(keypair),
56
+ };
57
+ }
@@ -0,0 +1,30 @@
1
+ import type { HexString } from "polkadot-api";
2
+
3
+ export type { HexString } from "polkadot-api";
4
+
5
+ export function isHexString(input: unknown): input is HexString {
6
+ if (typeof input !== "string") return false;
7
+ if (!input.startsWith("0x")) return false;
8
+ const s = input.slice(2);
9
+ return s.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(s);
10
+ }
11
+
12
+ export function hexToBytes(hex: unknown): Uint8Array {
13
+ if (!isHexString(hex)) {
14
+ throw new Error("Invalid hex string");
15
+ }
16
+ const s = (hex as string).slice(2);
17
+ const out = new Uint8Array(s.length / 2);
18
+ for (let i = 0; i < out.length; i++) {
19
+ out[i] = Number.parseInt(s.slice(i * 2, i * 2 + 2), 16);
20
+ }
21
+ return out;
22
+ }
23
+
24
+ export function bytesToHex(bytes: Uint8Array): HexString {
25
+ let hex = "";
26
+ for (let i = 0; i < bytes.length; i++) {
27
+ hex += bytes[i]!.toString(16).padStart(2, "0");
28
+ }
29
+ return `0x${hex}` as const;
30
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./hex";
2
+ export * from "./mnemonic";
3
+ export * from "./ss58";
4
+ export * from "./sr25519";
5
+ export * from "./signer";
6
+ export * from "./account";
@@ -0,0 +1,19 @@
1
+ import {
2
+ generateMnemonic as hdkdGenerateMnemonic,
3
+ mnemonicToMiniSecret as hdkdMnemonicToMiniSecret,
4
+ validateMnemonic as hdkdValidateMnemonic,
5
+ } from "@polkadot-labs/hdkd-helpers";
6
+
7
+ export function generateMnemonic(): string {
8
+ return hdkdGenerateMnemonic();
9
+ }
10
+
11
+ export function validateMnemonic(mnemonic: string): boolean {
12
+ return hdkdValidateMnemonic(mnemonic);
13
+ }
14
+
15
+ export function mnemonicToMiniSecret(mnemonic: string, password?: string): Uint8Array {
16
+ if (!validateMnemonic(mnemonic)) throw new Error("Invalid mnemonic");
17
+ return hdkdMnemonicToMiniSecret(mnemonic, password);
18
+ }
19
+
@@ -0,0 +1,9 @@
1
+ import { getPolkadotSigner } from "@polkadot-api/signer";
2
+ import type { PolkadotSigner } from "polkadot-api";
3
+ import type { KeyPair } from "@polkadot-labs/hdkd-helpers";
4
+
5
+ export type { PolkadotSigner } from "polkadot-api";
6
+
7
+ export function createSr25519SignerFromKeypair(keypair: KeyPair): PolkadotSigner {
8
+ return getPolkadotSigner(keypair.publicKey, "Sr25519", (payload) => keypair.sign(payload));
9
+ }
@@ -0,0 +1,42 @@
1
+ import { sr25519CreateDerive, withNetworkAccount } from "@polkadot-labs/hdkd";
2
+ import type { KeyPair } from "@polkadot-labs/hdkd-helpers";
3
+ import type { SS58String } from "polkadot-api";
4
+
5
+ import { hexToBytes } from "./hex";
6
+
7
+ export type Sr25519Keypair = KeyPair;
8
+
9
+ export function sr25519KeypairFromMiniSecret(miniSecret: Uint8Array): Sr25519Keypair {
10
+ const derive = sr25519CreateDerive(miniSecret);
11
+ const kp = derive("");
12
+ // hdkd derives at the root when path is empty string.
13
+ return kp;
14
+ }
15
+
16
+ export function sr25519DeriveFromMiniSecret(
17
+ miniSecret: Uint8Array,
18
+ derivationPath: string,
19
+ ): Sr25519Keypair {
20
+ const derive = sr25519CreateDerive(miniSecret);
21
+ return derive(derivationPath);
22
+ }
23
+
24
+ export function sr25519AddressFromKeypair(
25
+ keypair: Sr25519Keypair,
26
+ ss58Format?: number,
27
+ ): SS58String {
28
+ return withNetworkAccount(keypair, ss58Format).ss58Address as SS58String;
29
+ }
30
+
31
+ export function sr25519AddressFromSecretKeyHex(
32
+ secretKeyHex: string,
33
+ ss58Format: number,
34
+ ): SS58String {
35
+ const secretKey = hexToBytes(secretKeyHex);
36
+ if (secretKey.length !== 32) {
37
+ throw new Error("sr25519 secret key must be 32 bytes");
38
+ }
39
+ const keypair = sr25519KeypairFromMiniSecret(secretKey);
40
+ return sr25519AddressFromKeypair(keypair, ss58Format);
41
+ }
42
+
@@ -0,0 +1,14 @@
1
+ import { ss58Decode, ss58Encode } from "@polkadot-labs/hdkd-helpers";
2
+ import type { SS58String } from "polkadot-api";
3
+
4
+ export type { SS58String } from "polkadot-api";
5
+
6
+ export function ss58DecodePublicKey(address: SS58String): Uint8Array {
7
+ const [publicKey] = ss58Decode(address);
8
+ return publicKey;
9
+ }
10
+
11
+ export function ss58Reencode(address: SS58String, ss58Format: number): SS58String {
12
+ const publicKey = ss58DecodePublicKey(address);
13
+ return ss58Encode(publicKey, ss58Format) as SS58String;
14
+ }
@@ -0,0 +1,15 @@
1
+ import { describe, expect, it } from "bun:test";
2
+
3
+ import { createD9SdkClient } from "../src";
4
+
5
+ describe("client factory", () => {
6
+ it("creates client with api and inkSdk", () => {
7
+ const sdk = createD9SdkClient({ endpoint: "ws://127.0.0.1:0" });
8
+
9
+ expect(sdk.client).toBeDefined();
10
+ expect(sdk.api).toBeDefined();
11
+ expect(typeof sdk.inkSdk.getContract).toBe("function");
12
+
13
+ sdk.client.destroy();
14
+ });
15
+ });
@@ -0,0 +1,32 @@
1
+ import { describe, expect, it } from "bun:test";
2
+
3
+ import { contracts, getMetadata } from "../src";
4
+
5
+ describe("descriptors exports", () => {
6
+ it("exposes contract metadata and metadata lookup", async () => {
7
+ const descriptor = contracts.usdt;
8
+ expect(descriptor).toBeDefined();
9
+
10
+ expect(descriptor.metadata).toBeDefined();
11
+ const hash = descriptor.metadata?.source?.hash;
12
+ if (!hash) {
13
+ throw new Error("contracts.usdt.metadata.source.hash is missing");
14
+ }
15
+ expect(hash.startsWith("0x")).toBe(true);
16
+
17
+ const metadata = await getMetadata(hash);
18
+ expect(metadata).toBeNull();
19
+
20
+ const configUrl = new URL("../.papi/polkadot-api.json", import.meta.url);
21
+ const configText = await Bun.file(configUrl).text();
22
+ const config = JSON.parse(configText) as {
23
+ entries?: Record<string, { codeHash?: string }>;
24
+ };
25
+ const chainHash = config.entries?.d9?.codeHash;
26
+ expect(chainHash).toBeDefined();
27
+ if (chainHash) {
28
+ const chainMetadata = await getMetadata(chainHash);
29
+ expect(chainMetadata).not.toBeNull();
30
+ }
31
+ });
32
+ });
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from "bun:test";
2
+
3
+ import { DEV_MINI_SECRET, DEV_PHRASE } from "@polkadot-labs/hdkd-helpers";
4
+ import {
5
+ createAccountFromMnemonic,
6
+ createAccountFromPrivateKey,
7
+ mnemonicToMiniSecret,
8
+ sr25519AddressFromKeypair,
9
+ sr25519DeriveFromMiniSecret,
10
+ sr25519KeypairFromMiniSecret,
11
+ } from "../src/wallet/index";
12
+ import { createSr25519SignerFromKeypair } from "../src/wallet/signer";
13
+
14
+ const DEV_SS58_FORMAT = 9;
15
+
16
+ describe("wallet sr25519 account + signer", () => {
17
+ it("exposes publicKey in PolkadotSigner", () => {
18
+ const seed = Uint8Array.from(Buffer.from(DEV_MINI_SECRET, "hex"));
19
+ const keypair = sr25519KeypairFromMiniSecret(seed);
20
+ const signer = createSr25519SignerFromKeypair(keypair);
21
+
22
+ expect(Buffer.from(signer.publicKey).toString("hex")).toBe(
23
+ Buffer.from(keypair.publicKey).toString("hex"),
24
+ );
25
+ });
26
+
27
+ it("createAccountFromMnemonic uses same address as raw keypair", () => {
28
+ const miniSecret = mnemonicToMiniSecret(DEV_PHRASE);
29
+ const keypair = sr25519KeypairFromMiniSecret(miniSecret);
30
+ const expectedAddress = sr25519AddressFromKeypair(keypair, DEV_SS58_FORMAT);
31
+ const account = createAccountFromMnemonic({
32
+ mnemonic: DEV_PHRASE,
33
+ keyType: "sr25519",
34
+ ss58Format: DEV_SS58_FORMAT,
35
+ });
36
+
37
+ expect(account.address).toBe(expectedAddress);
38
+ });
39
+
40
+ it("supports derivation paths", () => {
41
+ const miniSecret = mnemonicToMiniSecret(DEV_PHRASE);
42
+ const derived = sr25519DeriveFromMiniSecret(miniSecret, "//test");
43
+ const expectedAddress = sr25519AddressFromKeypair(derived, DEV_SS58_FORMAT);
44
+ const account = createAccountFromMnemonic({
45
+ mnemonic: DEV_PHRASE,
46
+ keyType: "sr25519",
47
+ derivationPath: "//test",
48
+ ss58Format: DEV_SS58_FORMAT,
49
+ });
50
+
51
+ expect(account.address).toBe(expectedAddress);
52
+ });
53
+ });
54
+
55
+ describe("wallet secret key validation", () => {
56
+ it("throws when secret key is not 32 bytes", () => {
57
+ expect(() =>
58
+ createAccountFromPrivateKey({
59
+ secretKeyHex: "0x1234",
60
+ keyType: "sr25519",
61
+ ss58Format: DEV_SS58_FORMAT,
62
+ }),
63
+ ).toThrow("secret key must be 32 bytes");
64
+ });
65
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "strict": true,
7
+ "noEmit": true,
8
+ "types": ["bun"],
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["src/**/*", "test/**/*", "scripts/**/*"]
12
+ }
13
+
@@ -0,0 +1,13 @@
1
+ import { defineConfig } from "tsdown"
2
+
3
+ export default defineConfig({
4
+ entry: ["./src/index.ts"],
5
+ outDir: "./dist",
6
+ format: ["esm", "cjs"],
7
+ sourcemap: true,
8
+ clean: true,
9
+ dts: true,
10
+ exports: {
11
+ devExports: true
12
+ },
13
+ })