@provable-games/metagame-sdk 0.1.2 → 0.1.4
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/abis.cjs +2794 -0
- package/dist/abis.cjs.map +1 -0
- package/dist/abis.d.cts +2012 -0
- package/dist/abis.d.ts +2012 -0
- package/dist/abis.js +2786 -0
- package/dist/abis.js.map +1 -0
- package/dist/{prizeAggregation-CHwIJzXr.d.cts → client-CD-q6Alx.d.ts} +36 -2
- package/dist/{prizeAggregation-CHwIJzXr.d.ts → client-CcoKJS8i.d.cts} +36 -2
- package/dist/index.cjs +309 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -3
- package/dist/index.d.ts +123 -3
- package/dist/index.js +302 -7
- package/dist/index.js.map +1 -1
- package/dist/merkle.cjs +209 -0
- package/dist/merkle.cjs.map +1 -0
- package/dist/merkle.d.cts +151 -0
- package/dist/merkle.d.ts +151 -0
- package/dist/merkle.js +200 -0
- package/dist/merkle.js.map +1 -0
- package/dist/react.cjs +243 -22
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +53 -18
- package/dist/react.d.ts +53 -18
- package/dist/react.js +242 -25
- package/dist/react.js.map +1 -1
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.js.map +1 -1
- package/package.json +31 -11
package/dist/merkle.cjs
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var strkMerkleTree = require('@ericnordelo/strk-merkle-tree');
|
|
4
|
+
var starknet = require('starknet');
|
|
5
|
+
|
|
6
|
+
// src/merkle/merkleTree.ts
|
|
7
|
+
function computeLeafValue(address, count) {
|
|
8
|
+
const intermediate = starknet.hash.computePedersenHash("0x0", address);
|
|
9
|
+
return starknet.hash.computePedersenHash(intermediate, "0x" + count.toString(16));
|
|
10
|
+
}
|
|
11
|
+
function buildMerkleTree(entries) {
|
|
12
|
+
if (entries.length === 0) {
|
|
13
|
+
throw new Error("Cannot build merkle tree with no entries");
|
|
14
|
+
}
|
|
15
|
+
const leaves = entries.map((e) => [computeLeafValue(e.address, e.count)]);
|
|
16
|
+
const tree = strkMerkleTree.StandardMerkleTree.of(leaves, ["felt252"], {
|
|
17
|
+
sortLeaves: true
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
version: 2,
|
|
21
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22
|
+
entries,
|
|
23
|
+
root: tree.root,
|
|
24
|
+
tree: tree.dump()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getProof(treeData, address, count) {
|
|
28
|
+
const tree = strkMerkleTree.StandardMerkleTree.load(treeData.tree);
|
|
29
|
+
const leafValue = computeLeafValue(address, count);
|
|
30
|
+
for (const [index, leaf] of tree.entries()) {
|
|
31
|
+
if (BigInt(leaf[0]) === BigInt(leafValue)) {
|
|
32
|
+
return tree.getProof(index);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function verifyProof(treeData, address, count, proof) {
|
|
38
|
+
const leafValue = computeLeafValue(address, count);
|
|
39
|
+
return strkMerkleTree.StandardMerkleTree.verify(
|
|
40
|
+
treeData.root,
|
|
41
|
+
["felt252"],
|
|
42
|
+
[leafValue],
|
|
43
|
+
proof
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
function buildQualification(count, proof) {
|
|
47
|
+
return ["0x" + count.toString(16), ...proof];
|
|
48
|
+
}
|
|
49
|
+
function findEntry(treeData, address) {
|
|
50
|
+
return treeData.entries.find(
|
|
51
|
+
(e) => e.address.toLowerCase() === address.toLowerCase() || BigInt(e.address) === BigInt(address)
|
|
52
|
+
) || null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/merkle/client.ts
|
|
56
|
+
var DEFAULT_MERKLE_API_URLS = {
|
|
57
|
+
SN_SEPOLIA: "https://merkle-api-sepolia.up.railway.app",
|
|
58
|
+
SN_MAIN: "https://merkle-api.up.railway.app"
|
|
59
|
+
};
|
|
60
|
+
var MerkleClient = class {
|
|
61
|
+
apiUrl;
|
|
62
|
+
constructor(config) {
|
|
63
|
+
this.apiUrl = config.apiUrl ?? DEFAULT_MERKLE_API_URLS[config.chainId] ?? DEFAULT_MERKLE_API_URLS.SN_MAIN;
|
|
64
|
+
}
|
|
65
|
+
/** Fetch paginated list of merkle trees. */
|
|
66
|
+
async getTrees(options) {
|
|
67
|
+
const empty = {
|
|
68
|
+
data: [],
|
|
69
|
+
total: 0,
|
|
70
|
+
page: 1,
|
|
71
|
+
limit: 20,
|
|
72
|
+
totalPages: 0
|
|
73
|
+
};
|
|
74
|
+
try {
|
|
75
|
+
const params = new URLSearchParams();
|
|
76
|
+
if (options?.page) params.set("page", String(options.page));
|
|
77
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
78
|
+
const qs = params.toString();
|
|
79
|
+
const res = await fetch(`${this.apiUrl}/trees${qs ? `?${qs}` : ""}`);
|
|
80
|
+
if (!res.ok) return empty;
|
|
81
|
+
const json = await res.json();
|
|
82
|
+
return {
|
|
83
|
+
data: json.data ?? [],
|
|
84
|
+
total: json.total ?? 0,
|
|
85
|
+
page: json.page ?? 1,
|
|
86
|
+
limit: json.limit ?? 20,
|
|
87
|
+
totalPages: json.totalPages ?? 0
|
|
88
|
+
};
|
|
89
|
+
} catch {
|
|
90
|
+
return empty;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Fetch entries for a specific merkle tree. */
|
|
94
|
+
async getTreeEntries(treeId, options) {
|
|
95
|
+
const empty = {
|
|
96
|
+
data: [],
|
|
97
|
+
total: 0,
|
|
98
|
+
page: 1,
|
|
99
|
+
limit: 50,
|
|
100
|
+
totalPages: 0
|
|
101
|
+
};
|
|
102
|
+
try {
|
|
103
|
+
const params = new URLSearchParams();
|
|
104
|
+
if (options?.page) params.set("page", String(options.page));
|
|
105
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
106
|
+
const qs = params.toString();
|
|
107
|
+
const res = await fetch(
|
|
108
|
+
`${this.apiUrl}/trees/${treeId}/entries${qs ? `?${qs}` : ""}`
|
|
109
|
+
);
|
|
110
|
+
if (!res.ok) return empty;
|
|
111
|
+
const json = await res.json();
|
|
112
|
+
return {
|
|
113
|
+
data: json.data ?? [],
|
|
114
|
+
total: json.total ?? 0,
|
|
115
|
+
page: json.page ?? 1,
|
|
116
|
+
limit: json.limit ?? 50,
|
|
117
|
+
totalPages: json.totalPages ?? 0
|
|
118
|
+
};
|
|
119
|
+
} catch {
|
|
120
|
+
return empty;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Fetch a merkle proof for a player address. */
|
|
124
|
+
async getProof(treeId, playerAddress) {
|
|
125
|
+
try {
|
|
126
|
+
const res = await fetch(
|
|
127
|
+
`${this.apiUrl}/trees/${treeId}/proof/${playerAddress.toLowerCase()}`
|
|
128
|
+
);
|
|
129
|
+
if (!res.ok) return null;
|
|
130
|
+
return await res.json();
|
|
131
|
+
} catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Store a merkle tree in the API (after on-chain registration). */
|
|
136
|
+
async storeTree(request) {
|
|
137
|
+
const res = await fetch(`${this.apiUrl}/trees`, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: { "Content-Type": "application/json" },
|
|
140
|
+
body: JSON.stringify(request)
|
|
141
|
+
});
|
|
142
|
+
if (!res.ok) {
|
|
143
|
+
const text = await res.text();
|
|
144
|
+
throw new Error(`Failed to create merkle tree: ${text}`);
|
|
145
|
+
}
|
|
146
|
+
return await res.json();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Build a merkle tree locally and return the calldata needed
|
|
150
|
+
* to register it on-chain via the validator contract.
|
|
151
|
+
*
|
|
152
|
+
* The consumer is responsible for executing the call with their
|
|
153
|
+
* own account/signer.
|
|
154
|
+
*/
|
|
155
|
+
buildTreeCalldata(entries, validatorAddress) {
|
|
156
|
+
const tree = buildMerkleTree(entries);
|
|
157
|
+
return {
|
|
158
|
+
tree,
|
|
159
|
+
call: {
|
|
160
|
+
contractAddress: validatorAddress,
|
|
161
|
+
entrypoint: "create_tree",
|
|
162
|
+
calldata: [tree.root]
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Parse the tree ID from transaction receipt events.
|
|
168
|
+
* Returns null if the event cannot be found.
|
|
169
|
+
*/
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
|
+
parseTreeIdFromEvents(events, validatorAddress) {
|
|
172
|
+
const validatorBigInt = BigInt(validatorAddress);
|
|
173
|
+
const treeEvent = events.find((e) => {
|
|
174
|
+
try {
|
|
175
|
+
return BigInt(e.from_address) === validatorBigInt;
|
|
176
|
+
} catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
if (!treeEvent?.keys?.[1]) return null;
|
|
181
|
+
return Number(BigInt(treeEvent.keys[1]));
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Store the tree in the API after on-chain registration.
|
|
185
|
+
* Pass the tree ID from the on-chain event along with the original entries.
|
|
186
|
+
*/
|
|
187
|
+
async createTree(params) {
|
|
188
|
+
return this.storeTree({
|
|
189
|
+
id: params.treeId,
|
|
190
|
+
name: params.name,
|
|
191
|
+
description: params.description,
|
|
192
|
+
entries: params.entries
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
function createMerkleClient(config) {
|
|
197
|
+
return new MerkleClient(config);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
exports.MerkleClient = MerkleClient;
|
|
201
|
+
exports.buildMerkleTree = buildMerkleTree;
|
|
202
|
+
exports.buildQualification = buildQualification;
|
|
203
|
+
exports.computeLeafValue = computeLeafValue;
|
|
204
|
+
exports.createMerkleClient = createMerkleClient;
|
|
205
|
+
exports.findEntry = findEntry;
|
|
206
|
+
exports.getProof = getProof;
|
|
207
|
+
exports.verifyProof = verifyProof;
|
|
208
|
+
//# sourceMappingURL=merkle.cjs.map
|
|
209
|
+
//# sourceMappingURL=merkle.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/merkle/merkleTree.ts","../src/merkle/client.ts"],"names":["hash","StandardMerkleTree"],"mappings":"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","file":"merkle.cjs","sourcesContent":["import { StandardMerkleTree } from \"@ericnordelo/strk-merkle-tree\";\nimport { hash } from \"starknet\";\n\nexport interface MerkleEntry {\n address: string;\n count: number;\n}\n\nexport interface MerkleTreeData {\n version: 2;\n createdAt: string;\n entries: MerkleEntry[];\n root: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tree: any; // StandardMerkleTree dump format\n}\n\n/**\n * Compute the leaf value that gets passed to StandardMerkleTree.\n * This matches the Cairo contract's leaf computation:\n * PedersenTrait::new(0).update(address).update(count).finalize()\n *\n * The StandardMerkleTree then applies its own leaf hashing on top:\n * H(0, value, 1) using PedersenCHasher\n */\nexport function computeLeafValue(address: string, count: number): string {\n const intermediate = hash.computePedersenHash(\"0x0\", address);\n return hash.computePedersenHash(intermediate, \"0x\" + count.toString(16));\n}\n\n/**\n * Build a StandardMerkleTree from entries.\n * Each leaf is a single felt252 value (the pre-hashed leaf value).\n */\nexport function buildMerkleTree(entries: MerkleEntry[]): MerkleTreeData {\n if (entries.length === 0) {\n throw new Error(\"Cannot build merkle tree with no entries\");\n }\n\n const leaves = entries.map((e) => [computeLeafValue(e.address, e.count)]);\n\n const tree = StandardMerkleTree.of(leaves, [\"felt252\"], {\n sortLeaves: true,\n });\n\n return {\n version: 2,\n createdAt: new Date().toISOString(),\n entries,\n root: tree.root,\n tree: tree.dump(),\n };\n}\n\n/**\n * Load a tree from saved data and get the proof for an address.\n */\nexport function getProof(\n treeData: MerkleTreeData,\n address: string,\n count: number,\n): string[] | null {\n const tree = StandardMerkleTree.load(treeData.tree);\n const leafValue = computeLeafValue(address, count);\n\n for (const [index, leaf] of tree.entries()) {\n if (BigInt(leaf[0] as string) === BigInt(leafValue)) {\n return tree.getProof(index);\n }\n }\n\n return null;\n}\n\n/**\n * Verify a proof against a root (client-side).\n */\nexport function verifyProof(\n treeData: MerkleTreeData,\n address: string,\n count: number,\n proof: string[],\n): boolean {\n const leafValue = computeLeafValue(address, count);\n return StandardMerkleTree.verify(\n treeData.root,\n [\"felt252\"],\n [leafValue],\n proof,\n );\n}\n\n/**\n * Build qualification array for contract calls: [count, ...proof]\n */\nexport function buildQualification(count: number, proof: string[]): string[] {\n return [\"0x\" + count.toString(16), ...proof];\n}\n\n/**\n * Find an entry in the tree by address.\n */\nexport function findEntry(\n treeData: MerkleTreeData,\n address: string,\n): MerkleEntry | null {\n return (\n treeData.entries.find(\n (e) =>\n e.address.toLowerCase() === address.toLowerCase() ||\n BigInt(e.address) === BigInt(address),\n ) || null\n );\n}\n","/**\n * MerkleClient — chainId-aware client for the merkle API service.\n *\n * Resolves the API URL once at construction time so callers never\n * need to pass chainId on every request.\n */\n\nimport { buildMerkleTree } from \"./merkleTree\";\nimport type { MerkleEntry } from \"./merkleTree\";\n\n// ── Default API URLs per chain ──────────────────────────────────────────────\n\nconst DEFAULT_MERKLE_API_URLS: Record<string, string> = {\n SN_SEPOLIA: \"https://merkle-api-sepolia.up.railway.app\",\n SN_MAIN: \"https://merkle-api.up.railway.app\",\n};\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface MerkleClientConfig {\n /** Starknet chain ID, e.g. \"SN_MAIN\" or \"SN_SEPOLIA\" */\n chainId: string;\n /** Override the default API URL for this chain */\n apiUrl?: string;\n}\n\nexport interface MerkleTree {\n id: number;\n name: string;\n description: string;\n root: string;\n entryCount: number;\n createdAt: string;\n}\n\nexport interface MerkleTreesResponse {\n data: MerkleTree[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\nexport interface MerkleProofResponse {\n address: string;\n count: number;\n proof: string[];\n qualification: string[];\n}\n\nexport interface MerkleTreeEntry {\n address: string;\n count: number;\n}\n\nexport interface MerkleTreeEntriesResponse {\n data: MerkleTreeEntry[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\nexport interface CreateMerkleTreeRequest {\n id: number;\n name: string;\n description: string;\n entries: MerkleEntry[];\n}\n\nexport interface CreateMerkleTreeResponse {\n id: number;\n root: string;\n entryCount: number;\n}\n\nexport interface TreeCalldata {\n tree: ReturnType<typeof buildMerkleTree>;\n call: {\n contractAddress: string;\n entrypoint: string;\n calldata: string[];\n };\n}\n\n// ── Client ──────────────────────────────────────────────────────────────────\n\nexport class MerkleClient {\n readonly apiUrl: string;\n\n constructor(config: MerkleClientConfig) {\n this.apiUrl =\n config.apiUrl ??\n DEFAULT_MERKLE_API_URLS[config.chainId] ??\n DEFAULT_MERKLE_API_URLS.SN_MAIN;\n }\n\n /** Fetch paginated list of merkle trees. */\n async getTrees(options?: {\n page?: number;\n limit?: number;\n }): Promise<MerkleTreesResponse> {\n const empty: MerkleTreesResponse = {\n data: [],\n total: 0,\n page: 1,\n limit: 20,\n totalPages: 0,\n };\n try {\n const params = new URLSearchParams();\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n const res = await fetch(`${this.apiUrl}/trees${qs ? `?${qs}` : \"\"}`);\n if (!res.ok) return empty;\n const json = await res.json();\n return {\n data: json.data ?? [],\n total: json.total ?? 0,\n page: json.page ?? 1,\n limit: json.limit ?? 20,\n totalPages: json.totalPages ?? 0,\n };\n } catch {\n return empty;\n }\n }\n\n /** Fetch entries for a specific merkle tree. */\n async getTreeEntries(\n treeId: string | number,\n options?: { page?: number; limit?: number },\n ): Promise<MerkleTreeEntriesResponse> {\n const empty: MerkleTreeEntriesResponse = {\n data: [],\n total: 0,\n page: 1,\n limit: 50,\n totalPages: 0,\n };\n try {\n const params = new URLSearchParams();\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n const res = await fetch(\n `${this.apiUrl}/trees/${treeId}/entries${qs ? `?${qs}` : \"\"}`,\n );\n if (!res.ok) return empty;\n const json = await res.json();\n return {\n data: json.data ?? [],\n total: json.total ?? 0,\n page: json.page ?? 1,\n limit: json.limit ?? 50,\n totalPages: json.totalPages ?? 0,\n };\n } catch {\n return empty;\n }\n }\n\n /** Fetch a merkle proof for a player address. */\n async getProof(\n treeId: string | number,\n playerAddress: string,\n ): Promise<MerkleProofResponse | null> {\n try {\n const res = await fetch(\n `${this.apiUrl}/trees/${treeId}/proof/${playerAddress.toLowerCase()}`,\n );\n if (!res.ok) return null;\n return await res.json();\n } catch {\n return null;\n }\n }\n\n /** Store a merkle tree in the API (after on-chain registration). */\n async storeTree(\n request: CreateMerkleTreeRequest,\n ): Promise<CreateMerkleTreeResponse> {\n const res = await fetch(`${this.apiUrl}/trees`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to create merkle tree: ${text}`);\n }\n return await res.json();\n }\n\n /**\n * Build a merkle tree locally and return the calldata needed\n * to register it on-chain via the validator contract.\n *\n * The consumer is responsible for executing the call with their\n * own account/signer.\n */\n buildTreeCalldata(\n entries: MerkleEntry[],\n validatorAddress: string,\n ): TreeCalldata {\n const tree = buildMerkleTree(entries);\n return {\n tree,\n call: {\n contractAddress: validatorAddress,\n entrypoint: \"create_tree\",\n calldata: [tree.root],\n },\n };\n }\n\n /**\n * Parse the tree ID from transaction receipt events.\n * Returns null if the event cannot be found.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parseTreeIdFromEvents(events: any[], validatorAddress: string): number | null {\n const validatorBigInt = BigInt(validatorAddress);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const treeEvent = events.find((e: any) => {\n try {\n return BigInt(e.from_address) === validatorBigInt;\n } catch {\n return false;\n }\n });\n if (!treeEvent?.keys?.[1]) return null;\n return Number(BigInt(treeEvent.keys[1]));\n }\n\n /**\n * Store the tree in the API after on-chain registration.\n * Pass the tree ID from the on-chain event along with the original entries.\n */\n async createTree(params: {\n treeId: number;\n name: string;\n description: string;\n entries: MerkleEntry[];\n }): Promise<CreateMerkleTreeResponse> {\n return this.storeTree({\n id: params.treeId,\n name: params.name,\n description: params.description,\n entries: params.entries,\n });\n }\n}\n\n/** Factory function for creating a MerkleClient. */\nexport function createMerkleClient(config: MerkleClientConfig): MerkleClient {\n return new MerkleClient(config);\n}\n"]}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
interface MerkleEntry {
|
|
2
|
+
address: string;
|
|
3
|
+
count: number;
|
|
4
|
+
}
|
|
5
|
+
interface MerkleTreeData {
|
|
6
|
+
version: 2;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
entries: MerkleEntry[];
|
|
9
|
+
root: string;
|
|
10
|
+
tree: any;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compute the leaf value that gets passed to StandardMerkleTree.
|
|
14
|
+
* This matches the Cairo contract's leaf computation:
|
|
15
|
+
* PedersenTrait::new(0).update(address).update(count).finalize()
|
|
16
|
+
*
|
|
17
|
+
* The StandardMerkleTree then applies its own leaf hashing on top:
|
|
18
|
+
* H(0, value, 1) using PedersenCHasher
|
|
19
|
+
*/
|
|
20
|
+
declare function computeLeafValue(address: string, count: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Build a StandardMerkleTree from entries.
|
|
23
|
+
* Each leaf is a single felt252 value (the pre-hashed leaf value).
|
|
24
|
+
*/
|
|
25
|
+
declare function buildMerkleTree(entries: MerkleEntry[]): MerkleTreeData;
|
|
26
|
+
/**
|
|
27
|
+
* Load a tree from saved data and get the proof for an address.
|
|
28
|
+
*/
|
|
29
|
+
declare function getProof(treeData: MerkleTreeData, address: string, count: number): string[] | null;
|
|
30
|
+
/**
|
|
31
|
+
* Verify a proof against a root (client-side).
|
|
32
|
+
*/
|
|
33
|
+
declare function verifyProof(treeData: MerkleTreeData, address: string, count: number, proof: string[]): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Build qualification array for contract calls: [count, ...proof]
|
|
36
|
+
*/
|
|
37
|
+
declare function buildQualification(count: number, proof: string[]): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Find an entry in the tree by address.
|
|
40
|
+
*/
|
|
41
|
+
declare function findEntry(treeData: MerkleTreeData, address: string): MerkleEntry | null;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* MerkleClient — chainId-aware client for the merkle API service.
|
|
45
|
+
*
|
|
46
|
+
* Resolves the API URL once at construction time so callers never
|
|
47
|
+
* need to pass chainId on every request.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
interface MerkleClientConfig {
|
|
51
|
+
/** Starknet chain ID, e.g. "SN_MAIN" or "SN_SEPOLIA" */
|
|
52
|
+
chainId: string;
|
|
53
|
+
/** Override the default API URL for this chain */
|
|
54
|
+
apiUrl?: string;
|
|
55
|
+
}
|
|
56
|
+
interface MerkleTree {
|
|
57
|
+
id: number;
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
root: string;
|
|
61
|
+
entryCount: number;
|
|
62
|
+
createdAt: string;
|
|
63
|
+
}
|
|
64
|
+
interface MerkleTreesResponse {
|
|
65
|
+
data: MerkleTree[];
|
|
66
|
+
total: number;
|
|
67
|
+
page: number;
|
|
68
|
+
limit: number;
|
|
69
|
+
totalPages: number;
|
|
70
|
+
}
|
|
71
|
+
interface MerkleProofResponse {
|
|
72
|
+
address: string;
|
|
73
|
+
count: number;
|
|
74
|
+
proof: string[];
|
|
75
|
+
qualification: string[];
|
|
76
|
+
}
|
|
77
|
+
interface MerkleTreeEntry {
|
|
78
|
+
address: string;
|
|
79
|
+
count: number;
|
|
80
|
+
}
|
|
81
|
+
interface MerkleTreeEntriesResponse {
|
|
82
|
+
data: MerkleTreeEntry[];
|
|
83
|
+
total: number;
|
|
84
|
+
page: number;
|
|
85
|
+
limit: number;
|
|
86
|
+
totalPages: number;
|
|
87
|
+
}
|
|
88
|
+
interface CreateMerkleTreeRequest {
|
|
89
|
+
id: number;
|
|
90
|
+
name: string;
|
|
91
|
+
description: string;
|
|
92
|
+
entries: MerkleEntry[];
|
|
93
|
+
}
|
|
94
|
+
interface CreateMerkleTreeResponse {
|
|
95
|
+
id: number;
|
|
96
|
+
root: string;
|
|
97
|
+
entryCount: number;
|
|
98
|
+
}
|
|
99
|
+
interface TreeCalldata {
|
|
100
|
+
tree: ReturnType<typeof buildMerkleTree>;
|
|
101
|
+
call: {
|
|
102
|
+
contractAddress: string;
|
|
103
|
+
entrypoint: string;
|
|
104
|
+
calldata: string[];
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
declare class MerkleClient {
|
|
108
|
+
readonly apiUrl: string;
|
|
109
|
+
constructor(config: MerkleClientConfig);
|
|
110
|
+
/** Fetch paginated list of merkle trees. */
|
|
111
|
+
getTrees(options?: {
|
|
112
|
+
page?: number;
|
|
113
|
+
limit?: number;
|
|
114
|
+
}): Promise<MerkleTreesResponse>;
|
|
115
|
+
/** Fetch entries for a specific merkle tree. */
|
|
116
|
+
getTreeEntries(treeId: string | number, options?: {
|
|
117
|
+
page?: number;
|
|
118
|
+
limit?: number;
|
|
119
|
+
}): Promise<MerkleTreeEntriesResponse>;
|
|
120
|
+
/** Fetch a merkle proof for a player address. */
|
|
121
|
+
getProof(treeId: string | number, playerAddress: string): Promise<MerkleProofResponse | null>;
|
|
122
|
+
/** Store a merkle tree in the API (after on-chain registration). */
|
|
123
|
+
storeTree(request: CreateMerkleTreeRequest): Promise<CreateMerkleTreeResponse>;
|
|
124
|
+
/**
|
|
125
|
+
* Build a merkle tree locally and return the calldata needed
|
|
126
|
+
* to register it on-chain via the validator contract.
|
|
127
|
+
*
|
|
128
|
+
* The consumer is responsible for executing the call with their
|
|
129
|
+
* own account/signer.
|
|
130
|
+
*/
|
|
131
|
+
buildTreeCalldata(entries: MerkleEntry[], validatorAddress: string): TreeCalldata;
|
|
132
|
+
/**
|
|
133
|
+
* Parse the tree ID from transaction receipt events.
|
|
134
|
+
* Returns null if the event cannot be found.
|
|
135
|
+
*/
|
|
136
|
+
parseTreeIdFromEvents(events: any[], validatorAddress: string): number | null;
|
|
137
|
+
/**
|
|
138
|
+
* Store the tree in the API after on-chain registration.
|
|
139
|
+
* Pass the tree ID from the on-chain event along with the original entries.
|
|
140
|
+
*/
|
|
141
|
+
createTree(params: {
|
|
142
|
+
treeId: number;
|
|
143
|
+
name: string;
|
|
144
|
+
description: string;
|
|
145
|
+
entries: MerkleEntry[];
|
|
146
|
+
}): Promise<CreateMerkleTreeResponse>;
|
|
147
|
+
}
|
|
148
|
+
/** Factory function for creating a MerkleClient. */
|
|
149
|
+
declare function createMerkleClient(config: MerkleClientConfig): MerkleClient;
|
|
150
|
+
|
|
151
|
+
export { type CreateMerkleTreeRequest, type CreateMerkleTreeResponse, MerkleClient, type MerkleClientConfig, type MerkleEntry, type MerkleProofResponse, type MerkleTree, type MerkleTreeData, type MerkleTreeEntriesResponse, type MerkleTreeEntry, type MerkleTreesResponse, type TreeCalldata, buildMerkleTree, buildQualification, computeLeafValue, createMerkleClient, findEntry, getProof, verifyProof };
|
package/dist/merkle.d.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
interface MerkleEntry {
|
|
2
|
+
address: string;
|
|
3
|
+
count: number;
|
|
4
|
+
}
|
|
5
|
+
interface MerkleTreeData {
|
|
6
|
+
version: 2;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
entries: MerkleEntry[];
|
|
9
|
+
root: string;
|
|
10
|
+
tree: any;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compute the leaf value that gets passed to StandardMerkleTree.
|
|
14
|
+
* This matches the Cairo contract's leaf computation:
|
|
15
|
+
* PedersenTrait::new(0).update(address).update(count).finalize()
|
|
16
|
+
*
|
|
17
|
+
* The StandardMerkleTree then applies its own leaf hashing on top:
|
|
18
|
+
* H(0, value, 1) using PedersenCHasher
|
|
19
|
+
*/
|
|
20
|
+
declare function computeLeafValue(address: string, count: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Build a StandardMerkleTree from entries.
|
|
23
|
+
* Each leaf is a single felt252 value (the pre-hashed leaf value).
|
|
24
|
+
*/
|
|
25
|
+
declare function buildMerkleTree(entries: MerkleEntry[]): MerkleTreeData;
|
|
26
|
+
/**
|
|
27
|
+
* Load a tree from saved data and get the proof for an address.
|
|
28
|
+
*/
|
|
29
|
+
declare function getProof(treeData: MerkleTreeData, address: string, count: number): string[] | null;
|
|
30
|
+
/**
|
|
31
|
+
* Verify a proof against a root (client-side).
|
|
32
|
+
*/
|
|
33
|
+
declare function verifyProof(treeData: MerkleTreeData, address: string, count: number, proof: string[]): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Build qualification array for contract calls: [count, ...proof]
|
|
36
|
+
*/
|
|
37
|
+
declare function buildQualification(count: number, proof: string[]): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Find an entry in the tree by address.
|
|
40
|
+
*/
|
|
41
|
+
declare function findEntry(treeData: MerkleTreeData, address: string): MerkleEntry | null;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* MerkleClient — chainId-aware client for the merkle API service.
|
|
45
|
+
*
|
|
46
|
+
* Resolves the API URL once at construction time so callers never
|
|
47
|
+
* need to pass chainId on every request.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
interface MerkleClientConfig {
|
|
51
|
+
/** Starknet chain ID, e.g. "SN_MAIN" or "SN_SEPOLIA" */
|
|
52
|
+
chainId: string;
|
|
53
|
+
/** Override the default API URL for this chain */
|
|
54
|
+
apiUrl?: string;
|
|
55
|
+
}
|
|
56
|
+
interface MerkleTree {
|
|
57
|
+
id: number;
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
root: string;
|
|
61
|
+
entryCount: number;
|
|
62
|
+
createdAt: string;
|
|
63
|
+
}
|
|
64
|
+
interface MerkleTreesResponse {
|
|
65
|
+
data: MerkleTree[];
|
|
66
|
+
total: number;
|
|
67
|
+
page: number;
|
|
68
|
+
limit: number;
|
|
69
|
+
totalPages: number;
|
|
70
|
+
}
|
|
71
|
+
interface MerkleProofResponse {
|
|
72
|
+
address: string;
|
|
73
|
+
count: number;
|
|
74
|
+
proof: string[];
|
|
75
|
+
qualification: string[];
|
|
76
|
+
}
|
|
77
|
+
interface MerkleTreeEntry {
|
|
78
|
+
address: string;
|
|
79
|
+
count: number;
|
|
80
|
+
}
|
|
81
|
+
interface MerkleTreeEntriesResponse {
|
|
82
|
+
data: MerkleTreeEntry[];
|
|
83
|
+
total: number;
|
|
84
|
+
page: number;
|
|
85
|
+
limit: number;
|
|
86
|
+
totalPages: number;
|
|
87
|
+
}
|
|
88
|
+
interface CreateMerkleTreeRequest {
|
|
89
|
+
id: number;
|
|
90
|
+
name: string;
|
|
91
|
+
description: string;
|
|
92
|
+
entries: MerkleEntry[];
|
|
93
|
+
}
|
|
94
|
+
interface CreateMerkleTreeResponse {
|
|
95
|
+
id: number;
|
|
96
|
+
root: string;
|
|
97
|
+
entryCount: number;
|
|
98
|
+
}
|
|
99
|
+
interface TreeCalldata {
|
|
100
|
+
tree: ReturnType<typeof buildMerkleTree>;
|
|
101
|
+
call: {
|
|
102
|
+
contractAddress: string;
|
|
103
|
+
entrypoint: string;
|
|
104
|
+
calldata: string[];
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
declare class MerkleClient {
|
|
108
|
+
readonly apiUrl: string;
|
|
109
|
+
constructor(config: MerkleClientConfig);
|
|
110
|
+
/** Fetch paginated list of merkle trees. */
|
|
111
|
+
getTrees(options?: {
|
|
112
|
+
page?: number;
|
|
113
|
+
limit?: number;
|
|
114
|
+
}): Promise<MerkleTreesResponse>;
|
|
115
|
+
/** Fetch entries for a specific merkle tree. */
|
|
116
|
+
getTreeEntries(treeId: string | number, options?: {
|
|
117
|
+
page?: number;
|
|
118
|
+
limit?: number;
|
|
119
|
+
}): Promise<MerkleTreeEntriesResponse>;
|
|
120
|
+
/** Fetch a merkle proof for a player address. */
|
|
121
|
+
getProof(treeId: string | number, playerAddress: string): Promise<MerkleProofResponse | null>;
|
|
122
|
+
/** Store a merkle tree in the API (after on-chain registration). */
|
|
123
|
+
storeTree(request: CreateMerkleTreeRequest): Promise<CreateMerkleTreeResponse>;
|
|
124
|
+
/**
|
|
125
|
+
* Build a merkle tree locally and return the calldata needed
|
|
126
|
+
* to register it on-chain via the validator contract.
|
|
127
|
+
*
|
|
128
|
+
* The consumer is responsible for executing the call with their
|
|
129
|
+
* own account/signer.
|
|
130
|
+
*/
|
|
131
|
+
buildTreeCalldata(entries: MerkleEntry[], validatorAddress: string): TreeCalldata;
|
|
132
|
+
/**
|
|
133
|
+
* Parse the tree ID from transaction receipt events.
|
|
134
|
+
* Returns null if the event cannot be found.
|
|
135
|
+
*/
|
|
136
|
+
parseTreeIdFromEvents(events: any[], validatorAddress: string): number | null;
|
|
137
|
+
/**
|
|
138
|
+
* Store the tree in the API after on-chain registration.
|
|
139
|
+
* Pass the tree ID from the on-chain event along with the original entries.
|
|
140
|
+
*/
|
|
141
|
+
createTree(params: {
|
|
142
|
+
treeId: number;
|
|
143
|
+
name: string;
|
|
144
|
+
description: string;
|
|
145
|
+
entries: MerkleEntry[];
|
|
146
|
+
}): Promise<CreateMerkleTreeResponse>;
|
|
147
|
+
}
|
|
148
|
+
/** Factory function for creating a MerkleClient. */
|
|
149
|
+
declare function createMerkleClient(config: MerkleClientConfig): MerkleClient;
|
|
150
|
+
|
|
151
|
+
export { type CreateMerkleTreeRequest, type CreateMerkleTreeResponse, MerkleClient, type MerkleClientConfig, type MerkleEntry, type MerkleProofResponse, type MerkleTree, type MerkleTreeData, type MerkleTreeEntriesResponse, type MerkleTreeEntry, type MerkleTreesResponse, type TreeCalldata, buildMerkleTree, buildQualification, computeLeafValue, createMerkleClient, findEntry, getProof, verifyProof };
|