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 +86 -0
- package/dist/client.d.ts +35 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +38 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +44 -0
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.
|
package/dist/client.d.ts
ADDED
|
@@ -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
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -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
package/dist/types.d.ts
ADDED
|
@@ -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
|
+
}
|