@unlink-xyz/core 0.1.5 → 0.1.7-canary.252b8ea
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/account/account.d.ts +1 -1
- package/dist/account/account.d.ts.map +1 -1
- package/dist/browser/index.js +476 -215
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/wallet/index.js +427 -213
- package/dist/browser/wallet/index.js.map +1 -1
- package/dist/clients/http.d.ts.map +1 -1
- package/dist/config.d.ts +20 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +399 -138
- package/dist/index.js.map +1 -1
- package/dist/transactions/adapter.d.ts +34 -1
- package/dist/transactions/adapter.d.ts.map +1 -1
- package/dist/transactions/index.d.ts +1 -1
- package/dist/transactions/index.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/async.js.map +1 -1
- package/dist/utils/validators.d.ts +1 -1
- package/dist/wallet/adapter.d.ts +2 -2
- package/dist/wallet/adapter.d.ts.map +1 -1
- package/dist/wallet/burner/service.d.ts +1 -0
- package/dist/wallet/burner/service.d.ts.map +1 -1
- package/dist/wallet/burner/types.d.ts +2 -2
- package/dist/wallet/burner/types.d.ts.map +1 -1
- package/dist/wallet/index.d.ts +2 -2
- package/dist/wallet/index.d.ts.map +1 -1
- package/dist/wallet/index.js +350 -136
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/sdk.d.ts +8 -9
- package/dist/wallet/sdk.d.ts.map +1 -1
- package/dist/wallet/types.d.ts +61 -52
- package/dist/wallet/types.d.ts.map +1 -1
- package/dist/wallet/{unlink-wallet.d.ts → unlink.d.ts} +44 -38
- package/dist/wallet/unlink.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/wallet/unlink-wallet.d.ts.map +0 -1
package/dist/wallet/index.js
CHANGED
|
@@ -1827,63 +1827,110 @@ var Runtime = {
|
|
|
1827
1827
|
|
|
1828
1828
|
// config.ts
|
|
1829
1829
|
var CONFIG_URL = "https://config.unlink.xyz/networks.json";
|
|
1830
|
-
function parseRequiredString(
|
|
1830
|
+
function parseRequiredString(chain, field, value) {
|
|
1831
1831
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
1832
1832
|
throw new InitializationError(
|
|
1833
|
-
`Invalid SDK config for ${
|
|
1833
|
+
`Invalid SDK config for ${chain}: ${field} must be a non-empty string`
|
|
1834
1834
|
);
|
|
1835
1835
|
}
|
|
1836
1836
|
return value.trim();
|
|
1837
1837
|
}
|
|
1838
|
-
function parseOptionalString(
|
|
1838
|
+
function parseOptionalString(chain, field, value) {
|
|
1839
1839
|
if (value === void 0) return void 0;
|
|
1840
1840
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
1841
1841
|
throw new InitializationError(
|
|
1842
|
-
`Invalid SDK config for ${
|
|
1842
|
+
`Invalid SDK config for ${chain}: ${field} must be a non-empty string when provided`
|
|
1843
1843
|
);
|
|
1844
1844
|
}
|
|
1845
1845
|
return value.trim();
|
|
1846
1846
|
}
|
|
1847
|
-
function
|
|
1847
|
+
function parseRequiredChainId(chain, value) {
|
|
1848
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
1849
|
+
throw new InitializationError(
|
|
1850
|
+
`Invalid SDK config for ${chain}: chainId must be a positive integer`
|
|
1851
|
+
);
|
|
1852
|
+
}
|
|
1853
|
+
return value;
|
|
1854
|
+
}
|
|
1855
|
+
function parseChainConfig(chain, value) {
|
|
1848
1856
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
1849
1857
|
throw new InitializationError(
|
|
1850
|
-
`Invalid SDK config for ${
|
|
1858
|
+
`Invalid SDK config for ${chain}: expected object`
|
|
1851
1859
|
);
|
|
1852
1860
|
}
|
|
1853
1861
|
const raw = value;
|
|
1862
|
+
const chainId = parseRequiredChainId(chain, raw.chainId);
|
|
1854
1863
|
const gatewayUrl = parseRequiredString(
|
|
1855
|
-
|
|
1864
|
+
chain,
|
|
1856
1865
|
"gatewayUrl",
|
|
1857
1866
|
raw.gatewayUrl
|
|
1858
1867
|
).replace(/\/+$/, "");
|
|
1859
|
-
const poolAddress = parseRequiredString(
|
|
1868
|
+
const poolAddress = parseRequiredString(
|
|
1869
|
+
chain,
|
|
1870
|
+
"poolAddress",
|
|
1871
|
+
raw.poolAddress
|
|
1872
|
+
);
|
|
1860
1873
|
const artifactVersion = parseRequiredString(
|
|
1861
|
-
|
|
1874
|
+
chain,
|
|
1862
1875
|
"artifactVersion",
|
|
1863
1876
|
raw.artifactVersion
|
|
1864
1877
|
).replace(/^\/+|\/+$/g, "");
|
|
1878
|
+
const adapterAddress = parseOptionalString(
|
|
1879
|
+
chain,
|
|
1880
|
+
"adapterAddress",
|
|
1881
|
+
raw.adapterAddress
|
|
1882
|
+
);
|
|
1883
|
+
const frostUrl = parseOptionalString(
|
|
1884
|
+
chain,
|
|
1885
|
+
"frostUrl",
|
|
1886
|
+
raw.frostUrl
|
|
1887
|
+
)?.replace(/\/+$/, "");
|
|
1865
1888
|
const artifactBaseUrl = parseOptionalString(
|
|
1866
|
-
|
|
1889
|
+
chain,
|
|
1867
1890
|
"artifactBaseUrl",
|
|
1868
1891
|
raw.artifactBaseUrl
|
|
1869
1892
|
)?.replace(/\/+$/, "");
|
|
1893
|
+
let tokenAddresses;
|
|
1894
|
+
if (raw.tokenAddresses !== void 0) {
|
|
1895
|
+
if (raw.tokenAddresses === null || typeof raw.tokenAddresses !== "object" || Array.isArray(raw.tokenAddresses)) {
|
|
1896
|
+
throw new InitializationError(
|
|
1897
|
+
`Invalid SDK config for ${chain}: tokenAddresses must be an object`
|
|
1898
|
+
);
|
|
1899
|
+
}
|
|
1900
|
+
tokenAddresses = {};
|
|
1901
|
+
for (const [name, addr] of Object.entries(
|
|
1902
|
+
raw.tokenAddresses
|
|
1903
|
+
)) {
|
|
1904
|
+
tokenAddresses[name] = parseRequiredString(
|
|
1905
|
+
chain,
|
|
1906
|
+
`tokenAddresses.${name}`,
|
|
1907
|
+
addr
|
|
1908
|
+
);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1870
1911
|
return {
|
|
1912
|
+
chainId,
|
|
1871
1913
|
gatewayUrl,
|
|
1914
|
+
...frostUrl !== void 0 ? { frostUrl } : {},
|
|
1872
1915
|
poolAddress,
|
|
1916
|
+
...adapterAddress !== void 0 ? { adapterAddress } : {},
|
|
1873
1917
|
artifactVersion,
|
|
1874
|
-
...artifactBaseUrl !== void 0 ? { artifactBaseUrl } : { artifactBaseUrl: DEFAULT_ARTIFACT_BASE_URL }
|
|
1918
|
+
...artifactBaseUrl !== void 0 ? { artifactBaseUrl } : { artifactBaseUrl: DEFAULT_ARTIFACT_BASE_URL },
|
|
1919
|
+
...tokenAddresses !== void 0 ? { tokenAddresses } : {}
|
|
1875
1920
|
};
|
|
1876
1921
|
}
|
|
1877
|
-
async function
|
|
1922
|
+
async function fetchChainConfig(chain) {
|
|
1878
1923
|
const res = await fetch(CONFIG_URL);
|
|
1879
1924
|
if (!res.ok) {
|
|
1880
1925
|
throw new InitializationError(`Failed to fetch SDK config: ${res.status}`);
|
|
1881
1926
|
}
|
|
1882
1927
|
const config = await res.json();
|
|
1883
|
-
if (!config[
|
|
1884
|
-
throw new InitializationError(
|
|
1928
|
+
if (!config[chain]) {
|
|
1929
|
+
throw new InitializationError(
|
|
1930
|
+
`Unknown chain: "${chain}". Supported chains: ${Object.keys(config).join(", ")}`
|
|
1931
|
+
);
|
|
1885
1932
|
}
|
|
1886
|
-
return
|
|
1933
|
+
return parseChainConfig(chain, config[chain]);
|
|
1887
1934
|
}
|
|
1888
1935
|
function createServiceConfig(gatewayUrl) {
|
|
1889
1936
|
const baseUrl = gatewayUrl.replace(/\/+$/, "");
|
|
@@ -2220,9 +2267,9 @@ var Hex = class _Hex {
|
|
|
2220
2267
|
|
|
2221
2268
|
// keys/address.ts
|
|
2222
2269
|
var VERSION = 1;
|
|
2223
|
-
var LIMIT =
|
|
2270
|
+
var LIMIT = 130;
|
|
2224
2271
|
var ALL_CHAINS = "ffffffffffffffff";
|
|
2225
|
-
var PREFIX = "
|
|
2272
|
+
var PREFIX = "unlink";
|
|
2226
2273
|
var SALT = new TextEncoder().encode("unlink");
|
|
2227
2274
|
function xorWithSalt(hex) {
|
|
2228
2275
|
const bytes = Hex.toBytes(hex);
|
|
@@ -3970,29 +4017,41 @@ function createJsonHttpClient(baseUrl, deps) {
|
|
|
3970
4017
|
fetch: fetchImpl,
|
|
3971
4018
|
// Disable ky's automatic error throwing to prevent browser DevTools
|
|
3972
4019
|
// from logging expected 404s as network errors
|
|
3973
|
-
throwHttpErrors: false
|
|
4020
|
+
throwHttpErrors: false,
|
|
4021
|
+
retry: 0
|
|
3974
4022
|
});
|
|
4023
|
+
const RETRYABLE_STATUSES = [502, 503, 504];
|
|
4024
|
+
const MAX_RETRIES = 3;
|
|
4025
|
+
const BASE_DELAY_MS = 500;
|
|
3975
4026
|
return {
|
|
3976
4027
|
async request(opts) {
|
|
3977
4028
|
let res;
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
4029
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
4030
|
+
try {
|
|
4031
|
+
res = await api(opts.path.replace(/^\//, ""), {
|
|
4032
|
+
method: opts.method,
|
|
4033
|
+
searchParams: opts.query,
|
|
4034
|
+
json: opts.json,
|
|
4035
|
+
body: opts.body,
|
|
4036
|
+
headers: opts.headers,
|
|
4037
|
+
signal: opts.signal
|
|
4038
|
+
});
|
|
4039
|
+
} catch (err) {
|
|
4040
|
+
if (err instanceof TimeoutError) {
|
|
4041
|
+
throw new HttpError("HTTP timeout", 408, null);
|
|
4042
|
+
}
|
|
4043
|
+
throw new HttpError(
|
|
4044
|
+
err instanceof Error ? err.message : "Network error",
|
|
4045
|
+
0,
|
|
4046
|
+
null
|
|
4047
|
+
);
|
|
3990
4048
|
}
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
4049
|
+
if (RETRYABLE_STATUSES.includes(res.status) && attempt < MAX_RETRIES) {
|
|
4050
|
+
const delay = BASE_DELAY_MS * 2 ** attempt + Math.random() * 200;
|
|
4051
|
+
await new Promise((r2) => setTimeout(r2, delay));
|
|
4052
|
+
continue;
|
|
4053
|
+
}
|
|
4054
|
+
break;
|
|
3996
4055
|
}
|
|
3997
4056
|
if (!res.ok) {
|
|
3998
4057
|
const body = await readErrorBodySafe(res);
|
|
@@ -4210,7 +4269,7 @@ function parseZkAddress(value) {
|
|
|
4210
4269
|
};
|
|
4211
4270
|
} catch (err) {
|
|
4212
4271
|
throw new ValidationError(
|
|
4213
|
-
`Invalid ZK address (expected
|
|
4272
|
+
`Invalid ZK address (expected unlink1... format): ${err instanceof Error ? err.message : "unknown error"}`
|
|
4214
4273
|
);
|
|
4215
4274
|
}
|
|
4216
4275
|
}
|
|
@@ -6206,6 +6265,114 @@ var circuits_default = {
|
|
|
6206
6265
|
template: "JoinSplit",
|
|
6207
6266
|
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6208
6267
|
params: [5, 2, 16]
|
|
6268
|
+
},
|
|
6269
|
+
joinsplit_1x3_16: {
|
|
6270
|
+
file: "joinsplit",
|
|
6271
|
+
template: "JoinSplit",
|
|
6272
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6273
|
+
params: [1, 3, 16]
|
|
6274
|
+
},
|
|
6275
|
+
joinsplit_4x3_16: {
|
|
6276
|
+
file: "joinsplit",
|
|
6277
|
+
template: "JoinSplit",
|
|
6278
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6279
|
+
params: [4, 3, 16]
|
|
6280
|
+
},
|
|
6281
|
+
joinsplit_5x3_16: {
|
|
6282
|
+
file: "joinsplit",
|
|
6283
|
+
template: "JoinSplit",
|
|
6284
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6285
|
+
params: [5, 3, 16]
|
|
6286
|
+
},
|
|
6287
|
+
joinsplit_6x1_16: {
|
|
6288
|
+
file: "joinsplit",
|
|
6289
|
+
template: "JoinSplit",
|
|
6290
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6291
|
+
params: [6, 1, 16]
|
|
6292
|
+
},
|
|
6293
|
+
joinsplit_6x2_16: {
|
|
6294
|
+
file: "joinsplit",
|
|
6295
|
+
template: "JoinSplit",
|
|
6296
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6297
|
+
params: [6, 2, 16]
|
|
6298
|
+
},
|
|
6299
|
+
joinsplit_6x3_16: {
|
|
6300
|
+
file: "joinsplit",
|
|
6301
|
+
template: "JoinSplit",
|
|
6302
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6303
|
+
params: [6, 3, 16]
|
|
6304
|
+
},
|
|
6305
|
+
joinsplit_7x1_16: {
|
|
6306
|
+
file: "joinsplit",
|
|
6307
|
+
template: "JoinSplit",
|
|
6308
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6309
|
+
params: [7, 1, 16]
|
|
6310
|
+
},
|
|
6311
|
+
joinsplit_7x2_16: {
|
|
6312
|
+
file: "joinsplit",
|
|
6313
|
+
template: "JoinSplit",
|
|
6314
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6315
|
+
params: [7, 2, 16]
|
|
6316
|
+
},
|
|
6317
|
+
joinsplit_7x3_16: {
|
|
6318
|
+
file: "joinsplit",
|
|
6319
|
+
template: "JoinSplit",
|
|
6320
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6321
|
+
params: [7, 3, 16]
|
|
6322
|
+
},
|
|
6323
|
+
joinsplit_8x1_16: {
|
|
6324
|
+
file: "joinsplit",
|
|
6325
|
+
template: "JoinSplit",
|
|
6326
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6327
|
+
params: [8, 1, 16]
|
|
6328
|
+
},
|
|
6329
|
+
joinsplit_8x2_16: {
|
|
6330
|
+
file: "joinsplit",
|
|
6331
|
+
template: "JoinSplit",
|
|
6332
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6333
|
+
params: [8, 2, 16]
|
|
6334
|
+
},
|
|
6335
|
+
joinsplit_8x3_16: {
|
|
6336
|
+
file: "joinsplit",
|
|
6337
|
+
template: "JoinSplit",
|
|
6338
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6339
|
+
params: [8, 3, 16]
|
|
6340
|
+
},
|
|
6341
|
+
joinsplit_9x1_16: {
|
|
6342
|
+
file: "joinsplit",
|
|
6343
|
+
template: "JoinSplit",
|
|
6344
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6345
|
+
params: [9, 1, 16]
|
|
6346
|
+
},
|
|
6347
|
+
joinsplit_9x2_16: {
|
|
6348
|
+
file: "joinsplit",
|
|
6349
|
+
template: "JoinSplit",
|
|
6350
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6351
|
+
params: [9, 2, 16]
|
|
6352
|
+
},
|
|
6353
|
+
joinsplit_9x3_16: {
|
|
6354
|
+
file: "joinsplit",
|
|
6355
|
+
template: "JoinSplit",
|
|
6356
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6357
|
+
params: [9, 3, 16]
|
|
6358
|
+
},
|
|
6359
|
+
joinsplit_10x1_16: {
|
|
6360
|
+
file: "joinsplit",
|
|
6361
|
+
template: "JoinSplit",
|
|
6362
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6363
|
+
params: [10, 1, 16]
|
|
6364
|
+
},
|
|
6365
|
+
joinsplit_10x2_16: {
|
|
6366
|
+
file: "joinsplit",
|
|
6367
|
+
template: "JoinSplit",
|
|
6368
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6369
|
+
params: [10, 2, 16]
|
|
6370
|
+
},
|
|
6371
|
+
joinsplit_10x3_16: {
|
|
6372
|
+
file: "joinsplit",
|
|
6373
|
+
template: "JoinSplit",
|
|
6374
|
+
pubs: ["merkleRoot", "boundParamsHash", "nullifiers", "commitmentsOut"],
|
|
6375
|
+
params: [10, 3, 16]
|
|
6209
6376
|
}
|
|
6210
6377
|
};
|
|
6211
6378
|
|
|
@@ -6225,7 +6392,7 @@ function getCircuitConfig(inputs, outputs) {
|
|
|
6225
6392
|
}
|
|
6226
6393
|
|
|
6227
6394
|
// prover/prover.ts
|
|
6228
|
-
var MAX_ARTIFACT_CACHE_ENTRIES =
|
|
6395
|
+
var MAX_ARTIFACT_CACHE_ENTRIES = 16;
|
|
6229
6396
|
var artifactCache = /* @__PURE__ */ new Map();
|
|
6230
6397
|
function selectCircuit(inputs, outputs) {
|
|
6231
6398
|
const config = getCircuitConfig(inputs, outputs);
|
|
@@ -8208,26 +8375,34 @@ function normalizeCall2(call, index) {
|
|
|
8208
8375
|
value: call.value
|
|
8209
8376
|
};
|
|
8210
8377
|
}
|
|
8211
|
-
function
|
|
8212
|
-
const token = ensureAddress(`
|
|
8378
|
+
function normalizeSpendInput(input, index) {
|
|
8379
|
+
const token = ensureAddress(`spend[${index}].token`, input.token);
|
|
8380
|
+
if (token.toLowerCase() === ETH_TOKEN.toLowerCase()) {
|
|
8381
|
+
throw new AdapterError(
|
|
8382
|
+
`spend[${index}].token: native ETH is not supported in adapter execution`
|
|
8383
|
+
);
|
|
8384
|
+
}
|
|
8213
8385
|
if (input.amount <= 0n) {
|
|
8214
|
-
throw new AdapterError(`
|
|
8386
|
+
throw new AdapterError(`spend[${index}].amount must be greater than zero`);
|
|
8215
8387
|
}
|
|
8216
8388
|
return {
|
|
8217
8389
|
token,
|
|
8218
8390
|
amount: input.amount
|
|
8219
8391
|
};
|
|
8220
8392
|
}
|
|
8221
|
-
function
|
|
8222
|
-
const token = ensureAddress(`
|
|
8223
|
-
if (
|
|
8393
|
+
function normalizeReceiveInput(receive, index) {
|
|
8394
|
+
const token = ensureAddress(`receive[${index}].token`, receive.token);
|
|
8395
|
+
if (token.toLowerCase() === ETH_TOKEN.toLowerCase()) {
|
|
8224
8396
|
throw new AdapterError(
|
|
8225
|
-
`
|
|
8397
|
+
`receive[${index}].token: native ETH is not supported in adapter execution`
|
|
8226
8398
|
);
|
|
8227
8399
|
}
|
|
8400
|
+
if (receive.minAmount < 0n) {
|
|
8401
|
+
throw new AdapterError(`receive[${index}].minAmount must be non-negative`);
|
|
8402
|
+
}
|
|
8228
8403
|
return {
|
|
8229
8404
|
token,
|
|
8230
|
-
minAmount:
|
|
8405
|
+
minAmount: receive.minAmount
|
|
8231
8406
|
};
|
|
8232
8407
|
}
|
|
8233
8408
|
function randomFieldElement(randomBigintFn) {
|
|
@@ -8247,32 +8422,42 @@ function createAdapterService(deps) {
|
|
|
8247
8422
|
"adapterAddress",
|
|
8248
8423
|
params.adapterAddress
|
|
8249
8424
|
);
|
|
8250
|
-
if (!params.
|
|
8251
|
-
throw new AdapterError("at least one
|
|
8425
|
+
if (!params.spend.length) {
|
|
8426
|
+
throw new AdapterError("at least one spend token is required");
|
|
8252
8427
|
}
|
|
8253
8428
|
if (!params.calls.length) {
|
|
8254
8429
|
throw new AdapterError("at least one adapter call is required");
|
|
8255
8430
|
}
|
|
8256
|
-
if (!params.
|
|
8257
|
-
throw new AdapterError("at least one
|
|
8431
|
+
if (!params.receive.length) {
|
|
8432
|
+
throw new AdapterError("at least one receive output is required");
|
|
8258
8433
|
}
|
|
8259
|
-
const
|
|
8260
|
-
(input, i) =>
|
|
8434
|
+
const spendInputs = params.spend.map(
|
|
8435
|
+
(input, i) => normalizeSpendInput(input, i)
|
|
8261
8436
|
);
|
|
8262
8437
|
const seenTokens = /* @__PURE__ */ new Set();
|
|
8263
|
-
for (const input of
|
|
8438
|
+
for (const input of spendInputs) {
|
|
8264
8439
|
const lower = input.token.toLowerCase();
|
|
8265
8440
|
if (seenTokens.has(lower)) {
|
|
8266
8441
|
throw new AdapterError(
|
|
8267
|
-
`duplicate
|
|
8442
|
+
`duplicate spend token ${input.token}; combine amounts per token instead`
|
|
8268
8443
|
);
|
|
8269
8444
|
}
|
|
8270
8445
|
seenTokens.add(lower);
|
|
8271
8446
|
}
|
|
8272
8447
|
const calls = params.calls.map((call, i) => normalizeCall2(call, i));
|
|
8273
|
-
const
|
|
8274
|
-
(
|
|
8448
|
+
const receiveSpecs = params.receive.map(
|
|
8449
|
+
(receive, i) => normalizeReceiveInput(receive, i)
|
|
8275
8450
|
);
|
|
8451
|
+
const seenReceiveTokens = /* @__PURE__ */ new Set();
|
|
8452
|
+
for (const r2 of receiveSpecs) {
|
|
8453
|
+
const lower = r2.token.toLowerCase();
|
|
8454
|
+
if (seenReceiveTokens.has(lower)) {
|
|
8455
|
+
throw new AdapterError(
|
|
8456
|
+
`duplicate receive token ${r2.token}; each receive must target a unique token`
|
|
8457
|
+
);
|
|
8458
|
+
}
|
|
8459
|
+
seenReceiveTokens.add(lower);
|
|
8460
|
+
}
|
|
8276
8461
|
const account = overrides?.account ?? await deps.requireActiveAccount();
|
|
8277
8462
|
const signer = overrides?.signer ?? deps.requireSigner(account);
|
|
8278
8463
|
const nowSeconds = BigInt(Math.floor(nowImpl() / 1e3));
|
|
@@ -8281,19 +8466,19 @@ function createAdapterService(deps) {
|
|
|
8281
8466
|
throw new AdapterError("deadline must be in the future");
|
|
8282
8467
|
}
|
|
8283
8468
|
const executionCalls = calls;
|
|
8284
|
-
const reshields =
|
|
8285
|
-
(
|
|
8469
|
+
const reshields = receiveSpecs.map(
|
|
8470
|
+
(receive) => {
|
|
8286
8471
|
const random = randomFieldElement(randomBigintImpl);
|
|
8287
8472
|
const npk = poseidon([account.masterPublicKey, random]);
|
|
8288
8473
|
return {
|
|
8289
8474
|
npk,
|
|
8290
8475
|
random,
|
|
8291
|
-
token:
|
|
8292
|
-
minAmount:
|
|
8476
|
+
token: receive.token,
|
|
8477
|
+
minAmount: receive.minAmount
|
|
8293
8478
|
};
|
|
8294
8479
|
}
|
|
8295
8480
|
);
|
|
8296
|
-
const inputTokens =
|
|
8481
|
+
const inputTokens = spendInputs.map((input) => input.token);
|
|
8297
8482
|
const nonce = randomFieldElement(randomBigintImpl);
|
|
8298
8483
|
const adapterDataHash = computeAdapterDataHash({
|
|
8299
8484
|
calls: executionCalls,
|
|
@@ -8310,7 +8495,7 @@ function createAdapterService(deps) {
|
|
|
8310
8495
|
});
|
|
8311
8496
|
const withdrawalPlans = planWithdrawalsImpl(
|
|
8312
8497
|
notes,
|
|
8313
|
-
|
|
8498
|
+
spendInputs.map((input) => ({
|
|
8314
8499
|
token: input.token,
|
|
8315
8500
|
amount: input.amount,
|
|
8316
8501
|
recipient: adapterAddress
|
|
@@ -8393,7 +8578,7 @@ function createAdapterService(deps) {
|
|
|
8393
8578
|
adapterCalldata,
|
|
8394
8579
|
historyPreview: {
|
|
8395
8580
|
kind: "Withdraw",
|
|
8396
|
-
amounts:
|
|
8581
|
+
amounts: spendInputs.map((input) => ({
|
|
8397
8582
|
token: input.token,
|
|
8398
8583
|
delta: (-input.amount).toString()
|
|
8399
8584
|
}))
|
|
@@ -8420,6 +8605,9 @@ import {
|
|
|
8420
8605
|
} from "ethers";
|
|
8421
8606
|
var BIP44_ETH_PREFIX = "m/44'/60'/0'/0";
|
|
8422
8607
|
var ERC20_BALANCE_OF = "function balanceOf(address) view returns (uint256)";
|
|
8608
|
+
function isNativeToken(token) {
|
|
8609
|
+
return token.toLowerCase() === ETH_TOKEN.toLowerCase();
|
|
8610
|
+
}
|
|
8423
8611
|
function createBurnerService(deps) {
|
|
8424
8612
|
const { chainRpcUrl, getMasterSeed, withdrawToAddress, requestDeposit } = deps;
|
|
8425
8613
|
const provider = new JsonRpcProvider(chainRpcUrl);
|
|
@@ -8467,8 +8655,8 @@ function createBurnerService(deps) {
|
|
|
8467
8655
|
}
|
|
8468
8656
|
async function getTokenBalance(address, token) {
|
|
8469
8657
|
const iface = new Interface4([ERC20_BALANCE_OF]);
|
|
8470
|
-
const
|
|
8471
|
-
const bal = await
|
|
8658
|
+
const contract2 = new Contract(token, iface, provider);
|
|
8659
|
+
const bal = await contract2.getFunction("balanceOf")(address);
|
|
8472
8660
|
return BigInt(bal ?? 0);
|
|
8473
8661
|
}
|
|
8474
8662
|
async function getBalance(address) {
|
|
@@ -8487,6 +8675,12 @@ function createBurnerService(deps) {
|
|
|
8487
8675
|
}
|
|
8488
8676
|
async function sweepToPool(index, params) {
|
|
8489
8677
|
const { address } = await addressOf(index);
|
|
8678
|
+
const native = isNativeToken(params.token);
|
|
8679
|
+
if (native && params.amount == null) {
|
|
8680
|
+
throw new Error(
|
|
8681
|
+
"amount is required for native ETH sweeps (needed to reserve gas)"
|
|
8682
|
+
);
|
|
8683
|
+
}
|
|
8490
8684
|
const amount = params.amount ?? await getTokenBalance(address, params.token);
|
|
8491
8685
|
if (amount === 0n) {
|
|
8492
8686
|
throw new Error("No token balance to sweep");
|
|
@@ -8497,17 +8691,20 @@ function createBurnerService(deps) {
|
|
|
8497
8691
|
depositor: address,
|
|
8498
8692
|
deposits: [{ token: params.token, amount }]
|
|
8499
8693
|
});
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
|
|
8694
|
+
if (!native) {
|
|
8695
|
+
const erc20Iface = new Interface4([
|
|
8696
|
+
"function approve(address spender, uint256 amount)"
|
|
8697
|
+
]);
|
|
8698
|
+
const approveData = erc20Iface.encodeFunctionData("approve", [
|
|
8699
|
+
params.poolAddress,
|
|
8700
|
+
amount
|
|
8701
|
+
]);
|
|
8702
|
+
await send(index, { to: params.token, data: approveData });
|
|
8703
|
+
}
|
|
8508
8704
|
const { txHash } = await send(index, {
|
|
8509
8705
|
to: depositResult.to,
|
|
8510
|
-
data: depositResult.calldata
|
|
8706
|
+
data: depositResult.calldata,
|
|
8707
|
+
value: depositResult.value
|
|
8511
8708
|
});
|
|
8512
8709
|
return { txHash };
|
|
8513
8710
|
}
|
|
@@ -9163,28 +9360,31 @@ function createWalletSDK(deps, options) {
|
|
|
9163
9360
|
return sdk;
|
|
9164
9361
|
}
|
|
9165
9362
|
async function createBrowserWalletSDK(options) {
|
|
9363
|
+
let chainId;
|
|
9166
9364
|
let gatewayUrl;
|
|
9167
9365
|
let poolAddress;
|
|
9168
9366
|
let prover = options.prover;
|
|
9169
|
-
if ("
|
|
9367
|
+
if ("chain" in options) {
|
|
9368
|
+
const chainConfig = await fetchChainConfig(options.chain);
|
|
9369
|
+
chainId = chainConfig.chainId;
|
|
9370
|
+
gatewayUrl = chainConfig.gatewayUrl;
|
|
9371
|
+
poolAddress = options.poolAddress ?? chainConfig.poolAddress;
|
|
9372
|
+
prover = {
|
|
9373
|
+
artifactSource: {
|
|
9374
|
+
baseUrl: options.prover?.artifactSource?.baseUrl ?? chainConfig.artifactBaseUrl,
|
|
9375
|
+
version: options.prover?.artifactSource?.version ?? chainConfig.artifactVersion,
|
|
9376
|
+
preferLocalFiles: options.prover?.artifactSource?.preferLocalFiles
|
|
9377
|
+
}
|
|
9378
|
+
};
|
|
9379
|
+
} else {
|
|
9380
|
+
chainId = options.chainId;
|
|
9170
9381
|
gatewayUrl = options.gatewayUrl;
|
|
9171
9382
|
poolAddress = options.poolAddress;
|
|
9172
9383
|
if (typeof window !== "undefined" && !options.prover?.artifactSource?.version) {
|
|
9173
9384
|
throw new InitializationError(
|
|
9174
|
-
"prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use
|
|
9385
|
+
"prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use chain mode or provide a pinned artifact version."
|
|
9175
9386
|
);
|
|
9176
9387
|
}
|
|
9177
|
-
} else {
|
|
9178
|
-
const envConfig = await fetchEnvironmentConfig(options.environment);
|
|
9179
|
-
gatewayUrl = envConfig.gatewayUrl;
|
|
9180
|
-
poolAddress = options.poolAddress ?? envConfig.poolAddress;
|
|
9181
|
-
prover = {
|
|
9182
|
-
artifactSource: {
|
|
9183
|
-
baseUrl: options.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,
|
|
9184
|
-
version: options.prover?.artifactSource?.version ?? envConfig.artifactVersion,
|
|
9185
|
-
preferLocalFiles: options.prover?.artifactSource?.preferLocalFiles
|
|
9186
|
-
}
|
|
9187
|
-
};
|
|
9188
9388
|
}
|
|
9189
9389
|
const storage = createIndexedDbStorage({ name: "unlink-wallet" });
|
|
9190
9390
|
const rng = (n) => {
|
|
@@ -9201,7 +9401,7 @@ async function createBrowserWalletSDK(options) {
|
|
|
9201
9401
|
core,
|
|
9202
9402
|
fetch: globalThis.fetch
|
|
9203
9403
|
},
|
|
9204
|
-
{ chainId
|
|
9404
|
+
{ chainId, gatewayUrl, prover }
|
|
9205
9405
|
);
|
|
9206
9406
|
return {
|
|
9207
9407
|
sdk,
|
|
@@ -9214,51 +9414,63 @@ async function createBrowserWalletSDK(options) {
|
|
|
9214
9414
|
};
|
|
9215
9415
|
}
|
|
9216
9416
|
|
|
9217
|
-
// wallet/unlink
|
|
9218
|
-
var
|
|
9417
|
+
// wallet/unlink.ts
|
|
9418
|
+
var Unlink = class _Unlink {
|
|
9219
9419
|
/** @internal */
|
|
9220
9420
|
sdk;
|
|
9221
9421
|
/** Chain ID this wallet operates on. */
|
|
9222
9422
|
chainId;
|
|
9223
9423
|
/** Pool contract address this wallet transacts with. */
|
|
9224
9424
|
poolAddress;
|
|
9225
|
-
|
|
9425
|
+
/** Adapter contract address for DeFi operations. */
|
|
9426
|
+
adapterAddress;
|
|
9427
|
+
constructor(sdk, chainId, poolAddress, adapterAddress) {
|
|
9226
9428
|
this.sdk = sdk;
|
|
9227
9429
|
this.chainId = chainId;
|
|
9228
9430
|
this.poolAddress = poolAddress;
|
|
9431
|
+
this.adapterAddress = adapterAddress;
|
|
9432
|
+
this.adapter = {
|
|
9433
|
+
address: adapterAddress
|
|
9434
|
+
};
|
|
9229
9435
|
}
|
|
9230
9436
|
/**
|
|
9231
|
-
* Create a new
|
|
9437
|
+
* Create a new Unlink instance.
|
|
9232
9438
|
*
|
|
9233
9439
|
* Handles all initialization internally:
|
|
9234
|
-
* - Resolves
|
|
9440
|
+
* - Resolves chain config (if using `chain` instead of explicit URLs)
|
|
9235
9441
|
* - Auto-detects storage (IndexedDB in browser) and rng (crypto.getRandomValues)
|
|
9236
9442
|
* - Runs schema migration via `initCore()`
|
|
9237
9443
|
* - Creates the internal SDK
|
|
9238
9444
|
*/
|
|
9239
9445
|
static async create(config) {
|
|
9446
|
+
let chainId;
|
|
9240
9447
|
let gatewayUrl;
|
|
9241
9448
|
let poolAddress;
|
|
9449
|
+
let adapterAddress;
|
|
9242
9450
|
let proverConfig = config.prover;
|
|
9243
|
-
if ("
|
|
9451
|
+
if ("chain" in config) {
|
|
9452
|
+
const chainConfig = await fetchChainConfig(config.chain);
|
|
9453
|
+
chainId = chainConfig.chainId;
|
|
9454
|
+
gatewayUrl = chainConfig.gatewayUrl;
|
|
9455
|
+
poolAddress = config.poolAddress ?? chainConfig.poolAddress;
|
|
9456
|
+
adapterAddress = config.adapterAddress ?? chainConfig.adapterAddress;
|
|
9457
|
+
proverConfig = {
|
|
9458
|
+
artifactSource: {
|
|
9459
|
+
baseUrl: config.prover?.artifactSource?.baseUrl ?? chainConfig.artifactBaseUrl,
|
|
9460
|
+
version: config.prover?.artifactSource?.version ?? chainConfig.artifactVersion,
|
|
9461
|
+
preferLocalFiles: config.prover?.artifactSource?.preferLocalFiles
|
|
9462
|
+
}
|
|
9463
|
+
};
|
|
9464
|
+
} else {
|
|
9465
|
+
chainId = config.chainId;
|
|
9244
9466
|
gatewayUrl = config.gatewayUrl;
|
|
9245
9467
|
poolAddress = config.poolAddress;
|
|
9468
|
+
adapterAddress = config.adapterAddress;
|
|
9246
9469
|
if (typeof window !== "undefined" && !config.prover?.artifactSource?.version) {
|
|
9247
9470
|
throw new InitializationError(
|
|
9248
|
-
"prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use
|
|
9471
|
+
"prover.artifactSource.version is required in browser when using explicit gatewayUrl mode. Use chain mode or provide a pinned artifact version."
|
|
9249
9472
|
);
|
|
9250
9473
|
}
|
|
9251
|
-
} else {
|
|
9252
|
-
const envConfig = await fetchEnvironmentConfig(config.environment);
|
|
9253
|
-
gatewayUrl = envConfig.gatewayUrl;
|
|
9254
|
-
poolAddress = config.poolAddress ?? envConfig.poolAddress;
|
|
9255
|
-
proverConfig = {
|
|
9256
|
-
artifactSource: {
|
|
9257
|
-
baseUrl: config.prover?.artifactSource?.baseUrl ?? envConfig.artifactBaseUrl,
|
|
9258
|
-
version: config.prover?.artifactSource?.version ?? envConfig.artifactVersion,
|
|
9259
|
-
preferLocalFiles: config.prover?.artifactSource?.preferLocalFiles
|
|
9260
|
-
}
|
|
9261
|
-
};
|
|
9262
9474
|
}
|
|
9263
9475
|
const storage = config.storage ?? detectStorage();
|
|
9264
9476
|
const rng = config.rng ?? defaultRng;
|
|
@@ -9267,14 +9479,14 @@ var UnlinkWallet = class _UnlinkWallet {
|
|
|
9267
9479
|
const sdk = createWalletSDK(
|
|
9268
9480
|
{ core, fetch: fetchImpl },
|
|
9269
9481
|
{
|
|
9270
|
-
chainId
|
|
9482
|
+
chainId,
|
|
9271
9483
|
gatewayUrl,
|
|
9272
9484
|
chainRpcUrl: config.chainRpcUrl,
|
|
9273
9485
|
prover: proverConfig,
|
|
9274
9486
|
autoSync: config.autoSync
|
|
9275
9487
|
}
|
|
9276
9488
|
);
|
|
9277
|
-
return new
|
|
9489
|
+
return new _Unlink(sdk, chainId, poolAddress, adapterAddress ?? "");
|
|
9278
9490
|
}
|
|
9279
9491
|
// ===== Seed Lifecycle =====
|
|
9280
9492
|
/** Seed management (create, import, export, delete mnemonic). */
|
|
@@ -9305,10 +9517,10 @@ var UnlinkWallet = class _UnlinkWallet {
|
|
|
9305
9517
|
return this.sdk.deposit.reconcile(relayId);
|
|
9306
9518
|
}
|
|
9307
9519
|
/**
|
|
9308
|
-
*
|
|
9520
|
+
* Send a private transfer (1 or more recipients).
|
|
9309
9521
|
* Handles note selection, circuit selection, and proof generation automatically.
|
|
9310
9522
|
*/
|
|
9311
|
-
async
|
|
9523
|
+
async send(params, overrides) {
|
|
9312
9524
|
return this.sdk.transfer.send(
|
|
9313
9525
|
{
|
|
9314
9526
|
chainId: this.chainId,
|
|
@@ -9319,9 +9531,9 @@ var UnlinkWallet = class _UnlinkWallet {
|
|
|
9319
9531
|
);
|
|
9320
9532
|
}
|
|
9321
9533
|
/**
|
|
9322
|
-
* Get a
|
|
9534
|
+
* Get a send plan without executing (for preview/confirmation UIs).
|
|
9323
9535
|
*/
|
|
9324
|
-
async
|
|
9536
|
+
async planSend(params, account) {
|
|
9325
9537
|
return this.sdk.transfer.plan(
|
|
9326
9538
|
{
|
|
9327
9539
|
chainId: this.chainId,
|
|
@@ -9331,8 +9543,8 @@ var UnlinkWallet = class _UnlinkWallet {
|
|
|
9331
9543
|
account
|
|
9332
9544
|
);
|
|
9333
9545
|
}
|
|
9334
|
-
/** Execute a pre-built
|
|
9335
|
-
async
|
|
9546
|
+
/** Execute a pre-built send plan. */
|
|
9547
|
+
async executeSend(plans, overrides) {
|
|
9336
9548
|
return this.sdk.transfer.execute(
|
|
9337
9549
|
plans,
|
|
9338
9550
|
{ chainId: this.chainId, poolAddress: this.poolAddress },
|
|
@@ -9481,31 +9693,31 @@ var UnlinkWallet = class _UnlinkWallet {
|
|
|
9481
9693
|
return this.sdk.burner.getBalance(address);
|
|
9482
9694
|
}
|
|
9483
9695
|
};
|
|
9484
|
-
// =====
|
|
9696
|
+
// ===== Interact (Private DeFi) =====
|
|
9485
9697
|
/**
|
|
9486
|
-
*
|
|
9487
|
-
*
|
|
9698
|
+
* Adapter contract address (resolved from config).
|
|
9699
|
+
* Use for building DeFi calls that reference the adapter.
|
|
9488
9700
|
*/
|
|
9489
|
-
adapter
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
}
|
|
9701
|
+
adapter;
|
|
9702
|
+
/**
|
|
9703
|
+
* Execute an atomic unshield -> DeFi call(s) -> reshield flow through an adapter.
|
|
9704
|
+
* chainId/poolAddress/adapterAddress are injected automatically.
|
|
9705
|
+
*/
|
|
9706
|
+
async interact(params, opts, overrides) {
|
|
9707
|
+
return this.sdk.adapter.execute(
|
|
9708
|
+
{
|
|
9709
|
+
chainId: this.chainId,
|
|
9710
|
+
poolAddress: this.poolAddress,
|
|
9711
|
+
adapterAddress: this.adapterAddress,
|
|
9712
|
+
spend: params.spend,
|
|
9713
|
+
calls: params.calls,
|
|
9714
|
+
receive: params.receive,
|
|
9715
|
+
deadline: params.deadline
|
|
9716
|
+
},
|
|
9717
|
+
opts,
|
|
9718
|
+
overrides
|
|
9719
|
+
);
|
|
9720
|
+
}
|
|
9509
9721
|
// ===== Advanced =====
|
|
9510
9722
|
/**
|
|
9511
9723
|
* Advanced escape hatch for raw JoinSplit transaction building.
|
|
@@ -9553,6 +9765,7 @@ var defaultRng = (n) => {
|
|
|
9553
9765
|
}
|
|
9554
9766
|
return globalThis.crypto.getRandomValues(new Uint8Array(n));
|
|
9555
9767
|
};
|
|
9768
|
+
var UnlinkWallet = Unlink;
|
|
9556
9769
|
|
|
9557
9770
|
// utils/amounts.ts
|
|
9558
9771
|
function parseAmount(value, decimals) {
|
|
@@ -9605,6 +9818,7 @@ export {
|
|
|
9605
9818
|
HttpError,
|
|
9606
9819
|
InitializationError,
|
|
9607
9820
|
ProofError,
|
|
9821
|
+
Unlink,
|
|
9608
9822
|
UnlinkWallet,
|
|
9609
9823
|
ValidationError,
|
|
9610
9824
|
computeBalances,
|