@reclaimprotocol/js-sdk 4.5.2 → 4.6.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/dist/index.d.ts +338 -0
- package/dist/index.js +536 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -72,7 +72,7 @@ var require_package = __commonJS({
|
|
|
72
72
|
"package.json"(exports2, module2) {
|
|
73
73
|
module2.exports = {
|
|
74
74
|
name: "@reclaimprotocol/js-sdk",
|
|
75
|
-
version: "4.
|
|
75
|
+
version: "4.6.0",
|
|
76
76
|
description: "Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.",
|
|
77
77
|
main: "dist/index.js",
|
|
78
78
|
types: "dist/index.d.ts",
|
|
@@ -262,7 +262,7 @@ var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
|
|
|
262
262
|
|
|
263
263
|
// src/Reclaim.ts
|
|
264
264
|
var import_ethers6 = require("ethers");
|
|
265
|
-
var
|
|
265
|
+
var import_canonicalize3 = __toESM(require("canonicalize"));
|
|
266
266
|
|
|
267
267
|
// src/utils/errors.ts
|
|
268
268
|
function createErrorClass(name) {
|
|
@@ -1757,6 +1757,114 @@ function clearDeviceCache() {
|
|
|
1757
1757
|
cachedMobileType = null;
|
|
1758
1758
|
}
|
|
1759
1759
|
|
|
1760
|
+
// src/utils/apis/feature.ts
|
|
1761
|
+
var fetchFeatureFlagsFromServer = (_0) => __async(null, [_0], function* ({
|
|
1762
|
+
featureFlagNames,
|
|
1763
|
+
publicKey,
|
|
1764
|
+
appId,
|
|
1765
|
+
providerId,
|
|
1766
|
+
sessionId
|
|
1767
|
+
}) {
|
|
1768
|
+
const queryParams = new URLSearchParams();
|
|
1769
|
+
if (publicKey) queryParams.append("publicKey", publicKey);
|
|
1770
|
+
featureFlagNames.forEach((name) => queryParams.append("featureFlagNames", name));
|
|
1771
|
+
if (appId) queryParams.append("appId", appId);
|
|
1772
|
+
if (providerId) queryParams.append("providerId", providerId);
|
|
1773
|
+
if (sessionId) queryParams.append("sessionId", sessionId);
|
|
1774
|
+
try {
|
|
1775
|
+
const response = yield fetch(
|
|
1776
|
+
`https://api.reclaimprotocol.org/api/feature-flags/get?${queryParams.toString()}`,
|
|
1777
|
+
{
|
|
1778
|
+
method: "GET",
|
|
1779
|
+
headers: {
|
|
1780
|
+
"Content-Type": "application/json"
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
);
|
|
1784
|
+
if (response.ok) {
|
|
1785
|
+
const responseData = yield response.json();
|
|
1786
|
+
const featureFlags = {};
|
|
1787
|
+
for (const flag of responseData) {
|
|
1788
|
+
const flagName = flag.name;
|
|
1789
|
+
const flagValue = flag.value;
|
|
1790
|
+
if (flag.type === "boolean") {
|
|
1791
|
+
featureFlags[flagName] = typeof flagValue === "boolean" ? flagValue : false;
|
|
1792
|
+
} else if (flag.type === "string") {
|
|
1793
|
+
featureFlags[flagName] = typeof flagValue === "string" ? flagValue : "";
|
|
1794
|
+
} else if (flag.type === "number") {
|
|
1795
|
+
featureFlags[flagName] = typeof flagValue === "number" ? flagValue : 0;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
return featureFlags;
|
|
1799
|
+
} else {
|
|
1800
|
+
throw new Error(`Failed to load feature flags: ${response.status}`);
|
|
1801
|
+
}
|
|
1802
|
+
} catch (e) {
|
|
1803
|
+
console.error("Error fetching feature flags:", e);
|
|
1804
|
+
return {};
|
|
1805
|
+
}
|
|
1806
|
+
});
|
|
1807
|
+
var CACHE_DURATION = 60 * 60 * 1e3;
|
|
1808
|
+
var InMemoryCache = class {
|
|
1809
|
+
constructor() {
|
|
1810
|
+
this.storage = {};
|
|
1811
|
+
}
|
|
1812
|
+
getItem(key) {
|
|
1813
|
+
return this.storage[key];
|
|
1814
|
+
}
|
|
1815
|
+
setItem(key, value) {
|
|
1816
|
+
this.storage[key] = value.toString();
|
|
1817
|
+
}
|
|
1818
|
+
removeItem(key) {
|
|
1819
|
+
delete this.storage[key];
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
var InternalCacheProvider = class {
|
|
1823
|
+
static provide() {
|
|
1824
|
+
if ("localStorage" in globalThis) {
|
|
1825
|
+
return globalThis.localStorage;
|
|
1826
|
+
}
|
|
1827
|
+
return this.inMemory;
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
InternalCacheProvider.inMemory = new InMemoryCache();
|
|
1831
|
+
var _Features = class _Features {
|
|
1832
|
+
constructor() {
|
|
1833
|
+
}
|
|
1834
|
+
};
|
|
1835
|
+
_Features.isNewLinkingEnabled = (config) => __async(null, null, function* () {
|
|
1836
|
+
try {
|
|
1837
|
+
const featureFlags = yield fetchFeatureFlagsFromServer({
|
|
1838
|
+
featureFlagNames: ["newLinkingAndroid"],
|
|
1839
|
+
appId: config == null ? void 0 : config.applicationId,
|
|
1840
|
+
providerId: config == null ? void 0 : config.providerId,
|
|
1841
|
+
sessionId: config == null ? void 0 : config.sessionId
|
|
1842
|
+
});
|
|
1843
|
+
return featureFlags.newLinkingAndroid === true;
|
|
1844
|
+
} catch (error) {
|
|
1845
|
+
console.error("Error checking feature flag:", error);
|
|
1846
|
+
return false;
|
|
1847
|
+
}
|
|
1848
|
+
});
|
|
1849
|
+
_Features.isFirstAttemptToLaunchAppClip = () => {
|
|
1850
|
+
const storage = InternalCacheProvider.provide();
|
|
1851
|
+
const d = /* @__PURE__ */ new Date();
|
|
1852
|
+
const key = `isFirstAttemptToLaunchAppClip:${d.toDateString()}`;
|
|
1853
|
+
const value = storage.getItem(key);
|
|
1854
|
+
storage.setItem(key, "true");
|
|
1855
|
+
return value == "true";
|
|
1856
|
+
};
|
|
1857
|
+
var Features = _Features;
|
|
1858
|
+
|
|
1859
|
+
// src/utils/strings.ts
|
|
1860
|
+
var import_canonicalize2 = __toESM(require("canonicalize"));
|
|
1861
|
+
function canonicalStringify(params) {
|
|
1862
|
+
if (!params) {
|
|
1863
|
+
return "";
|
|
1864
|
+
}
|
|
1865
|
+
return (0, import_canonicalize2.default)(params) || "";
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1760
1868
|
// src/Reclaim.ts
|
|
1761
1869
|
var logger7 = logger_default.logger;
|
|
1762
1870
|
var sdkVersion = require_package().version;
|
|
@@ -1789,7 +1897,7 @@ function verifyProof(proofOrProofs, allowAiWitness) {
|
|
|
1789
1897
|
}
|
|
1790
1898
|
const calculatedIdentifier = getIdentifierFromClaimInfo({
|
|
1791
1899
|
parameters: JSON.parse(
|
|
1792
|
-
(0,
|
|
1900
|
+
(0, import_canonicalize3.default)(proof.claimData.parameters)
|
|
1793
1901
|
),
|
|
1794
1902
|
provider: proof.claimData.provider,
|
|
1795
1903
|
context: proof.claimData.context
|
|
@@ -1848,15 +1956,41 @@ var emptyTemplateData = {
|
|
|
1848
1956
|
jsonProofResponse: false
|
|
1849
1957
|
};
|
|
1850
1958
|
var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
1851
|
-
// 30 seconds timeout, can be adjusted
|
|
1852
|
-
// Private constructor
|
|
1853
1959
|
constructor(applicationId, providerId, options) {
|
|
1854
1960
|
this.context = { contextAddress: "0x0", contextMessage: "sample context" };
|
|
1855
1961
|
this.claimCreationType = "createClaim" /* STANDALONE */;
|
|
1856
1962
|
this.intervals = /* @__PURE__ */ new Map();
|
|
1857
1963
|
this.jsonProofResponse = false;
|
|
1858
1964
|
this.extensionID = "reclaim-extension";
|
|
1859
|
-
this.FAILURE_TIMEOUT =
|
|
1965
|
+
this.FAILURE_TIMEOUT = 30 * 1e3;
|
|
1966
|
+
/**
|
|
1967
|
+
* Validates signature and returns template data
|
|
1968
|
+
* @returns
|
|
1969
|
+
*/
|
|
1970
|
+
this.getTemplateData = () => {
|
|
1971
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1972
|
+
if (!this.signature) {
|
|
1973
|
+
throw new SignatureNotFoundError("Signature is not set.");
|
|
1974
|
+
}
|
|
1975
|
+
validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
|
|
1976
|
+
const templateData = {
|
|
1977
|
+
sessionId: this.sessionId,
|
|
1978
|
+
providerId: this.providerId,
|
|
1979
|
+
applicationId: this.applicationId,
|
|
1980
|
+
signature: this.signature,
|
|
1981
|
+
timestamp: this.timeStamp,
|
|
1982
|
+
callbackUrl: this.getAppCallbackUrl(),
|
|
1983
|
+
context: canonicalStringify(this.context),
|
|
1984
|
+
providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
|
|
1985
|
+
resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
|
|
1986
|
+
parameters: this.parameters,
|
|
1987
|
+
redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
|
|
1988
|
+
acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
|
|
1989
|
+
sdkVersion: this.sdkVersion,
|
|
1990
|
+
jsonProofResponse: this.jsonProofResponse
|
|
1991
|
+
};
|
|
1992
|
+
return templateData;
|
|
1993
|
+
};
|
|
1860
1994
|
var _a;
|
|
1861
1995
|
this.providerId = providerId;
|
|
1862
1996
|
this.timeStamp = Date.now().toString();
|
|
@@ -1891,8 +2025,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1891
2025
|
this.options = options;
|
|
1892
2026
|
this.sdkVersion = "js-" + sdkVersion;
|
|
1893
2027
|
logger7.info(`Initializing client with applicationId: ${this.applicationId}`);
|
|
2028
|
+
this.isNewLinkingEnabledAsync = Features.isNewLinkingEnabled({
|
|
2029
|
+
applicationId,
|
|
2030
|
+
providerId,
|
|
2031
|
+
sessionId: this.sessionId
|
|
2032
|
+
});
|
|
1894
2033
|
}
|
|
1895
|
-
|
|
2034
|
+
/**
|
|
2035
|
+
* Initializes a new Reclaim proof request instance with automatic signature generation and session creation
|
|
2036
|
+
*
|
|
2037
|
+
* @param applicationId - Your Reclaim application ID
|
|
2038
|
+
* @param appSecret - Your application secret key for signing requests
|
|
2039
|
+
* @param providerId - The ID of the provider to use for proof generation
|
|
2040
|
+
* @param options - Optional configuration options for the proof request
|
|
2041
|
+
* @returns Promise<ReclaimProofRequest> - A fully initialized proof request instance
|
|
2042
|
+
* @throws {InitError} When initialization fails due to invalid parameters or session creation errors
|
|
2043
|
+
*
|
|
2044
|
+
* @example
|
|
2045
|
+
* ```typescript
|
|
2046
|
+
* const proofRequest = await ReclaimProofRequest.init(
|
|
2047
|
+
* 'your-app-id',
|
|
2048
|
+
* 'your-app-secret',
|
|
2049
|
+
* 'provider-id',
|
|
2050
|
+
* { log: true, acceptAiProviders: true }
|
|
2051
|
+
* );
|
|
2052
|
+
* ```
|
|
2053
|
+
*/
|
|
1896
2054
|
static init(applicationId, appSecret, providerId, options) {
|
|
1897
2055
|
return __async(this, null, function* () {
|
|
1898
2056
|
try {
|
|
@@ -1966,6 +2124,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1966
2124
|
}
|
|
1967
2125
|
});
|
|
1968
2126
|
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Creates a ReclaimProofRequest instance from a JSON string representation
|
|
2129
|
+
*
|
|
2130
|
+
* This method deserializes a previously exported proof request (via toJsonString) and reconstructs
|
|
2131
|
+
* the instance with all its properties. Useful for recreating requests on the frontend or across different contexts.
|
|
2132
|
+
*
|
|
2133
|
+
* @param jsonString - JSON string containing the serialized proof request data
|
|
2134
|
+
* @returns {Promise<ReclaimProofRequest>} - Reconstructed proof request instance
|
|
2135
|
+
* @throws {InvalidParamError} When JSON string is invalid or contains invalid parameters
|
|
2136
|
+
*
|
|
2137
|
+
* @example
|
|
2138
|
+
* ```typescript
|
|
2139
|
+
* const jsonString = proofRequest.toJsonString();
|
|
2140
|
+
* const reconstructed = await ReclaimProofRequest.fromJsonString(jsonString);
|
|
2141
|
+
* // Can also be used with InApp SDK's startVerificationFromJson method
|
|
2142
|
+
* ```
|
|
2143
|
+
*/
|
|
1969
2144
|
static fromJsonString(jsonString) {
|
|
1970
2145
|
return __async(this, null, function* () {
|
|
1971
2146
|
try {
|
|
@@ -2047,19 +2222,75 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2047
2222
|
}
|
|
2048
2223
|
});
|
|
2049
2224
|
}
|
|
2050
|
-
|
|
2225
|
+
/**
|
|
2226
|
+
* Sets a custom callback URL where proofs will be submitted via HTTP POST
|
|
2227
|
+
*
|
|
2228
|
+
* By default, proofs are posted as `application/x-www-form-urlencoded`.
|
|
2229
|
+
* When a custom callback URL is set, Reclaim will no longer receive proofs upon submission,
|
|
2230
|
+
* and listeners on the startSession method will not be triggered. Your application must
|
|
2231
|
+
* coordinate with your backend to receive and verify proofs using verifyProof().
|
|
2232
|
+
*
|
|
2233
|
+
* Note: InApp SDKs are unaffected by this property as they do not handle proof submission.
|
|
2234
|
+
*
|
|
2235
|
+
* @param url - The URL where proofs should be submitted via HTTP POST
|
|
2236
|
+
* @param jsonProofResponse - Optional. Set to true to submit proofs as `application/json`. Defaults to false
|
|
2237
|
+
* @throws {InvalidParamError} When URL is invalid
|
|
2238
|
+
*
|
|
2239
|
+
* @example
|
|
2240
|
+
* ```typescript
|
|
2241
|
+
* proofRequest.setAppCallbackUrl('https://your-backend.com/callback');
|
|
2242
|
+
* // Or with JSON format
|
|
2243
|
+
* proofRequest.setAppCallbackUrl('https://your-backend.com/callback', true);
|
|
2244
|
+
* ```
|
|
2245
|
+
*/
|
|
2051
2246
|
setAppCallbackUrl(url, jsonProofResponse) {
|
|
2052
2247
|
validateURL(url, "setAppCallbackUrl");
|
|
2053
2248
|
this.appCallbackUrl = url;
|
|
2054
2249
|
this.jsonProofResponse = jsonProofResponse != null ? jsonProofResponse : false;
|
|
2055
2250
|
}
|
|
2251
|
+
/**
|
|
2252
|
+
* Sets a redirect URL where users will be redirected after successfully acquiring and submitting proof
|
|
2253
|
+
*
|
|
2254
|
+
* @param url - The URL where users should be redirected after successful proof generation
|
|
2255
|
+
* @throws {InvalidParamError} When URL is invalid
|
|
2256
|
+
*
|
|
2257
|
+
* @example
|
|
2258
|
+
* ```typescript
|
|
2259
|
+
* proofRequest.setRedirectUrl('https://your-app.com/success');
|
|
2260
|
+
* ```
|
|
2261
|
+
*/
|
|
2056
2262
|
setRedirectUrl(url) {
|
|
2057
2263
|
validateURL(url, "setRedirectUrl");
|
|
2058
2264
|
this.redirectUrl = url;
|
|
2059
2265
|
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Sets the claim creation type for the proof request
|
|
2268
|
+
*
|
|
2269
|
+
* @param claimCreationType - The type of claim creation (e.g., STANDALONE)
|
|
2270
|
+
*
|
|
2271
|
+
* @example
|
|
2272
|
+
* ```typescript
|
|
2273
|
+
* proofRequest.setClaimCreationType(ClaimCreationType.STANDALONE);
|
|
2274
|
+
* ```
|
|
2275
|
+
*/
|
|
2060
2276
|
setClaimCreationType(claimCreationType) {
|
|
2061
2277
|
this.claimCreationType = claimCreationType;
|
|
2062
2278
|
}
|
|
2279
|
+
/**
|
|
2280
|
+
* Sets custom options for the QR code modal display
|
|
2281
|
+
*
|
|
2282
|
+
* @param options - Modal configuration options including title, description, theme, etc.
|
|
2283
|
+
* @throws {SetParamsError} When modal options are invalid
|
|
2284
|
+
*
|
|
2285
|
+
* @example
|
|
2286
|
+
* ```typescript
|
|
2287
|
+
* proofRequest.setModalOptions({
|
|
2288
|
+
* title: 'Scan QR Code',
|
|
2289
|
+
* description: 'Scan with your mobile device',
|
|
2290
|
+
* darkTheme: true
|
|
2291
|
+
* });
|
|
2292
|
+
* ```
|
|
2293
|
+
*/
|
|
2063
2294
|
setModalOptions(options) {
|
|
2064
2295
|
try {
|
|
2065
2296
|
validateModalOptions(options, "setModalOptions");
|
|
@@ -2070,6 +2301,48 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2070
2301
|
throw new SetParamsError("Error setting modal options", error);
|
|
2071
2302
|
}
|
|
2072
2303
|
}
|
|
2304
|
+
/**
|
|
2305
|
+
* Sets additional context data to be stored with the claim
|
|
2306
|
+
*
|
|
2307
|
+
* This allows you to associate custom data (address and message) with the proof claim.
|
|
2308
|
+
* The context can be retrieved and validated when verifying the proof.
|
|
2309
|
+
*
|
|
2310
|
+
* Also see [setContext] which is an alternate way to set context that has an address & message.
|
|
2311
|
+
*
|
|
2312
|
+
* @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.
|
|
2313
|
+
* @throws {SetContextError} When context parameters are invalid
|
|
2314
|
+
*
|
|
2315
|
+
* @example
|
|
2316
|
+
* ```typescript
|
|
2317
|
+
* proofRequest.setJsonContext({foo: 'bar'});
|
|
2318
|
+
* ```
|
|
2319
|
+
*/
|
|
2320
|
+
setJsonContext(context) {
|
|
2321
|
+
try {
|
|
2322
|
+
validateFunctionParams([
|
|
2323
|
+
{ input: context, paramName: "context", isString: false }
|
|
2324
|
+
], "setJsonContext");
|
|
2325
|
+
this.context = JSON.parse(canonicalStringify(context));
|
|
2326
|
+
} catch (error) {
|
|
2327
|
+
logger7.info("Error setting context", error);
|
|
2328
|
+
throw new SetContextError("Error setting context", error);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Sets additional context data to be stored with the claim
|
|
2333
|
+
*
|
|
2334
|
+
* This allows you to associate custom data (address and message) with the proof claim.
|
|
2335
|
+
* The context can be retrieved and validated when verifying the proof.
|
|
2336
|
+
*
|
|
2337
|
+
* @param address - Context address identifier
|
|
2338
|
+
* @param message - Additional data to associate with the address
|
|
2339
|
+
* @throws {SetContextError} When context parameters are invalid
|
|
2340
|
+
*
|
|
2341
|
+
* @example
|
|
2342
|
+
* ```typescript
|
|
2343
|
+
* proofRequest.setContext('0x1234...', 'User verification for premium access');
|
|
2344
|
+
* ```
|
|
2345
|
+
*/
|
|
2073
2346
|
setContext(address, message) {
|
|
2074
2347
|
try {
|
|
2075
2348
|
validateFunctionParams([
|
|
@@ -2082,10 +2355,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2082
2355
|
throw new SetContextError("Error setting context", error);
|
|
2083
2356
|
}
|
|
2084
2357
|
}
|
|
2085
|
-
|
|
2358
|
+
/**
|
|
2359
|
+
* @deprecated use setContext instead
|
|
2360
|
+
*
|
|
2361
|
+
* @param address
|
|
2362
|
+
* @param message additional data you want associated with the [address]
|
|
2363
|
+
*/
|
|
2086
2364
|
addContext(address, message) {
|
|
2087
2365
|
this.setContext(address, message);
|
|
2088
2366
|
}
|
|
2367
|
+
/**
|
|
2368
|
+
* Sets provider-specific parameters for the proof request
|
|
2369
|
+
*
|
|
2370
|
+
* These parameters are passed to the provider and may include configuration options,
|
|
2371
|
+
* filters, or other provider-specific settings required for proof generation.
|
|
2372
|
+
*
|
|
2373
|
+
* @param params - Key-value pairs of parameters to set
|
|
2374
|
+
* @throws {SetParamsError} When parameters are invalid
|
|
2375
|
+
*
|
|
2376
|
+
* @example
|
|
2377
|
+
* ```typescript
|
|
2378
|
+
* proofRequest.setParams({
|
|
2379
|
+
* minFollowers: '1000',
|
|
2380
|
+
* platform: 'twitter'
|
|
2381
|
+
* });
|
|
2382
|
+
* ```
|
|
2383
|
+
*/
|
|
2089
2384
|
setParams(params) {
|
|
2090
2385
|
try {
|
|
2091
2386
|
validateParameters(params);
|
|
@@ -2095,7 +2390,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2095
2390
|
throw new SetParamsError("Error setting params", error);
|
|
2096
2391
|
}
|
|
2097
2392
|
}
|
|
2098
|
-
|
|
2393
|
+
/**
|
|
2394
|
+
* Returns the currently configured app callback URL
|
|
2395
|
+
*
|
|
2396
|
+
* If no custom callback URL was set via setAppCallbackUrl(), this returns the default
|
|
2397
|
+
* Reclaim service callback URL with the current session ID.
|
|
2398
|
+
*
|
|
2399
|
+
* @returns The callback URL where proofs will be submitted
|
|
2400
|
+
* @throws {GetAppCallbackUrlError} When unable to retrieve the callback URL
|
|
2401
|
+
*
|
|
2402
|
+
* @example
|
|
2403
|
+
* ```typescript
|
|
2404
|
+
* const callbackUrl = proofRequest.getAppCallbackUrl();
|
|
2405
|
+
* console.log('Proofs will be sent to:', callbackUrl);
|
|
2406
|
+
* ```
|
|
2407
|
+
*/
|
|
2099
2408
|
getAppCallbackUrl() {
|
|
2100
2409
|
try {
|
|
2101
2410
|
validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
|
|
@@ -2105,6 +2414,20 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2105
2414
|
throw new GetAppCallbackUrlError("Error getting app callback url", error);
|
|
2106
2415
|
}
|
|
2107
2416
|
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Returns the status URL for monitoring the current session
|
|
2419
|
+
*
|
|
2420
|
+
* This URL can be used to check the status of the proof request session.
|
|
2421
|
+
*
|
|
2422
|
+
* @returns The status monitoring URL for the current session
|
|
2423
|
+
* @throws {GetStatusUrlError} When unable to retrieve the status URL
|
|
2424
|
+
*
|
|
2425
|
+
* @example
|
|
2426
|
+
* ```typescript
|
|
2427
|
+
* const statusUrl = proofRequest.getStatusUrl();
|
|
2428
|
+
* // Use this URL to poll for session status updates
|
|
2429
|
+
* ```
|
|
2430
|
+
*/
|
|
2108
2431
|
getStatusUrl() {
|
|
2109
2432
|
try {
|
|
2110
2433
|
validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
|
|
@@ -2114,7 +2437,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2114
2437
|
throw new GetStatusUrlError("Error fetching status url", error);
|
|
2115
2438
|
}
|
|
2116
2439
|
}
|
|
2117
|
-
|
|
2440
|
+
/**
|
|
2441
|
+
* Returns the session ID associated with this proof request
|
|
2442
|
+
*
|
|
2443
|
+
* The session ID is automatically generated during initialization and uniquely
|
|
2444
|
+
* identifies this proof request session.
|
|
2445
|
+
*
|
|
2446
|
+
* @returns The session ID string
|
|
2447
|
+
* @throws {SessionNotStartedError} When session ID is not set
|
|
2448
|
+
*
|
|
2449
|
+
* @example
|
|
2450
|
+
* ```typescript
|
|
2451
|
+
* const sessionId = proofRequest.getSessionId();
|
|
2452
|
+
* console.log('Session ID:', sessionId);
|
|
2453
|
+
* ```
|
|
2454
|
+
*/
|
|
2118
2455
|
getSessionId() {
|
|
2119
2456
|
if (!this.sessionId) {
|
|
2120
2457
|
throw new SessionNotStartedError("SessionId is not set");
|
|
@@ -2136,7 +2473,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2136
2473
|
return __async(this, null, function* () {
|
|
2137
2474
|
try {
|
|
2138
2475
|
const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
|
|
2139
|
-
const canonicalData = (0,
|
|
2476
|
+
const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
|
|
2140
2477
|
if (!canonicalData) {
|
|
2141
2478
|
throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
|
|
2142
2479
|
}
|
|
@@ -2161,7 +2498,22 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2161
2498
|
}
|
|
2162
2499
|
return `${baseUrl}/?template=${template}`;
|
|
2163
2500
|
}
|
|
2164
|
-
|
|
2501
|
+
/**
|
|
2502
|
+
* Exports the Reclaim proof verification request as a JSON string
|
|
2503
|
+
*
|
|
2504
|
+
* This serialized format can be sent to the frontend to recreate this request using
|
|
2505
|
+
* ReclaimProofRequest.fromJsonString() or any InApp SDK's startVerificationFromJson()
|
|
2506
|
+
* method to initiate the verification journey.
|
|
2507
|
+
*
|
|
2508
|
+
* @returns JSON string representation of the proof request
|
|
2509
|
+
*
|
|
2510
|
+
* @example
|
|
2511
|
+
* ```typescript
|
|
2512
|
+
* const jsonString = proofRequest.toJsonString();
|
|
2513
|
+
* // Send to frontend or store for later use
|
|
2514
|
+
* // Can be reconstructed with: ReclaimProofRequest.fromJsonString(jsonString)
|
|
2515
|
+
* ```
|
|
2516
|
+
*/
|
|
2165
2517
|
toJsonString() {
|
|
2166
2518
|
var _a;
|
|
2167
2519
|
return JSON.stringify({
|
|
@@ -2190,40 +2542,45 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2190
2542
|
} : void 0
|
|
2191
2543
|
});
|
|
2192
2544
|
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Generates and returns the request URL for proof verification
|
|
2547
|
+
*
|
|
2548
|
+
* This URL can be shared with users to initiate the proof generation process.
|
|
2549
|
+
* The URL format varies based on device type:
|
|
2550
|
+
* - Mobile iOS: Returns App Clip URL (if useAppClip is enabled)
|
|
2551
|
+
* - Mobile Android: Returns Instant App URL (if useAppClip is enabled)
|
|
2552
|
+
* - Desktop/Other: Returns standard verification URL
|
|
2553
|
+
*
|
|
2554
|
+
* @returns Promise<string> - The generated request URL
|
|
2555
|
+
* @throws {SignatureNotFoundError} When signature is not set
|
|
2556
|
+
*
|
|
2557
|
+
* @example
|
|
2558
|
+
* ```typescript
|
|
2559
|
+
* const requestUrl = await proofRequest.getRequestUrl();
|
|
2560
|
+
* // Share this URL with users or display as QR code
|
|
2561
|
+
* ```
|
|
2562
|
+
*/
|
|
2193
2563
|
getRequestUrl() {
|
|
2194
2564
|
return __async(this, null, function* () {
|
|
2195
|
-
var _a
|
|
2565
|
+
var _a;
|
|
2196
2566
|
logger7.info("Creating Request Url");
|
|
2197
2567
|
if (!this.signature) {
|
|
2198
2568
|
throw new SignatureNotFoundError("Signature is not set.");
|
|
2199
2569
|
}
|
|
2200
2570
|
try {
|
|
2201
|
-
|
|
2202
|
-
const templateData = {
|
|
2203
|
-
sessionId: this.sessionId,
|
|
2204
|
-
providerId: this.providerId,
|
|
2205
|
-
providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
|
|
2206
|
-
resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
|
|
2207
|
-
applicationId: this.applicationId,
|
|
2208
|
-
signature: this.signature,
|
|
2209
|
-
timestamp: this.timeStamp,
|
|
2210
|
-
callbackUrl: this.getAppCallbackUrl(),
|
|
2211
|
-
context: JSON.stringify(this.context),
|
|
2212
|
-
parameters: this.parameters,
|
|
2213
|
-
redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
|
|
2214
|
-
acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
|
|
2215
|
-
sdkVersion: this.sdkVersion,
|
|
2216
|
-
jsonProofResponse: this.jsonProofResponse
|
|
2217
|
-
};
|
|
2571
|
+
const templateData = this.getTemplateData();
|
|
2218
2572
|
yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
|
|
2219
2573
|
const deviceType = getDeviceType();
|
|
2220
|
-
if (((
|
|
2574
|
+
if (((_a = this.options) == null ? void 0 : _a.useAppClip) && deviceType === "mobile" /* MOBILE */) {
|
|
2221
2575
|
let template = encodeURIComponent(JSON.stringify(templateData));
|
|
2222
2576
|
template = replaceAll(template, "(", "%28");
|
|
2223
2577
|
template = replaceAll(template, ")", "%29");
|
|
2224
2578
|
const isIos = getMobileDeviceType() === "ios" /* IOS */;
|
|
2225
2579
|
if (!isIos) {
|
|
2226
|
-
|
|
2580
|
+
let instantAppUrl = this.buildSharePageUrl(template);
|
|
2581
|
+
if (yield this.isNewLinkingEnabledAsync) {
|
|
2582
|
+
instantAppUrl = instantAppUrl.replace("/verifier", "/link");
|
|
2583
|
+
}
|
|
2227
2584
|
logger7.info("Instant App Url created successfully: " + instantAppUrl);
|
|
2228
2585
|
return instantAppUrl;
|
|
2229
2586
|
} else {
|
|
@@ -2242,37 +2599,39 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2242
2599
|
}
|
|
2243
2600
|
});
|
|
2244
2601
|
}
|
|
2602
|
+
/**
|
|
2603
|
+
* Triggers the appropriate Reclaim verification flow based on device type and configuration
|
|
2604
|
+
*
|
|
2605
|
+
* This method automatically detects the device type and initiates the optimal verification flow:
|
|
2606
|
+
* - Desktop with browser extension: Triggers extension flow
|
|
2607
|
+
* - Desktop without extension: Shows QR code modal
|
|
2608
|
+
* - Mobile Android: Redirects to Instant App
|
|
2609
|
+
* - Mobile iOS: Redirects to App Clip
|
|
2610
|
+
*
|
|
2611
|
+
* @returns Promise<void>
|
|
2612
|
+
* @throws {SignatureNotFoundError} When signature is not set
|
|
2613
|
+
*
|
|
2614
|
+
* @example
|
|
2615
|
+
* ```typescript
|
|
2616
|
+
* await proofRequest.triggerReclaimFlow();
|
|
2617
|
+
* // The appropriate verification method will be triggered automatically
|
|
2618
|
+
* ```
|
|
2619
|
+
*/
|
|
2245
2620
|
triggerReclaimFlow() {
|
|
2246
2621
|
return __async(this, null, function* () {
|
|
2247
|
-
var _a
|
|
2622
|
+
var _a;
|
|
2248
2623
|
if (!this.signature) {
|
|
2249
2624
|
throw new SignatureNotFoundError("Signature is not set.");
|
|
2250
2625
|
}
|
|
2251
2626
|
try {
|
|
2252
|
-
|
|
2253
|
-
const templateData = {
|
|
2254
|
-
sessionId: this.sessionId,
|
|
2255
|
-
providerId: this.providerId,
|
|
2256
|
-
applicationId: this.applicationId,
|
|
2257
|
-
signature: this.signature,
|
|
2258
|
-
timestamp: this.timeStamp,
|
|
2259
|
-
callbackUrl: this.getAppCallbackUrl(),
|
|
2260
|
-
context: JSON.stringify(this.context),
|
|
2261
|
-
providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
|
|
2262
|
-
resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
|
|
2263
|
-
parameters: this.parameters,
|
|
2264
|
-
redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
|
|
2265
|
-
acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
|
|
2266
|
-
sdkVersion: this.sdkVersion,
|
|
2267
|
-
jsonProofResponse: this.jsonProofResponse
|
|
2268
|
-
};
|
|
2627
|
+
const templateData = this.getTemplateData();
|
|
2269
2628
|
this.templateData = templateData;
|
|
2270
2629
|
logger7.info("Triggering Reclaim flow");
|
|
2271
2630
|
const deviceType = getDeviceType();
|
|
2272
|
-
|
|
2631
|
+
updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
|
|
2273
2632
|
if (deviceType === "desktop" /* DESKTOP */) {
|
|
2274
2633
|
const extensionAvailable = yield this.isBrowserExtensionAvailable();
|
|
2275
|
-
if (((
|
|
2634
|
+
if (((_a = this.options) == null ? void 0 : _a.useBrowserExtension) && extensionAvailable) {
|
|
2276
2635
|
logger7.info("Triggering browser extension flow");
|
|
2277
2636
|
this.triggerBrowserExtensionFlow();
|
|
2278
2637
|
return;
|
|
@@ -2287,7 +2646,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2287
2646
|
yield this.redirectToInstantApp();
|
|
2288
2647
|
} else if (mobileDeviceType === "ios" /* IOS */) {
|
|
2289
2648
|
logger7.info("Redirecting to iOS app clip");
|
|
2290
|
-
|
|
2649
|
+
this.redirectToAppClip();
|
|
2291
2650
|
}
|
|
2292
2651
|
}
|
|
2293
2652
|
} catch (error) {
|
|
@@ -2296,6 +2655,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2296
2655
|
}
|
|
2297
2656
|
});
|
|
2298
2657
|
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Checks if the Reclaim browser extension is installed and available
|
|
2660
|
+
*
|
|
2661
|
+
* This method attempts to communicate with the browser extension to verify its availability.
|
|
2662
|
+
* It uses a timeout mechanism to quickly determine if the extension responds.
|
|
2663
|
+
*
|
|
2664
|
+
* @param timeout - Timeout in milliseconds to wait for extension response. Defaults to 200ms
|
|
2665
|
+
* @returns Promise<boolean> - True if extension is available, false otherwise
|
|
2666
|
+
*
|
|
2667
|
+
* @example
|
|
2668
|
+
* ```typescript
|
|
2669
|
+
* const hasExtension = await proofRequest.isBrowserExtensionAvailable();
|
|
2670
|
+
* if (hasExtension) {
|
|
2671
|
+
* console.log('Browser extension is installed');
|
|
2672
|
+
* }
|
|
2673
|
+
* ```
|
|
2674
|
+
*/
|
|
2299
2675
|
isBrowserExtensionAvailable(timeout = 200) {
|
|
2300
2676
|
return __async(this, null, function* () {
|
|
2301
2677
|
try {
|
|
@@ -2355,8 +2731,54 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2355
2731
|
let template = encodeURIComponent(JSON.stringify(this.templateData));
|
|
2356
2732
|
template = replaceAll(template, "(", "%28");
|
|
2357
2733
|
template = replaceAll(template, ")", "%29");
|
|
2358
|
-
|
|
2734
|
+
let instantAppUrl = this.buildSharePageUrl(template);
|
|
2359
2735
|
logger7.info("Redirecting to Android instant app: " + instantAppUrl);
|
|
2736
|
+
if (yield this.isNewLinkingEnabledAsync) {
|
|
2737
|
+
instantAppUrl = instantAppUrl.replace("/verifier", "/link");
|
|
2738
|
+
const deepLink = `intent://details?id=org.reclaimprotocol.app&url=${encodeURIComponent(
|
|
2739
|
+
instantAppUrl
|
|
2740
|
+
)}&template=${template}#Intent;scheme=market;action=android.intent.action.VIEW;package=com.android.vending;end;`;
|
|
2741
|
+
try {
|
|
2742
|
+
const requestUrl = instantAppUrl;
|
|
2743
|
+
let appInstalled = false;
|
|
2744
|
+
let timeoutId;
|
|
2745
|
+
const iframe = document.createElement("iframe");
|
|
2746
|
+
iframe.style.display = "none";
|
|
2747
|
+
iframe.style.width = "1px";
|
|
2748
|
+
iframe.style.height = "1px";
|
|
2749
|
+
document.body.appendChild(iframe);
|
|
2750
|
+
const cleanup = () => {
|
|
2751
|
+
if (iframe.parentNode) {
|
|
2752
|
+
document.body.removeChild(iframe);
|
|
2753
|
+
}
|
|
2754
|
+
if (timeoutId) {
|
|
2755
|
+
clearTimeout(timeoutId);
|
|
2756
|
+
}
|
|
2757
|
+
};
|
|
2758
|
+
const onVisibilityChange = () => {
|
|
2759
|
+
if (document.hidden) {
|
|
2760
|
+
appInstalled = true;
|
|
2761
|
+
cleanup();
|
|
2762
|
+
window.location.href = deepLink;
|
|
2763
|
+
}
|
|
2764
|
+
};
|
|
2765
|
+
document.addEventListener("visibilitychange", onVisibilityChange, { once: true });
|
|
2766
|
+
iframe.src = deepLink.replace("intent:", "reclaimverifier:");
|
|
2767
|
+
timeoutId = setTimeout(() => {
|
|
2768
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
2769
|
+
cleanup();
|
|
2770
|
+
if (!appInstalled) {
|
|
2771
|
+
window.navigator.clipboard.writeText(requestUrl).catch(() => {
|
|
2772
|
+
console.error("We can't access the clipboard. Please copy this link and open Reclaim Verifier app.");
|
|
2773
|
+
});
|
|
2774
|
+
window.location.href = deepLink;
|
|
2775
|
+
}
|
|
2776
|
+
}, 1500);
|
|
2777
|
+
} catch (e) {
|
|
2778
|
+
window.location.href = instantAppUrl;
|
|
2779
|
+
}
|
|
2780
|
+
return;
|
|
2781
|
+
}
|
|
2360
2782
|
window.location.href = instantAppUrl;
|
|
2361
2783
|
} catch (error) {
|
|
2362
2784
|
logger7.info("Error redirecting to instant app:", error);
|
|
@@ -2365,20 +2787,53 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2365
2787
|
});
|
|
2366
2788
|
}
|
|
2367
2789
|
redirectToAppClip() {
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2790
|
+
try {
|
|
2791
|
+
let template = encodeURIComponent(JSON.stringify(this.templateData));
|
|
2792
|
+
template = replaceAll(template, "(", "%28");
|
|
2793
|
+
template = replaceAll(template, ")", "%29");
|
|
2794
|
+
const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
|
|
2795
|
+
logger7.info("Redirecting to iOS app clip: " + appClipUrl);
|
|
2796
|
+
window.location.href = appClipUrl;
|
|
2797
|
+
if (Features.isFirstAttemptToLaunchAppClip()) {
|
|
2798
|
+
setTimeout(() => {
|
|
2799
|
+
window.location.href = appClipUrl;
|
|
2800
|
+
}, 2e3);
|
|
2379
2801
|
}
|
|
2380
|
-
})
|
|
2802
|
+
} catch (error) {
|
|
2803
|
+
logger7.info("Error redirecting to app clip:", error);
|
|
2804
|
+
throw error;
|
|
2805
|
+
}
|
|
2381
2806
|
}
|
|
2807
|
+
/**
|
|
2808
|
+
* Starts the proof request session and monitors for proof submission
|
|
2809
|
+
*
|
|
2810
|
+
* This method begins polling the session status to detect when
|
|
2811
|
+
* a proof has been generated and submitted. It handles both default Reclaim callbacks
|
|
2812
|
+
* and custom callback URLs.
|
|
2813
|
+
*
|
|
2814
|
+
* For default callbacks: Verifies proofs automatically and passes them to onSuccess
|
|
2815
|
+
* For custom callbacks: Monitors submission status and notifies via onSuccess when complete
|
|
2816
|
+
*
|
|
2817
|
+
* @param onSuccess - Callback function invoked when proof is successfully submitted
|
|
2818
|
+
* @param onError - Callback function invoked when an error occurs during the session
|
|
2819
|
+
* @returns Promise<void>
|
|
2820
|
+
* @throws {SessionNotStartedError} When session ID is not defined
|
|
2821
|
+
* @throws {ProofNotVerifiedError} When proof verification fails (default callback only)
|
|
2822
|
+
* @throws {ProofSubmissionFailedError} When proof submission fails (custom callback only)
|
|
2823
|
+
* @throws {ProviderFailedError} When proof generation fails with timeout
|
|
2824
|
+
*
|
|
2825
|
+
* @example
|
|
2826
|
+
* ```typescript
|
|
2827
|
+
* await proofRequest.startSession({
|
|
2828
|
+
* onSuccess: (proof) => {
|
|
2829
|
+
* console.log('Proof received:', proof);
|
|
2830
|
+
* },
|
|
2831
|
+
* onError: (error) => {
|
|
2832
|
+
* console.error('Error:', error);
|
|
2833
|
+
* }
|
|
2834
|
+
* });
|
|
2835
|
+
* ```
|
|
2836
|
+
*/
|
|
2382
2837
|
startSession(_0) {
|
|
2383
2838
|
return __async(this, arguments, function* ({ onSuccess, onError }) {
|
|
2384
2839
|
if (!this.sessionId) {
|
|
@@ -2387,6 +2842,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2387
2842
|
throw new SessionNotStartedError(message);
|
|
2388
2843
|
}
|
|
2389
2844
|
logger7.info("Starting session");
|
|
2845
|
+
const sessionUpdatePollingInterval = 3 * 1e3;
|
|
2390
2846
|
const interval = setInterval(() => __async(this, null, function* () {
|
|
2391
2847
|
var _a, _b, _c;
|
|
2392
2848
|
try {
|
|
@@ -2442,11 +2898,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2442
2898
|
this.clearInterval();
|
|
2443
2899
|
(_c = this.modal) == null ? void 0 : _c.close();
|
|
2444
2900
|
}
|
|
2445
|
-
}),
|
|
2901
|
+
}), sessionUpdatePollingInterval);
|
|
2446
2902
|
this.intervals.set(this.sessionId, interval);
|
|
2447
2903
|
scheduleIntervalEndingTask(this.sessionId, this.intervals, onError);
|
|
2448
2904
|
});
|
|
2449
2905
|
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Closes the QR code modal if it is currently open
|
|
2908
|
+
*
|
|
2909
|
+
* This method can be called to programmatically close the modal, for example,
|
|
2910
|
+
* when implementing custom UI behavior or cleanup logic.
|
|
2911
|
+
*
|
|
2912
|
+
* @example
|
|
2913
|
+
* ```typescript
|
|
2914
|
+
* // Close modal after some condition
|
|
2915
|
+
* proofRequest.closeModal();
|
|
2916
|
+
* ```
|
|
2917
|
+
*/
|
|
2450
2918
|
closeModal() {
|
|
2451
2919
|
if (this.modal) {
|
|
2452
2920
|
this.modal.close();
|