chainmerge-sdk 0.1.2

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 ADDED
@@ -0,0 +1,86 @@
1
+ # chainmerge-sdk
2
+
3
+ TypeScript/JavaScript SDK for the ChainMerge multichain transaction decoder API.
4
+
5
+ ChainMerge normalizes transactions from multiple chains (Ethereum, Solana, Cosmos, Aptos, Sui, Polkadot, Bitcoin, Starknet, etc.) into a single JSON shape. This SDK makes it easy for dapps, wallets, and backends to call the `/api/decode` endpoint and work with typed results.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install chainmerge-sdk
11
+ # or
12
+ yarn add chainmerge-sdk
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import { ChainMergeClient } from "chainmerge-sdk";
19
+
20
+ const client = new ChainMergeClient({
21
+ baseUrl: "http://127.0.0.1:8080", // or your hosted URL
22
+ // apiKey: "optional-api-key",
23
+ });
24
+
25
+ async function main() {
26
+ const tx = await client.decodeTx({
27
+ chain: "ethereum",
28
+ hash: "0xd5d0587189f3411699ae946baa2a7d3ebfaf13133f9014a22bab6948591611ad",
29
+ });
30
+
31
+ console.log("normalized tx:", tx);
32
+
33
+ for (const event of tx.events) {
34
+ if (event.event_type === "token_transfer") {
35
+ console.log(
36
+ `Token transfer of ${event.amount} from ${event.from} to ${event.to} (token: ${event.token})`,
37
+ );
38
+ }
39
+ }
40
+ }
41
+
42
+ main().catch((err) => {
43
+ console.error("decode failed:", err);
44
+ });
45
+ ```
46
+
47
+ ## API
48
+
49
+ ### `new ChainMergeClient(options)`
50
+
51
+ - **`baseUrl`** (string, required): Base URL of the ChainMerge API (`http://127.0.0.1:8080`, `https://api.chainmerge.io`, etc.). No trailing slash.
52
+ - **`apiKey`** (string, optional): Sent as `x-api-key` header if provided.
53
+ - **`fetchImpl`** (function, optional): Custom `fetch` implementation for environments where `fetch` is not global (e.g. Node.js < 18).
54
+
55
+ ### `client.decodeTx({ chain, hash, rpcUrl? })`
56
+
57
+ Decode a single transaction.
58
+
59
+ - **`chain`**: One of `"solana" | "ethereum" | "cosmos" | "aptos" | "sui" | "polkadot" | "bitcoin" | "starknet"`.
60
+ - **`hash`**: Transaction hash string.
61
+ - **`rpcUrl`** (optional): Override RPC URL for this request; if omitted, ChainMerge's internal defaults and env config are used.
62
+
63
+ Returns a `Promise<NormalizedTransaction>`, where:
64
+
65
+ - `NormalizedTransaction` includes:
66
+ - `chain`, `tx_hash`, `sender?`, `receiver?`, `value?`
67
+ - `events: NormalizedEvent[]`, with event types like `"token_transfer"`.
68
+
69
+ Errors from the API are thrown as `Error` instances with extra properties:
70
+
71
+ - `error.code`
72
+ - `error.retryable`
73
+
74
+ ## Publishing (repo maintainers)
75
+
76
+ From the `sdk/js` directory:
77
+
78
+ ```bash
79
+ npm install
80
+ npm run build
81
+
82
+ # first time: npm login
83
+ npm publish --access public
84
+ ```
85
+
86
+ Make sure you bump the `version` field in `package.json` before publishing a new release.
@@ -0,0 +1,35 @@
1
+ import type { Chain, NormalizedTransaction } from "./types.js";
2
+ export interface ChainMergeClientOptions {
3
+ /**
4
+ * Base URL of the ChainMerge API, e.g.:
5
+ * - "http://127.0.0.1:8080" for local development
6
+ * - "https://api.chainmerge.io" for a hosted deployment
7
+ *
8
+ * Do not include a trailing slash.
9
+ */
10
+ baseUrl: string;
11
+ /**
12
+ * Optional API key that will be sent as "x-api-key".
13
+ */
14
+ apiKey?: string;
15
+ /**
16
+ * Custom fetch implementation for environments where "fetch"
17
+ * is not globally available (e.g. Node < 18).
18
+ */
19
+ fetchImpl?: typeof fetch;
20
+ }
21
+ export declare class ChainMergeClient {
22
+ private readonly baseUrl;
23
+ private readonly apiKey?;
24
+ private readonly fetchImpl;
25
+ constructor(options: ChainMergeClientOptions);
26
+ /**
27
+ * Decode a single transaction into a normalized representation.
28
+ */
29
+ decodeTx(params: {
30
+ chain: Chain;
31
+ hash: string;
32
+ rpcUrl?: string;
33
+ }): Promise<NormalizedTransaction>;
34
+ }
35
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAA8C,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE3G,MAAM,WAAW,uBAAuB;IACtC;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,uBAAuB;IAU5C;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE;QACrB,KAAK,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAiCnC"}
package/dist/client.js ADDED
@@ -0,0 +1,38 @@
1
+ export class ChainMergeClient {
2
+ constructor(options) {
3
+ if (!options.baseUrl) {
4
+ throw new Error("ChainMergeClient: baseUrl is required");
5
+ }
6
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
7
+ this.apiKey = options.apiKey;
8
+ this.fetchImpl = options.fetchImpl ?? fetch;
9
+ }
10
+ /**
11
+ * Decode a single transaction into a normalized representation.
12
+ */
13
+ async decodeTx(params) {
14
+ const search = new URLSearchParams({
15
+ chain: params.chain,
16
+ hash: params.hash.trim(),
17
+ });
18
+ if (params.rpcUrl?.trim()) {
19
+ search.set("rpc_url", params.rpcUrl.trim());
20
+ }
21
+ const url = `${this.baseUrl}/api/decode?${search.toString()}`;
22
+ const res = await this.fetchImpl(url, {
23
+ headers: {
24
+ ...(this.apiKey ? { "x-api-key": this.apiKey } : null),
25
+ },
26
+ });
27
+ const body = (await res.json());
28
+ if (!res.ok) {
29
+ const envelope = body;
30
+ const error = new Error(envelope.error.message);
31
+ error.code = envelope.error.code;
32
+ error.retryable = envelope.error.retryable;
33
+ throw error;
34
+ }
35
+ const envelope = body;
36
+ return envelope.decoded;
37
+ }
38
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export * from "./client.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./types.js";
2
+ export * from "./client.js";
@@ -0,0 +1,40 @@
1
+ export type Chain = "solana" | "ethereum" | "cosmos" | "aptos" | "sui" | "polkadot" | "bitcoin" | "starknet";
2
+ export type EventType = "token_transfer" | "unsupported";
3
+ export interface NormalizedEvent {
4
+ event_type: EventType;
5
+ token?: string;
6
+ from?: string;
7
+ to?: string;
8
+ amount?: string;
9
+ raw_program?: string;
10
+ }
11
+ export type ActionType = "transfer" | "swap" | "nft_transfer" | "stake" | "bridge" | "unknown";
12
+ export interface Action {
13
+ action_type: ActionType;
14
+ from?: string;
15
+ to?: string;
16
+ amount?: string;
17
+ token?: string;
18
+ metadata?: unknown;
19
+ }
20
+ export interface NormalizedTransaction {
21
+ chain: Chain;
22
+ tx_hash: string;
23
+ sender?: string;
24
+ receiver?: string;
25
+ value?: string;
26
+ events: NormalizedEvent[];
27
+ actions: Action[];
28
+ }
29
+ export interface ErrorEnvelope {
30
+ code: string;
31
+ message: string;
32
+ retryable: boolean;
33
+ }
34
+ export interface DecodeSuccessEnvelope {
35
+ decoded: NormalizedTransaction;
36
+ }
37
+ export interface DecodeErrorEnvelope {
38
+ error: ErrorEnvelope;
39
+ }
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GACb,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,OAAO,GACP,KAAK,GACL,UAAU,GACV,SAAS,GACT,UAAU,CAAC;AAEf,MAAM,MAAM,SAAS,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,MAAM,GACN,cAAc,GACd,OAAO,GACP,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,qBAAqB,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,aAAa,CAAC;CACtB"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "chainmerge-sdk",
3
+ "version": "0.1.2",
4
+ "description": "TypeScript/JavaScript SDK for the ChainMerge multichain transaction decoder API.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "module": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.build.json",
22
+ "clean": "rm -rf dist",
23
+ "lint": "echo \"no lint configured\"",
24
+ "prepare": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "blockchain",
28
+ "multichain",
29
+ "sdk",
30
+ "transaction-decoder",
31
+ "chainmerge"
32
+ ],
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/I-lost-everytime/Chaincodec.git"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/I-lost-everytime/Chaincodec/issues"
39
+ },
40
+ "homepage": "https://github.com/I-lost-everytime/Chaincodec#readme",
41
+ "devDependencies": {
42
+ "typescript": "^5.6.3"
43
+ }
44
+ }