@silvana-one/storage 0.1.0
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 +1 -0
- package/dist/node/base64/bigint.d.ts +6 -0
- package/dist/node/base64/bigint.js +83 -0
- package/dist/node/base64/bigint.js.map +1 -0
- package/dist/node/base64/field.d.ts +5 -0
- package/dist/node/base64/field.js +29 -0
- package/dist/node/base64/field.js.map +1 -0
- package/dist/node/base64/index.d.ts +2 -0
- package/dist/node/base64/index.js +3 -0
- package/dist/node/base64/index.js.map +1 -0
- package/dist/node/index.cjs +735 -0
- package/dist/node/index.d.ts +5 -0
- package/dist/node/index.js +6 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/indexed-map/index.d.ts +1 -0
- package/dist/node/indexed-map/index.js +2 -0
- package/dist/node/indexed-map/index.js.map +1 -0
- package/dist/node/indexed-map/indexed-map.d.ts +39 -0
- package/dist/node/indexed-map/indexed-map.js +125 -0
- package/dist/node/indexed-map/indexed-map.js.map +1 -0
- package/dist/node/storage/index.d.ts +3 -0
- package/dist/node/storage/index.js +4 -0
- package/dist/node/storage/index.js.map +1 -0
- package/dist/node/storage/ipfs.d.ts +5 -0
- package/dist/node/storage/ipfs.js +16 -0
- package/dist/node/storage/ipfs.js.map +1 -0
- package/dist/node/storage/pinata.d.ts +6 -0
- package/dist/node/storage/pinata.js +40 -0
- package/dist/node/storage/pinata.js.map +1 -0
- package/dist/node/storage/storage.d.ts +78 -0
- package/dist/node/storage/storage.js +60 -0
- package/dist/node/storage/storage.js.map +1 -0
- package/dist/node/util/index.d.ts +1 -0
- package/dist/node/util/index.js +2 -0
- package/dist/node/util/index.js.map +1 -0
- package/dist/node/util/sleep.d.ts +1 -0
- package/dist/node/util/sleep.js +4 -0
- package/dist/node/util/sleep.js.map +1 -0
- package/dist/node/whitelist/index.d.ts +2 -0
- package/dist/node/whitelist/index.js +3 -0
- package/dist/node/whitelist/index.js.map +1 -0
- package/dist/node/whitelist/offchain-map.d.ts +352 -0
- package/dist/node/whitelist/offchain-map.js +247 -0
- package/dist/node/whitelist/offchain-map.js.map +1 -0
- package/dist/node/whitelist/whitelist.d.ts +122 -0
- package/dist/node/whitelist/whitelist.js +98 -0
- package/dist/node/whitelist/whitelist.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/tsconfig.web.tsbuildinfo +1 -0
- package/dist/web/base64/bigint.d.ts +6 -0
- package/dist/web/base64/bigint.js +83 -0
- package/dist/web/base64/bigint.js.map +1 -0
- package/dist/web/base64/field.d.ts +5 -0
- package/dist/web/base64/field.js +29 -0
- package/dist/web/base64/field.js.map +1 -0
- package/dist/web/base64/index.d.ts +2 -0
- package/dist/web/base64/index.js +3 -0
- package/dist/web/base64/index.js.map +1 -0
- package/dist/web/index.d.ts +5 -0
- package/dist/web/index.js +6 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/indexed-map/index.d.ts +1 -0
- package/dist/web/indexed-map/index.js +2 -0
- package/dist/web/indexed-map/index.js.map +1 -0
- package/dist/web/indexed-map/indexed-map.d.ts +39 -0
- package/dist/web/indexed-map/indexed-map.js +125 -0
- package/dist/web/indexed-map/indexed-map.js.map +1 -0
- package/dist/web/storage/index.d.ts +3 -0
- package/dist/web/storage/index.js +4 -0
- package/dist/web/storage/index.js.map +1 -0
- package/dist/web/storage/ipfs.d.ts +5 -0
- package/dist/web/storage/ipfs.js +16 -0
- package/dist/web/storage/ipfs.js.map +1 -0
- package/dist/web/storage/pinata.d.ts +6 -0
- package/dist/web/storage/pinata.js +40 -0
- package/dist/web/storage/pinata.js.map +1 -0
- package/dist/web/storage/storage.d.ts +78 -0
- package/dist/web/storage/storage.js +60 -0
- package/dist/web/storage/storage.js.map +1 -0
- package/dist/web/util/index.d.ts +1 -0
- package/dist/web/util/index.js +2 -0
- package/dist/web/util/index.js.map +1 -0
- package/dist/web/util/sleep.d.ts +1 -0
- package/dist/web/util/sleep.js +4 -0
- package/dist/web/util/sleep.js.map +1 -0
- package/dist/web/whitelist/index.d.ts +2 -0
- package/dist/web/whitelist/index.js +3 -0
- package/dist/web/whitelist/index.js.map +1 -0
- package/dist/web/whitelist/offchain-map.d.ts +352 -0
- package/dist/web/whitelist/offchain-map.js +247 -0
- package/dist/web/whitelist/offchain-map.js.map +1 -0
- package/dist/web/whitelist/whitelist.d.ts +122 -0
- package/dist/web/whitelist/whitelist.js +98 -0
- package/dist/web/whitelist/whitelist.js.map +1 -0
- package/package.json +60 -0
- package/src/base64/bigint.ts +87 -0
- package/src/base64/field.ts +34 -0
- package/src/base64/index.ts +2 -0
- package/src/index.ts +5 -0
- package/src/indexed-map/index.ts +1 -0
- package/src/indexed-map/indexed-map.ts +189 -0
- package/src/storage/index.ts +3 -0
- package/src/storage/ipfs.ts +20 -0
- package/src/storage/pinata.ts +56 -0
- package/src/storage/storage.ts +65 -0
- package/src/util/index.ts +1 -0
- package/src/util/sleep.ts +3 -0
- package/src/whitelist/index.ts +2 -0
- package/src/whitelist/offchain-map.ts +341 -0
- package/src/whitelist/whitelist.ts +139 -0
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// dist/node/index.js
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
FieldOption: () => FieldOption,
|
|
24
|
+
OffChainList: () => OffChainList,
|
|
25
|
+
OffChainListBase: () => OffChainListBase,
|
|
26
|
+
OffchainMap: () => OffchainMap,
|
|
27
|
+
OffchainMapOption: () => OffchainMapOption,
|
|
28
|
+
Storage: () => Storage,
|
|
29
|
+
UInt64Option: () => UInt64Option,
|
|
30
|
+
Whitelist: () => Whitelist,
|
|
31
|
+
WhitelistedAddress: () => WhitelistedAddress,
|
|
32
|
+
bigintFromBase56: () => bigintFromBase56,
|
|
33
|
+
bigintFromBase64: () => bigintFromBase64,
|
|
34
|
+
bigintToBase56: () => bigintToBase56,
|
|
35
|
+
bigintToBase64: () => bigintToBase64,
|
|
36
|
+
createIpfsURL: () => createIpfsURL,
|
|
37
|
+
deserializeIndexedMerkleMap: () => deserializeIndexedMerkleMap,
|
|
38
|
+
fieldFromBase56: () => fieldFromBase56,
|
|
39
|
+
fieldFromBase64: () => fieldFromBase64,
|
|
40
|
+
fieldToBase56: () => fieldToBase56,
|
|
41
|
+
fieldToBase64: () => fieldToBase64,
|
|
42
|
+
fromBase: () => fromBase,
|
|
43
|
+
loadIndexedMerkleMap: () => loadIndexedMerkleMap,
|
|
44
|
+
parseIndexedMapSerialized: () => parseIndexedMapSerialized,
|
|
45
|
+
pinJSON: () => pinJSON,
|
|
46
|
+
saveIndexedMerkleMap: () => saveIndexedMerkleMap,
|
|
47
|
+
serializeIndexedMap: () => serializeIndexedMap,
|
|
48
|
+
sleep: () => sleep,
|
|
49
|
+
toBase: () => toBase
|
|
50
|
+
});
|
|
51
|
+
module.exports = __toCommonJS(index_exports);
|
|
52
|
+
|
|
53
|
+
// dist/node/base64/bigint.js
|
|
54
|
+
var TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
55
|
+
function bigintToBase56(value) {
|
|
56
|
+
const digits = toBase(value, 56n);
|
|
57
|
+
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
|
58
|
+
return str;
|
|
59
|
+
}
|
|
60
|
+
function bigintFromBase56(str) {
|
|
61
|
+
const base56Digits = str.split("").map((x2) => BigInt(TABLE.indexOf(x2)));
|
|
62
|
+
const x = fromBase(base56Digits, 56n);
|
|
63
|
+
return x;
|
|
64
|
+
}
|
|
65
|
+
function bigintToBase64(value) {
|
|
66
|
+
const digits = toBase(value, 64n);
|
|
67
|
+
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
|
68
|
+
return str;
|
|
69
|
+
}
|
|
70
|
+
function bigintFromBase64(str) {
|
|
71
|
+
const base64Digits = str.split("").map((x2) => BigInt(TABLE.indexOf(x2)));
|
|
72
|
+
const x = fromBase(base64Digits, 64n);
|
|
73
|
+
return x;
|
|
74
|
+
}
|
|
75
|
+
function fromBase(digits, base) {
|
|
76
|
+
if (base <= 0n)
|
|
77
|
+
throw Error("fromBase: base must be positive");
|
|
78
|
+
let basePowers = [];
|
|
79
|
+
for (let power = base, n = 1; n < digits.length; power **= 2n, n *= 2) {
|
|
80
|
+
basePowers.push(power);
|
|
81
|
+
}
|
|
82
|
+
let k = basePowers.length;
|
|
83
|
+
digits = digits.concat(Array(2 ** k - digits.length).fill(0n));
|
|
84
|
+
for (let i = 0; i < k; i++) {
|
|
85
|
+
let newDigits = Array(digits.length >> 1);
|
|
86
|
+
let basePower = basePowers[i];
|
|
87
|
+
for (let j = 0; j < newDigits.length; j++) {
|
|
88
|
+
newDigits[j] = digits[2 * j] + basePower * digits[2 * j + 1];
|
|
89
|
+
}
|
|
90
|
+
digits = newDigits;
|
|
91
|
+
}
|
|
92
|
+
console.assert(digits.length === 1);
|
|
93
|
+
let [digit] = digits;
|
|
94
|
+
return digit;
|
|
95
|
+
}
|
|
96
|
+
function toBase(x, base) {
|
|
97
|
+
if (base <= 0n)
|
|
98
|
+
throw Error("toBase: base must be positive");
|
|
99
|
+
let basePowers = [];
|
|
100
|
+
for (let power = base; power <= x; power **= 2n) {
|
|
101
|
+
basePowers.push(power);
|
|
102
|
+
}
|
|
103
|
+
let digits = [x];
|
|
104
|
+
let k = basePowers.length;
|
|
105
|
+
for (let i = 0; i < k; i++) {
|
|
106
|
+
let newDigits = Array(2 * digits.length);
|
|
107
|
+
let basePower = basePowers[k - 1 - i];
|
|
108
|
+
for (let j = 0; j < digits.length; j++) {
|
|
109
|
+
let x2 = digits[j];
|
|
110
|
+
let high = x2 / basePower;
|
|
111
|
+
newDigits[2 * j + 1] = high;
|
|
112
|
+
newDigits[2 * j] = x2 - high * basePower;
|
|
113
|
+
}
|
|
114
|
+
digits = newDigits;
|
|
115
|
+
}
|
|
116
|
+
while (digits[digits.length - 1] === 0n) {
|
|
117
|
+
digits.pop();
|
|
118
|
+
}
|
|
119
|
+
return digits;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// dist/node/base64/field.js
|
|
123
|
+
var import_o1js = require("o1js");
|
|
124
|
+
var TABLE2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
125
|
+
function fieldToBase56(field) {
|
|
126
|
+
const digits = toBase(field.toBigInt(), 56n);
|
|
127
|
+
const str = digits.map((x) => TABLE2[Number(x)]).join("");
|
|
128
|
+
return str;
|
|
129
|
+
}
|
|
130
|
+
function fieldFromBase56(str) {
|
|
131
|
+
const base56Digits = str.split("").map((x2) => BigInt(TABLE2.indexOf(x2)));
|
|
132
|
+
const x = fromBase(base56Digits, 56n);
|
|
133
|
+
return (0, import_o1js.Field)(x);
|
|
134
|
+
}
|
|
135
|
+
function fieldToBase64(field) {
|
|
136
|
+
const digits = toBase(field.toBigInt(), 64n);
|
|
137
|
+
const str = digits.map((x) => TABLE2[Number(x)]).join("");
|
|
138
|
+
return str;
|
|
139
|
+
}
|
|
140
|
+
function fieldFromBase64(str) {
|
|
141
|
+
const base64Digits = str.split("").map((x2) => BigInt(TABLE2.indexOf(x2)));
|
|
142
|
+
const x = fromBase(base64Digits, 64n);
|
|
143
|
+
return (0, import_o1js.Field)(x);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// dist/node/indexed-map/indexed-map.js
|
|
147
|
+
var import_o1js2 = require("o1js");
|
|
148
|
+
|
|
149
|
+
// dist/node/util/sleep.js
|
|
150
|
+
function sleep(ms) {
|
|
151
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// dist/node/storage/pinata.js
|
|
155
|
+
async function pinJSON(params) {
|
|
156
|
+
const { data, name = "data.json", keyvalues = { library: "zkcloudworker" } } = params;
|
|
157
|
+
const auth = params.auth ?? process.env.PINATA_JWT ?? process.env.NEXT_PUBLIC_PINATA_JWT ?? process.env.REACT_APP_PINATA_JWT;
|
|
158
|
+
if (!auth)
|
|
159
|
+
throw new Error("pinJSON: auth, PINATA_JWT, NEXT_PUBLIC_PINATA_JWT or REACT_APP_PINATA_JWT should be defined");
|
|
160
|
+
try {
|
|
161
|
+
const pinataData = {
|
|
162
|
+
pinataOptions: {
|
|
163
|
+
cidVersion: 1
|
|
164
|
+
},
|
|
165
|
+
pinataMetadata: {
|
|
166
|
+
name,
|
|
167
|
+
keyvalues
|
|
168
|
+
},
|
|
169
|
+
pinataContent: data
|
|
170
|
+
};
|
|
171
|
+
const res = await fetch("https://api.pinata.cloud/pinning/pinJSONToIPFS", {
|
|
172
|
+
method: "POST",
|
|
173
|
+
headers: {
|
|
174
|
+
"Content-Type": "application/json",
|
|
175
|
+
Authorization: "Bearer " + auth
|
|
176
|
+
},
|
|
177
|
+
body: JSON.stringify(pinataData)
|
|
178
|
+
});
|
|
179
|
+
if (!res.ok) {
|
|
180
|
+
throw new Error(`Pinata error: status: ${res.status} ${res.statusText}`);
|
|
181
|
+
}
|
|
182
|
+
const responseData = await res.json();
|
|
183
|
+
console.log("saveToIPFS result:", responseData);
|
|
184
|
+
return responseData?.IpfsHash;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error("saveToIPFS error:", error?.message);
|
|
187
|
+
return void 0;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// dist/node/indexed-map/indexed-map.js
|
|
192
|
+
var { IndexedMerkleMap } = import_o1js2.Experimental;
|
|
193
|
+
async function loadIndexedMerkleMap(params) {
|
|
194
|
+
const { url, type, name = "indexed-map", timeout = 6e4, attempts = 5 } = params;
|
|
195
|
+
let attempt = 0;
|
|
196
|
+
const start = Date.now();
|
|
197
|
+
let response = await fetch(url);
|
|
198
|
+
while (!response.ok && attempt < attempts && Date.now() - start < timeout) {
|
|
199
|
+
attempt++;
|
|
200
|
+
await sleep(5e3 * attempt);
|
|
201
|
+
response = await fetch(url);
|
|
202
|
+
}
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
throw new Error("Failed to fetch IndexedMerkleMap");
|
|
205
|
+
}
|
|
206
|
+
const json = await response.json();
|
|
207
|
+
const serializedIndexedMap = json[name].map;
|
|
208
|
+
if (!serializedIndexedMap)
|
|
209
|
+
throw new Error("wrong IndexedMerkleMap json format");
|
|
210
|
+
const map = deserializeIndexedMerkleMapInternal({
|
|
211
|
+
serializedIndexedMap,
|
|
212
|
+
type
|
|
213
|
+
});
|
|
214
|
+
if (!map) {
|
|
215
|
+
throw new Error("Failed to deserialize whitelist");
|
|
216
|
+
}
|
|
217
|
+
return map;
|
|
218
|
+
}
|
|
219
|
+
async function saveIndexedMerkleMap(params) {
|
|
220
|
+
const { map, name = "indexed-map", keyvalues, auth, filename = "indexed-map" } = params;
|
|
221
|
+
const serialized = serializeIndexedMap(map);
|
|
222
|
+
const json = { [name]: { map: serialized } };
|
|
223
|
+
const ipfsHash = await pinJSON({
|
|
224
|
+
data: json,
|
|
225
|
+
name: filename,
|
|
226
|
+
keyvalues,
|
|
227
|
+
auth
|
|
228
|
+
});
|
|
229
|
+
return ipfsHash;
|
|
230
|
+
}
|
|
231
|
+
function serializeIndexedMap(map) {
|
|
232
|
+
return {
|
|
233
|
+
height: map.height,
|
|
234
|
+
root: map.root.toJSON(),
|
|
235
|
+
length: map.length.toJSON(),
|
|
236
|
+
nodes: JSON.stringify(map.data.get().nodes, (_, v) => typeof v === "bigint" ? "n" + bigintToBase64(v) : v),
|
|
237
|
+
sortedLeaves: JSON.stringify(map.data.get().sortedLeaves.map((v) => [
|
|
238
|
+
bigintToBase64(v.key),
|
|
239
|
+
bigintToBase64(v.nextKey),
|
|
240
|
+
bigintToBase64(v.value),
|
|
241
|
+
bigintToBase64(BigInt(v.index))
|
|
242
|
+
]))
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function deserializeIndexedMerkleMap(params) {
|
|
246
|
+
try {
|
|
247
|
+
const { serializedIndexedMap, type } = params;
|
|
248
|
+
return deserializeIndexedMerkleMapInternal({
|
|
249
|
+
serializedIndexedMap,
|
|
250
|
+
type: type ?? IndexedMerkleMap(serializedIndexedMap.height)
|
|
251
|
+
});
|
|
252
|
+
} catch (error) {
|
|
253
|
+
console.error("Error deserializing map:", error?.message ?? error);
|
|
254
|
+
return void 0;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function parseIndexedMapSerialized(serializedMap) {
|
|
258
|
+
const json = JSON.parse(serializedMap);
|
|
259
|
+
if (json.height === void 0 || json.root === void 0 || json.length === void 0 || json.nodes === void 0 || json.sortedLeaves === void 0)
|
|
260
|
+
throw new Error("wrong IndexedMerkleMap json format");
|
|
261
|
+
if (typeof json.height !== "number")
|
|
262
|
+
throw new Error("wrong IndexedMerkleMap height format");
|
|
263
|
+
if (typeof json.root !== "string")
|
|
264
|
+
throw new Error("wrong IndexedMerkleMap root format");
|
|
265
|
+
if (typeof json.length !== "string")
|
|
266
|
+
throw new Error("wrong IndexedMerkleMap length format");
|
|
267
|
+
if (typeof json.nodes !== "string")
|
|
268
|
+
throw new Error("wrong IndexedMerkleMap nodes format");
|
|
269
|
+
if (typeof json.sortedLeaves !== "string")
|
|
270
|
+
throw new Error("wrong IndexedMerkleMap sortedLeaves format");
|
|
271
|
+
return json;
|
|
272
|
+
}
|
|
273
|
+
function deserializeIndexedMerkleMapInternal(params) {
|
|
274
|
+
const { serializedIndexedMap, type } = params;
|
|
275
|
+
const map = new type();
|
|
276
|
+
if (serializedIndexedMap.height !== map.height) {
|
|
277
|
+
throw new Error("wrong IndexedMap height");
|
|
278
|
+
}
|
|
279
|
+
const nodes = JSON.parse(serializedIndexedMap.nodes, (_, v) => {
|
|
280
|
+
if (typeof v === "string" && v[0] === "n") {
|
|
281
|
+
return bigintFromBase64(v.slice(1));
|
|
282
|
+
}
|
|
283
|
+
return v;
|
|
284
|
+
});
|
|
285
|
+
const sortedLeaves = JSON.parse(serializedIndexedMap.sortedLeaves).map((row) => {
|
|
286
|
+
return {
|
|
287
|
+
key: bigintFromBase64(row[0]),
|
|
288
|
+
nextKey: bigintFromBase64(row[1]),
|
|
289
|
+
value: bigintFromBase64(row[2]),
|
|
290
|
+
index: Number(bigintFromBase64(row[3]))
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
map.root = import_o1js2.Field.fromJSON(serializedIndexedMap.root);
|
|
294
|
+
map.length = import_o1js2.Field.fromJSON(serializedIndexedMap.length);
|
|
295
|
+
map.data.updateAsProver(() => {
|
|
296
|
+
return {
|
|
297
|
+
nodes: nodes.map((row) => [...row]),
|
|
298
|
+
sortedLeaves: [...sortedLeaves]
|
|
299
|
+
};
|
|
300
|
+
});
|
|
301
|
+
return map;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// dist/node/storage/ipfs.js
|
|
305
|
+
function createIpfsURL(params) {
|
|
306
|
+
let { hash, gateway, apiToken } = params;
|
|
307
|
+
gateway ??= process.env.PINATA_IPFS_GATEWAY ?? process.env.NEXT_PUBLIC_PINATA_IPFS_GATEWAY ?? process.env.REACT_APP_PINATA_IPFS_GATEWAY;
|
|
308
|
+
apiToken ??= process.env.PINATA_GATEWAY_TOKEN ?? process.env.NEXT_PUBLIC_PINATA_GATEWAY_TOKEN ?? process.env.REACT_APP_PINATA_GATEWAY_TOKEN;
|
|
309
|
+
if (!gateway) {
|
|
310
|
+
gateway = "https://gateway.pinata.cloud/ipfs/";
|
|
311
|
+
}
|
|
312
|
+
return gateway + hash + (apiToken ? "?pinataGatewayToken=" + apiToken : "");
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// dist/node/storage/storage.js
|
|
316
|
+
var import_o1js3 = require("o1js");
|
|
317
|
+
var Storage = class _Storage extends (0, import_o1js3.Struct)({
|
|
318
|
+
url: import_o1js3.Provable.Array(import_o1js3.Field, 2)
|
|
319
|
+
}) {
|
|
320
|
+
constructor(value) {
|
|
321
|
+
super(value);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Asserts that two Storage instances are equal.
|
|
325
|
+
* @param a The first Storage instance.
|
|
326
|
+
* @param b The second Storage instance.
|
|
327
|
+
*/
|
|
328
|
+
static assertEquals(a, b) {
|
|
329
|
+
a.url[0].assertEquals(b.url[0]);
|
|
330
|
+
a.url[1].assertEquals(b.url[1]);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Checks if two Storage instances are equal.
|
|
334
|
+
* @param a The first Storage instance.
|
|
335
|
+
* @param b The second Storage instance.
|
|
336
|
+
* @returns A Bool indicating whether the two instances are equal.
|
|
337
|
+
*/
|
|
338
|
+
static equals(a, b) {
|
|
339
|
+
return a.url[0].equals(b.url[0]).and(a.url[1].equals(b.url[1]));
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Creates a Storage instance from a string.
|
|
343
|
+
* @param url The string representing the storage URL.
|
|
344
|
+
* @returns A new Storage instance.
|
|
345
|
+
*/
|
|
346
|
+
static fromString(url) {
|
|
347
|
+
if (url === "")
|
|
348
|
+
return _Storage.empty();
|
|
349
|
+
const fields = import_o1js3.Encoding.stringToFields(url);
|
|
350
|
+
if (fields.length !== 2)
|
|
351
|
+
throw new Error("Invalid string length");
|
|
352
|
+
return new _Storage({ url: [fields[0], fields[1]] });
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Converts the Storage instance to a string.
|
|
356
|
+
* @returns The string representation of the storage URL.
|
|
357
|
+
*/
|
|
358
|
+
toString() {
|
|
359
|
+
if (this.isEmpty().toBoolean()) {
|
|
360
|
+
return "";
|
|
361
|
+
}
|
|
362
|
+
return import_o1js3.Encoding.stringFromFields([this.url[0], this.url[1]]);
|
|
363
|
+
}
|
|
364
|
+
static empty() {
|
|
365
|
+
return new _Storage({ url: [(0, import_o1js3.Field)(0), (0, import_o1js3.Field)(0)] });
|
|
366
|
+
}
|
|
367
|
+
isEmpty() {
|
|
368
|
+
return this.url[0].equals((0, import_o1js3.Field)(0)).and(this.url[1].equals((0, import_o1js3.Field)(0)));
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// dist/node/whitelist/whitelist.js
|
|
373
|
+
var import_o1js5 = require("o1js");
|
|
374
|
+
|
|
375
|
+
// dist/node/whitelist/offchain-map.js
|
|
376
|
+
var import_o1js4 = require("o1js");
|
|
377
|
+
var { IndexedMerkleMap: IndexedMerkleMap2 } = import_o1js4.Experimental;
|
|
378
|
+
var OFFCHAIN_MAP_HEIGHT = 20;
|
|
379
|
+
var OffchainMap = class extends IndexedMerkleMap2(OFFCHAIN_MAP_HEIGHT) {
|
|
380
|
+
};
|
|
381
|
+
var OffchainMapOption = class extends (0, import_o1js4.Option)(OffchainMap) {
|
|
382
|
+
};
|
|
383
|
+
var FieldOption = class extends (0, import_o1js4.Option)(import_o1js4.Field) {
|
|
384
|
+
};
|
|
385
|
+
var OffChainListBase = class _OffChainListBase extends (0, import_o1js4.Struct)({
|
|
386
|
+
/** The root hash of the Merkle tree representing the whitelist. */
|
|
387
|
+
root: import_o1js4.Field
|
|
388
|
+
}) {
|
|
389
|
+
isNone() {
|
|
390
|
+
return this.root.equals((0, import_o1js4.Field)(0));
|
|
391
|
+
}
|
|
392
|
+
isSome() {
|
|
393
|
+
return this.isNone().not();
|
|
394
|
+
}
|
|
395
|
+
async load(storage, name = "offchain-map") {
|
|
396
|
+
const isNone = this.isNone();
|
|
397
|
+
const map = await import_o1js4.Provable.witnessAsync(OffchainMapOption, async () => {
|
|
398
|
+
if (isNone.toBoolean())
|
|
399
|
+
return OffchainMapOption.none();
|
|
400
|
+
else
|
|
401
|
+
return OffchainMapOption.fromValue(await loadIndexedMerkleMap({
|
|
402
|
+
url: createIpfsURL({ hash: storage.toString() }),
|
|
403
|
+
type: OffchainMap,
|
|
404
|
+
name
|
|
405
|
+
}));
|
|
406
|
+
});
|
|
407
|
+
isNone.assertEquals(map.isSome.not());
|
|
408
|
+
const root = import_o1js4.Provable.if(map.isSome, map.orElse(new OffchainMap()).root, (0, import_o1js4.Field)(0));
|
|
409
|
+
root.assertEquals(this.root);
|
|
410
|
+
return map;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* The function fetches a whitelisted amount associated with a given key using a map and returns it
|
|
414
|
+
* as a FieldOption.
|
|
415
|
+
* @param {Field} key - The `key` parameter is of type `Field`,
|
|
416
|
+
* which represents a field element in the context of a cryptographic system.
|
|
417
|
+
* @returns The `getValue` function returns a `Promise` that resolves to a `FieldOption`
|
|
418
|
+
* object. This object contains a `value` property representing the amount retrieved from a map based
|
|
419
|
+
* on the provided key. The `isSome` property indicates whether the value is present or not.
|
|
420
|
+
* The value is not present if the list is NOT empty and the key is NOT in the map.
|
|
421
|
+
* The value is present if the list IS empty or the key IS in the map.
|
|
422
|
+
* The value is present and equals to Field(0) if the list IS empty.
|
|
423
|
+
*/
|
|
424
|
+
async getValue(key, storage, name = "offchain-map") {
|
|
425
|
+
const map = await this.load(storage, name);
|
|
426
|
+
const value = map.orElse(new OffchainMap()).getOption(key);
|
|
427
|
+
const valueField = value.orElse((0, import_o1js4.Field)(0));
|
|
428
|
+
return new FieldOption({
|
|
429
|
+
value: valueField,
|
|
430
|
+
isSome: value.isSome.or(this.isNone())
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
static empty() {
|
|
434
|
+
return new _OffChainListBase({
|
|
435
|
+
root: (0, import_o1js4.Field)(0)
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Creates a new OffchainListBase
|
|
440
|
+
* @param params - The parameters for creating the list.
|
|
441
|
+
* @param params.list - The list of entries to be added to the map.
|
|
442
|
+
* @param params.data - The JSON data that should be added to the IPFS storage that represent the initial data
|
|
443
|
+
* @returns A new `OffChainList` instance.
|
|
444
|
+
*/
|
|
445
|
+
static async create(params) {
|
|
446
|
+
function toField(value) {
|
|
447
|
+
if (!value)
|
|
448
|
+
return (0, import_o1js4.Field)(0);
|
|
449
|
+
if (typeof value === "string")
|
|
450
|
+
return import_o1js4.Field.fromJSON(value);
|
|
451
|
+
if (typeof value === "bigint" || typeof value === "number")
|
|
452
|
+
return (0, import_o1js4.Field)(value);
|
|
453
|
+
return value;
|
|
454
|
+
}
|
|
455
|
+
const list = params.list.map((item) => ({
|
|
456
|
+
key: toField(item.key),
|
|
457
|
+
value: toField(item.value)
|
|
458
|
+
}));
|
|
459
|
+
const map = new OffchainMap();
|
|
460
|
+
for (const item of list) {
|
|
461
|
+
map.insert(item.key, item.value);
|
|
462
|
+
}
|
|
463
|
+
const serializedMap = serializeIndexedMap(map);
|
|
464
|
+
const json = {
|
|
465
|
+
[params.name ?? "offchain-map"]: {
|
|
466
|
+
map: serializedMap,
|
|
467
|
+
list: list.map((item) => ({
|
|
468
|
+
key: item.key.toJSON(),
|
|
469
|
+
value: item.value?.toJSON()
|
|
470
|
+
})),
|
|
471
|
+
data: params.data
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
return {
|
|
475
|
+
listBase: new _OffChainListBase({
|
|
476
|
+
root: map.root
|
|
477
|
+
}),
|
|
478
|
+
json
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
toString() {
|
|
482
|
+
return JSON.stringify({ root: this.root.toJSON() }, null, 2);
|
|
483
|
+
}
|
|
484
|
+
static fromString(str) {
|
|
485
|
+
const json = JSON.parse(str);
|
|
486
|
+
return new _OffChainListBase({
|
|
487
|
+
root: import_o1js4.Field.fromJSON(json.root)
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
var OffChainList = class _OffChainList extends (0, import_o1js4.Struct)({
|
|
492
|
+
/** The root hash of the Merkle tree representing the whitelist. */
|
|
493
|
+
root: import_o1js4.Field,
|
|
494
|
+
/** Off-chain storage information, typically an IPFS hash pointing to the whitelist data. */
|
|
495
|
+
storage: Storage
|
|
496
|
+
}) {
|
|
497
|
+
isNone() {
|
|
498
|
+
return this.root.equals((0, import_o1js4.Field)(0)).or(this.storage.isEmpty());
|
|
499
|
+
}
|
|
500
|
+
isSome() {
|
|
501
|
+
return this.isNone().not();
|
|
502
|
+
}
|
|
503
|
+
async load(name = "offchain-map") {
|
|
504
|
+
const isNone = this.isNone();
|
|
505
|
+
const map = await import_o1js4.Provable.witnessAsync(OffchainMapOption, async () => {
|
|
506
|
+
if (isNone.toBoolean())
|
|
507
|
+
return OffchainMapOption.none();
|
|
508
|
+
else
|
|
509
|
+
return OffchainMapOption.fromValue(await loadIndexedMerkleMap({
|
|
510
|
+
url: createIpfsURL({ hash: this.storage.toString() }),
|
|
511
|
+
type: OffchainMap,
|
|
512
|
+
name
|
|
513
|
+
}));
|
|
514
|
+
});
|
|
515
|
+
isNone.assertEquals(map.isSome.not());
|
|
516
|
+
const root = import_o1js4.Provable.if(map.isSome, map.orElse(new OffchainMap()).root, (0, import_o1js4.Field)(0));
|
|
517
|
+
root.assertEquals(this.root);
|
|
518
|
+
return map;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* The function fetches a whitelisted amount associated with a given key using a map and returns it
|
|
522
|
+
* as a FieldOption.
|
|
523
|
+
* @param {Field} key - The `key` parameter is of type `Field`,
|
|
524
|
+
* which represents a field element in the context of a cryptographic system.
|
|
525
|
+
* @returns The `getValue` function returns a `Promise` that resolves to a `FieldOption`
|
|
526
|
+
* object. This object contains a `value` property representing the amount retrieved from a map based
|
|
527
|
+
* on the provided key. The `isSome` property indicates whether the value is present or not.
|
|
528
|
+
* The value is not present if the list is NOT empty and the key is NOT in the map.
|
|
529
|
+
* The value is present if the list IS empty or the key IS in the map.
|
|
530
|
+
* The value is present and equals to Field(0) if the list IS empty.
|
|
531
|
+
*/
|
|
532
|
+
async getValue(key, name = "offchain-map") {
|
|
533
|
+
const map = await this.load(name);
|
|
534
|
+
const value = map.orElse(new OffchainMap()).getOption(key);
|
|
535
|
+
const valueField = value.orElse((0, import_o1js4.Field)(0));
|
|
536
|
+
return new FieldOption({
|
|
537
|
+
value: valueField,
|
|
538
|
+
isSome: value.isSome.or(this.isNone())
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
static empty() {
|
|
542
|
+
return new _OffChainList({
|
|
543
|
+
root: (0, import_o1js4.Field)(0),
|
|
544
|
+
storage: Storage.empty()
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Creates a new OffchainList
|
|
549
|
+
* and pins it to IPFS.
|
|
550
|
+
* @param params - The parameters for creating the list.
|
|
551
|
+
* @param params.list - The list of entries to be added to the map.
|
|
552
|
+
* @param params.data - The JSON data that should be added to the IPFS storage that represent the initial data
|
|
553
|
+
* @returns A new `OffChainList` instance.
|
|
554
|
+
*/
|
|
555
|
+
static async create(params) {
|
|
556
|
+
const { name = "offchain-map", filename = "offchain-list.json", keyvalues, timeout = 60 * 1e3, attempts = 5, auth, pin = true, json: initialJson = {} } = params;
|
|
557
|
+
const { listBase, json: newJson } = await OffChainListBase.create({
|
|
558
|
+
list: params.list,
|
|
559
|
+
data: params.data,
|
|
560
|
+
name
|
|
561
|
+
});
|
|
562
|
+
const json = { ...initialJson, ...newJson };
|
|
563
|
+
if (process.env.DEBUG === "true")
|
|
564
|
+
console.log("OffChainList.create:", { json, name, keyvalues });
|
|
565
|
+
if (pin) {
|
|
566
|
+
let attempt = 0;
|
|
567
|
+
const start = Date.now();
|
|
568
|
+
let hash = await pinJSON({
|
|
569
|
+
data: json,
|
|
570
|
+
name: filename,
|
|
571
|
+
keyvalues,
|
|
572
|
+
auth
|
|
573
|
+
});
|
|
574
|
+
while (!hash && attempt < attempts && Date.now() - start < timeout) {
|
|
575
|
+
attempt++;
|
|
576
|
+
await sleep(5e3 * attempt);
|
|
577
|
+
hash = await pinJSON({
|
|
578
|
+
data: json,
|
|
579
|
+
name,
|
|
580
|
+
keyvalues,
|
|
581
|
+
auth
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
if (!hash)
|
|
585
|
+
throw new Error("Failed to pin OffchainMap");
|
|
586
|
+
return {
|
|
587
|
+
list: new _OffChainList({
|
|
588
|
+
root: listBase.root,
|
|
589
|
+
storage: Storage.fromString(hash)
|
|
590
|
+
}),
|
|
591
|
+
json
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
return {
|
|
595
|
+
list: new _OffChainList({
|
|
596
|
+
root: listBase.root,
|
|
597
|
+
storage: Storage.empty()
|
|
598
|
+
}),
|
|
599
|
+
json
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
toString() {
|
|
603
|
+
return JSON.stringify({ root: this.root.toJSON(), storage: this.storage.toString() }, null, 2);
|
|
604
|
+
}
|
|
605
|
+
static fromString(str) {
|
|
606
|
+
const json = JSON.parse(str);
|
|
607
|
+
return new _OffChainList({
|
|
608
|
+
root: import_o1js4.Field.fromJSON(json.root),
|
|
609
|
+
storage: Storage.fromString(json.storage)
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
// dist/node/whitelist/whitelist.js
|
|
615
|
+
var UInt64Option = class extends (0, import_o1js5.Option)(import_o1js5.UInt64) {
|
|
616
|
+
};
|
|
617
|
+
var WhitelistedAddress = class {
|
|
618
|
+
};
|
|
619
|
+
var Whitelist = class _Whitelist extends (0, import_o1js5.Struct)({
|
|
620
|
+
list: OffChainList
|
|
621
|
+
}) {
|
|
622
|
+
isNone() {
|
|
623
|
+
return this.list.isNone();
|
|
624
|
+
}
|
|
625
|
+
isSome() {
|
|
626
|
+
return this.list.isSome();
|
|
627
|
+
}
|
|
628
|
+
async load() {
|
|
629
|
+
return this.list.load();
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* The function fetches a whitelisted amount associated with a given address using a map and returns it
|
|
633
|
+
* as a UInt64Option.
|
|
634
|
+
* @param {PublicKey} address - The `address` parameter is of type `PublicKey`,
|
|
635
|
+
* used to retrieve a whitelisted amount for the given address.
|
|
636
|
+
* @returns The `fetchWhitelistedAmount` function returns a `Promise` that resolves to a `UInt64Option`
|
|
637
|
+
* object. This object contains a `value` property representing the amount retrieved from a map based
|
|
638
|
+
* on the provided address. The `isSome` property indicates whether the value is present or not.
|
|
639
|
+
* The value is not present if the whitelist is NOT empty and the address is NOT whitelisted.
|
|
640
|
+
* The value is present if the whitelist is NOT empty or the address IS whitelisted.
|
|
641
|
+
* The value is present and equals to UInt64.MAXINT() if the whitelist IS empty.
|
|
642
|
+
*/
|
|
643
|
+
async getWhitelistedAmount(address, name = "whitelist") {
|
|
644
|
+
const map = await this.list.load(name);
|
|
645
|
+
const key = import_o1js5.Poseidon.hashPacked(import_o1js5.PublicKey, address);
|
|
646
|
+
const value = map.orElse(new OffchainMap()).getOption(key);
|
|
647
|
+
const valueField = value.orElse(import_o1js5.UInt64.MAXINT().value);
|
|
648
|
+
valueField.assertLessThanOrEqual(import_o1js5.UInt64.MAXINT().value);
|
|
649
|
+
const amount = import_o1js5.UInt64.Unsafe.fromField(valueField);
|
|
650
|
+
return new UInt64Option({
|
|
651
|
+
value: amount,
|
|
652
|
+
isSome: value.isSome.or(this.isNone())
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
static empty() {
|
|
656
|
+
return new _Whitelist({
|
|
657
|
+
list: OffChainList.empty()
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Creates a new whitelist and pins it to IPFS.
|
|
662
|
+
* @param params - The parameters for creating the whitelist.
|
|
663
|
+
* @returns A new `Whitelist` instance.
|
|
664
|
+
*/
|
|
665
|
+
static async create(params) {
|
|
666
|
+
const { name = "whitelist", filename = "whitelist.json", keyvalues, timeout, attempts, auth, pin = true, json: initialJson = {} } = params;
|
|
667
|
+
function parseAddress(address) {
|
|
668
|
+
return typeof address === "string" ? import_o1js5.PublicKey.fromBase58(address) : address;
|
|
669
|
+
}
|
|
670
|
+
function parseAmount(amount) {
|
|
671
|
+
if (amount === void 0)
|
|
672
|
+
return import_o1js5.UInt64.zero;
|
|
673
|
+
return typeof amount === "number" ? import_o1js5.UInt64.from(Math.round(amount)) : amount;
|
|
674
|
+
}
|
|
675
|
+
const entries = params.list.map((item) => ({
|
|
676
|
+
address: parseAddress(item.address),
|
|
677
|
+
amount: parseAmount(item.amount)
|
|
678
|
+
}));
|
|
679
|
+
const { list, json } = await OffChainList.create({
|
|
680
|
+
list: entries.map((item) => ({
|
|
681
|
+
key: import_o1js5.Poseidon.hashPacked(import_o1js5.PublicKey, item.address),
|
|
682
|
+
value: item.amount.value
|
|
683
|
+
})),
|
|
684
|
+
data: entries.map((item) => ({
|
|
685
|
+
address: item.address.toBase58(),
|
|
686
|
+
amount: Number(item.amount.toBigInt())
|
|
687
|
+
})),
|
|
688
|
+
name,
|
|
689
|
+
filename,
|
|
690
|
+
keyvalues,
|
|
691
|
+
timeout,
|
|
692
|
+
attempts,
|
|
693
|
+
auth,
|
|
694
|
+
pin,
|
|
695
|
+
json: initialJson
|
|
696
|
+
});
|
|
697
|
+
return { whitelist: new _Whitelist({ list }), json };
|
|
698
|
+
}
|
|
699
|
+
toString() {
|
|
700
|
+
return this.list.toString();
|
|
701
|
+
}
|
|
702
|
+
static fromString(str) {
|
|
703
|
+
return new _Whitelist({ list: OffChainList.fromString(str) });
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
707
|
+
0 && (module.exports = {
|
|
708
|
+
FieldOption,
|
|
709
|
+
OffChainList,
|
|
710
|
+
OffChainListBase,
|
|
711
|
+
OffchainMap,
|
|
712
|
+
OffchainMapOption,
|
|
713
|
+
Storage,
|
|
714
|
+
UInt64Option,
|
|
715
|
+
Whitelist,
|
|
716
|
+
WhitelistedAddress,
|
|
717
|
+
bigintFromBase56,
|
|
718
|
+
bigintFromBase64,
|
|
719
|
+
bigintToBase56,
|
|
720
|
+
bigintToBase64,
|
|
721
|
+
createIpfsURL,
|
|
722
|
+
deserializeIndexedMerkleMap,
|
|
723
|
+
fieldFromBase56,
|
|
724
|
+
fieldFromBase64,
|
|
725
|
+
fieldToBase56,
|
|
726
|
+
fieldToBase64,
|
|
727
|
+
fromBase,
|
|
728
|
+
loadIndexedMerkleMap,
|
|
729
|
+
parseIndexedMapSerialized,
|
|
730
|
+
pinJSON,
|
|
731
|
+
saveIndexedMerkleMap,
|
|
732
|
+
serializeIndexedMap,
|
|
733
|
+
sleep,
|
|
734
|
+
toBase
|
|
735
|
+
});
|