@entros/pulse-sdk 3.1.0 → 3.3.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 -1
- package/dist/index.d.mts +182 -18
- package/dist/index.d.ts +182 -18
- package/dist/index.js +641 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +628 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
DEFAULT_CAPTURE_MS: () => DEFAULT_CAPTURE_MS,
|
|
34
34
|
DEFAULT_MIN_DISTANCE: () => DEFAULT_MIN_DISTANCE,
|
|
35
35
|
DEFAULT_THRESHOLD: () => DEFAULT_THRESHOLD,
|
|
36
|
+
ENCRYPTED_BASELINE_BLOB_BYTES: () => ENCRYPTED_BASELINE_BLOB_BYTES,
|
|
36
37
|
FINGERPRINT_BITS: () => FINGERPRINT_BITS,
|
|
37
38
|
MAX_CAPTURE_MS: () => MAX_CAPTURE_MS,
|
|
38
39
|
MIN_AUDIO_SAMPLES: () => MIN_AUDIO_SAMPLES,
|
|
@@ -44,14 +45,19 @@ __export(index_exports, {
|
|
|
44
45
|
PulseSDK: () => PulseSDK,
|
|
45
46
|
PulseSession: () => PulseSession,
|
|
46
47
|
SPEAKER_FEATURE_COUNT: () => SPEAKER_FEATURE_COUNT,
|
|
48
|
+
StaleEncryptedBaselineError: () => StaleEncryptedBaselineError,
|
|
47
49
|
TOUCH_FEATURE_COUNT: () => TOUCH_FEATURE_COUNT,
|
|
48
50
|
attestAgentOperator: () => attestAgentOperator,
|
|
49
|
-
autocorrelation: () => autocorrelation,
|
|
50
51
|
bigintToBytes32: () => bigintToBytes32,
|
|
52
|
+
bytes32ToBigint: () => bytes32ToBigint,
|
|
53
|
+
bytesToFingerprint: () => bytesToFingerprint,
|
|
54
|
+
clearBaselineKeyCache: () => clearBaselineKeyCache,
|
|
51
55
|
computeCommitment: () => computeCommitment,
|
|
52
|
-
|
|
56
|
+
decryptBaselineBlob: () => decryptBaselineBlob,
|
|
57
|
+
deriveBaselineKey: () => deriveBaselineKey,
|
|
58
|
+
deriveEncryptedBaselinePda: () => deriveEncryptedBaselinePda,
|
|
53
59
|
encodeAudioAsBase64: () => encodeAudioAsBase64,
|
|
54
|
-
|
|
60
|
+
encryptBaselineBlob: () => encryptBaselineBlob,
|
|
55
61
|
extractAccelerationMagnitude: () => extractAccelerationMagnitude,
|
|
56
62
|
extractMotionFeatures: () => extractMotionFeatures,
|
|
57
63
|
extractMouseDynamics: () => extractMouseDynamics,
|
|
@@ -59,7 +65,9 @@ __export(index_exports, {
|
|
|
59
65
|
extractSpeakerFeaturesDetailed: () => extractSpeakerFeaturesDetailed,
|
|
60
66
|
extractTouchFeatures: () => extractTouchFeatures,
|
|
61
67
|
fetchChallenge: () => fetchChallenge,
|
|
68
|
+
fetchEncryptedBaseline: () => fetchEncryptedBaseline,
|
|
62
69
|
fetchIdentityState: () => fetchIdentityState,
|
|
70
|
+
fingerprintToBytes: () => fingerprintToBytes,
|
|
63
71
|
fuseFeatures: () => fuseFeatures,
|
|
64
72
|
fuseRawFeatures: () => fuseRawFeatures,
|
|
65
73
|
generateLissajousPoints: () => generateLissajousPoints,
|
|
@@ -71,22 +79,20 @@ __export(index_exports, {
|
|
|
71
79
|
generateSolanaProof: () => generateSolanaProof,
|
|
72
80
|
generateTBH: () => generateTBH,
|
|
73
81
|
getAgentHumanOperator: () => getAgentHumanOperator,
|
|
82
|
+
getOrDeriveBaselineKey: () => getOrDeriveBaselineKey,
|
|
74
83
|
hammingDistance: () => hammingDistance,
|
|
75
|
-
kurtosis: () => kurtosis,
|
|
76
84
|
loadVerificationData: () => loadVerificationData,
|
|
77
|
-
mean: () => mean,
|
|
78
85
|
packBits: () => packBits,
|
|
79
86
|
prepareCircuitInput: () => prepareCircuitInput,
|
|
80
87
|
randomLissajousParams: () => randomLissajousParams,
|
|
88
|
+
recoverBaselineFromChain: () => recoverBaselineFromChain,
|
|
81
89
|
serializeProof: () => serializeProof,
|
|
82
90
|
simhash: () => simhash,
|
|
83
|
-
skewness: () => skewness,
|
|
84
91
|
storeVerificationData: () => storeVerificationData,
|
|
85
92
|
submitResetViaWallet: () => submitResetViaWallet,
|
|
86
93
|
submitViaRelayer: () => submitViaRelayer,
|
|
87
94
|
submitViaWallet: () => submitViaWallet,
|
|
88
95
|
toBigEndian32: () => toBigEndian32,
|
|
89
|
-
variance: () => variance,
|
|
90
96
|
verifyEntrosAttestation: () => verifyEntrosAttestation
|
|
91
97
|
});
|
|
92
98
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -2249,12 +2255,6 @@ var entros_anchor_default = {
|
|
|
2249
2255
|
spec: "0.1.0",
|
|
2250
2256
|
description: "Non-transferable identity token for Entros Protocol"
|
|
2251
2257
|
},
|
|
2252
|
-
docs: [
|
|
2253
|
-
"Mint account space for Token-2022 with NonTransferable extension.",
|
|
2254
|
-
"Base mint = 82 bytes, account type = 1 byte, extension type (2) + length (2) = 4 bytes,",
|
|
2255
|
-
"NonTransferable data = 0 bytes. Plus multisig padding from Token-2022.",
|
|
2256
|
-
"We use a constant derived from the Token-2022 spec."
|
|
2257
|
-
],
|
|
2258
2258
|
instructions: [
|
|
2259
2259
|
{
|
|
2260
2260
|
name: "authorize_new_wallet",
|
|
@@ -3236,6 +3236,132 @@ var entros_anchor_default = {
|
|
|
3236
3236
|
}
|
|
3237
3237
|
]
|
|
3238
3238
|
},
|
|
3239
|
+
{
|
|
3240
|
+
name: "set_encrypted_baseline",
|
|
3241
|
+
docs: [
|
|
3242
|
+
"Write or overwrite the caller's encrypted baseline blob.",
|
|
3243
|
+
"",
|
|
3244
|
+
"The blob is opaque to the program \u2014 AES-256-GCM ciphertext of the",
|
|
3245
|
+
"user's previous SimHash plus salt, produced off-chain in the SDK",
|
|
3246
|
+
"under a key derived from a deterministic `signMessage`. The GCM",
|
|
3247
|
+
"auth tag binds the blob to (wallet, this PDA's address, on-chain",
|
|
3248
|
+
"`current_commitment` at encryption time), so a stale blob produced",
|
|
3249
|
+
"before a `reset_identity_state` fails authentication under the new",
|
|
3250
|
+
"commitment and the SDK falls back to a fresh-capture flow.",
|
|
3251
|
+
"",
|
|
3252
|
+
"The program never decrypts the blob \u2014 it only stores opaque bytes.",
|
|
3253
|
+
"Plaintext biometric data never reaches chain at any point.",
|
|
3254
|
+
"",
|
|
3255
|
+
"Guards:",
|
|
3256
|
+
"* Signer must equal the wallet that seeds the EncryptedBaseline",
|
|
3257
|
+
"PDA (enforced by the seeds constraint on the Accounts struct).",
|
|
3258
|
+
'* The caller\'s IdentityState PDA at `[b"identity", signer]` must',
|
|
3259
|
+
"already exist \u2014 pre-mint attempts are rejected with",
|
|
3260
|
+
"`IdentityStateNotFound`. Anchor's seeds constraint validates the",
|
|
3261
|
+
"PDA address; the `data_len() > 0` check confirms initialization."
|
|
3262
|
+
],
|
|
3263
|
+
discriminator: [
|
|
3264
|
+
10,
|
|
3265
|
+
73,
|
|
3266
|
+
41,
|
|
3267
|
+
36,
|
|
3268
|
+
2,
|
|
3269
|
+
145,
|
|
3270
|
+
87,
|
|
3271
|
+
111
|
|
3272
|
+
],
|
|
3273
|
+
accounts: [
|
|
3274
|
+
{
|
|
3275
|
+
name: "authority",
|
|
3276
|
+
writable: true,
|
|
3277
|
+
signer: true
|
|
3278
|
+
},
|
|
3279
|
+
{
|
|
3280
|
+
name: "identity_state",
|
|
3281
|
+
docs: [
|
|
3282
|
+
"UncheckedAccount because we only need to verify the IdentityState",
|
|
3283
|
+
"PDA exists at the expected address \u2014 we don't need to deserialize",
|
|
3284
|
+
"its fields. The seeds constraint validates the PDA address."
|
|
3285
|
+
],
|
|
3286
|
+
pda: {
|
|
3287
|
+
seeds: [
|
|
3288
|
+
{
|
|
3289
|
+
kind: "const",
|
|
3290
|
+
value: [
|
|
3291
|
+
105,
|
|
3292
|
+
100,
|
|
3293
|
+
101,
|
|
3294
|
+
110,
|
|
3295
|
+
116,
|
|
3296
|
+
105,
|
|
3297
|
+
116,
|
|
3298
|
+
121
|
|
3299
|
+
]
|
|
3300
|
+
},
|
|
3301
|
+
{
|
|
3302
|
+
kind: "account",
|
|
3303
|
+
path: "authority"
|
|
3304
|
+
}
|
|
3305
|
+
]
|
|
3306
|
+
}
|
|
3307
|
+
},
|
|
3308
|
+
{
|
|
3309
|
+
name: "encrypted_baseline",
|
|
3310
|
+
docs: [
|
|
3311
|
+
"The EncryptedBaseline PDA. Created on first call, overwritten on",
|
|
3312
|
+
"subsequent calls. PDA seeds bind to the signer's wallet, so only",
|
|
3313
|
+
"the wallet owner can write to their own baseline."
|
|
3314
|
+
],
|
|
3315
|
+
writable: true,
|
|
3316
|
+
pda: {
|
|
3317
|
+
seeds: [
|
|
3318
|
+
{
|
|
3319
|
+
kind: "const",
|
|
3320
|
+
value: [
|
|
3321
|
+
101,
|
|
3322
|
+
110,
|
|
3323
|
+
99,
|
|
3324
|
+
114,
|
|
3325
|
+
121,
|
|
3326
|
+
112,
|
|
3327
|
+
116,
|
|
3328
|
+
101,
|
|
3329
|
+
100,
|
|
3330
|
+
95,
|
|
3331
|
+
98,
|
|
3332
|
+
97,
|
|
3333
|
+
115,
|
|
3334
|
+
101,
|
|
3335
|
+
108,
|
|
3336
|
+
105,
|
|
3337
|
+
110,
|
|
3338
|
+
101
|
|
3339
|
+
]
|
|
3340
|
+
},
|
|
3341
|
+
{
|
|
3342
|
+
kind: "account",
|
|
3343
|
+
path: "authority"
|
|
3344
|
+
}
|
|
3345
|
+
]
|
|
3346
|
+
}
|
|
3347
|
+
},
|
|
3348
|
+
{
|
|
3349
|
+
name: "system_program",
|
|
3350
|
+
address: "11111111111111111111111111111111"
|
|
3351
|
+
}
|
|
3352
|
+
],
|
|
3353
|
+
args: [
|
|
3354
|
+
{
|
|
3355
|
+
name: "blob",
|
|
3356
|
+
type: {
|
|
3357
|
+
array: [
|
|
3358
|
+
"u8",
|
|
3359
|
+
96
|
|
3360
|
+
]
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
]
|
|
3364
|
+
},
|
|
3239
3365
|
{
|
|
3240
3366
|
name: "update_anchor",
|
|
3241
3367
|
docs: [
|
|
@@ -3539,6 +3665,19 @@ var entros_anchor_default = {
|
|
|
3539
3665
|
}
|
|
3540
3666
|
],
|
|
3541
3667
|
accounts: [
|
|
3668
|
+
{
|
|
3669
|
+
name: "EncryptedBaseline",
|
|
3670
|
+
discriminator: [
|
|
3671
|
+
235,
|
|
3672
|
+
60,
|
|
3673
|
+
246,
|
|
3674
|
+
174,
|
|
3675
|
+
131,
|
|
3676
|
+
9,
|
|
3677
|
+
248,
|
|
3678
|
+
146
|
|
3679
|
+
]
|
|
3680
|
+
},
|
|
3542
3681
|
{
|
|
3543
3682
|
name: "IdentityState",
|
|
3544
3683
|
discriminator: [
|
|
@@ -3593,6 +3732,19 @@ var entros_anchor_default = {
|
|
|
3593
3732
|
59
|
|
3594
3733
|
]
|
|
3595
3734
|
},
|
|
3735
|
+
{
|
|
3736
|
+
name: "EncryptedBaselineSet",
|
|
3737
|
+
discriminator: [
|
|
3738
|
+
198,
|
|
3739
|
+
176,
|
|
3740
|
+
56,
|
|
3741
|
+
167,
|
|
3742
|
+
74,
|
|
3743
|
+
225,
|
|
3744
|
+
138,
|
|
3745
|
+
121
|
|
3746
|
+
]
|
|
3747
|
+
},
|
|
3596
3748
|
{
|
|
3597
3749
|
name: "MigrateIdentityEvent",
|
|
3598
3750
|
discriminator: [
|
|
@@ -3717,6 +3869,11 @@ var entros_anchor_default = {
|
|
|
3717
3869
|
code: 6021,
|
|
3718
3870
|
name: "MalformedReceiptMessage",
|
|
3719
3871
|
msg: "Receipt message has malformed length or layout"
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
code: 6022,
|
|
3875
|
+
name: "IdentityStateNotFound",
|
|
3876
|
+
msg: "set_encrypted_baseline called before mint_anchor \u2014 IdentityState PDA does not exist"
|
|
3720
3877
|
}
|
|
3721
3878
|
],
|
|
3722
3879
|
types: [
|
|
@@ -3799,6 +3956,64 @@ var entros_anchor_default = {
|
|
|
3799
3956
|
]
|
|
3800
3957
|
}
|
|
3801
3958
|
},
|
|
3959
|
+
{
|
|
3960
|
+
name: "EncryptedBaseline",
|
|
3961
|
+
docs: [
|
|
3962
|
+
"Wallet-keyed encrypted baseline blob, stored at PDA seeds",
|
|
3963
|
+
'`[b"encrypted_baseline", wallet.key().as_ref()]`. Persists the user\'s',
|
|
3964
|
+
"previous SimHash + salt across cache wipes and device changes so the",
|
|
3965
|
+
"Hamming-distance ZK proof can recover its private witnesses on any",
|
|
3966
|
+
"device with the originating wallet.",
|
|
3967
|
+
"",
|
|
3968
|
+
"The blob is opaque ciphertext to the program \u2014 AES-256-GCM produced",
|
|
3969
|
+
"off-chain in the SDK under a key derived from a deterministic",
|
|
3970
|
+
"`signMessage` on a domain-separated payload. The GCM AAD binds the",
|
|
3971
|
+
"blob to (wallet, this PDA's address, current on-chain commitment),",
|
|
3972
|
+
"so a stale blob (post-`reset_identity_state`) fails authentication",
|
|
3973
|
+
"against the new commitment and the SDK falls back to a fresh-capture",
|
|
3974
|
+
"flow.",
|
|
3975
|
+
"",
|
|
3976
|
+
"The program never decrypts the blob \u2014 it only stores opaque bytes.",
|
|
3977
|
+
"Plaintext biometric data never reaches chain at any point."
|
|
3978
|
+
],
|
|
3979
|
+
type: {
|
|
3980
|
+
kind: "struct",
|
|
3981
|
+
fields: [
|
|
3982
|
+
{
|
|
3983
|
+
name: "blob",
|
|
3984
|
+
docs: [
|
|
3985
|
+
"96-byte versioned ciphertext envelope.",
|
|
3986
|
+
"Layout: version(1) || algo(1) || reserved(2) || iv(12) || ct+tag(80)."
|
|
3987
|
+
],
|
|
3988
|
+
type: {
|
|
3989
|
+
array: [
|
|
3990
|
+
"u8",
|
|
3991
|
+
96
|
|
3992
|
+
]
|
|
3993
|
+
}
|
|
3994
|
+
},
|
|
3995
|
+
{
|
|
3996
|
+
name: "bump",
|
|
3997
|
+
docs: [
|
|
3998
|
+
"PDA bump seed."
|
|
3999
|
+
],
|
|
4000
|
+
type: "u8"
|
|
4001
|
+
}
|
|
4002
|
+
]
|
|
4003
|
+
}
|
|
4004
|
+
},
|
|
4005
|
+
{
|
|
4006
|
+
name: "EncryptedBaselineSet",
|
|
4007
|
+
type: {
|
|
4008
|
+
kind: "struct",
|
|
4009
|
+
fields: [
|
|
4010
|
+
{
|
|
4011
|
+
name: "owner",
|
|
4012
|
+
type: "pubkey"
|
|
4013
|
+
}
|
|
4014
|
+
]
|
|
4015
|
+
}
|
|
4016
|
+
},
|
|
3802
4017
|
{
|
|
3803
4018
|
name: "IdentityState",
|
|
3804
4019
|
type: {
|
|
@@ -4528,7 +4743,250 @@ async function buildEd25519ReceiptIx(receipt) {
|
|
|
4528
4743
|
});
|
|
4529
4744
|
}
|
|
4530
4745
|
|
|
4746
|
+
// src/identity/baseline.ts
|
|
4747
|
+
var BLOB_VERSION = 1;
|
|
4748
|
+
var ALGORITHM_AES_256_GCM = 1;
|
|
4749
|
+
var ENCRYPTED_BASELINE_BLOB_BYTES = 96;
|
|
4750
|
+
var IV_BYTES = 12;
|
|
4751
|
+
var HEADER_BYTES = 4;
|
|
4752
|
+
var PLAINTEXT_BYTES = 64;
|
|
4753
|
+
function fingerprintToBytes(bits) {
|
|
4754
|
+
if (bits.length !== 256) {
|
|
4755
|
+
throw new Error(`expected 256-bit fingerprint, got ${bits.length}`);
|
|
4756
|
+
}
|
|
4757
|
+
const out = new Uint8Array(32);
|
|
4758
|
+
for (let i = 0; i < 256; i++) {
|
|
4759
|
+
if (bits[i] === 1) {
|
|
4760
|
+
out[i >> 3] = (out[i >> 3] ?? 0) | 1 << (i & 7);
|
|
4761
|
+
}
|
|
4762
|
+
}
|
|
4763
|
+
return out;
|
|
4764
|
+
}
|
|
4765
|
+
function bytesToFingerprint(bytes) {
|
|
4766
|
+
if (bytes.length !== 32) {
|
|
4767
|
+
throw new Error(`expected 32 bytes, got ${bytes.length}`);
|
|
4768
|
+
}
|
|
4769
|
+
const bits = new Array(256);
|
|
4770
|
+
for (let i = 0; i < 256; i++) {
|
|
4771
|
+
bits[i] = (bytes[i >> 3] ?? 0) >> (i & 7) & 1;
|
|
4772
|
+
}
|
|
4773
|
+
return bits;
|
|
4774
|
+
}
|
|
4775
|
+
function bytes32ToBigint(bytes) {
|
|
4776
|
+
if (bytes.length !== 32) {
|
|
4777
|
+
throw new Error(`expected 32 bytes, got ${bytes.length}`);
|
|
4778
|
+
}
|
|
4779
|
+
let val = BigInt(0);
|
|
4780
|
+
for (let i = 0; i < 32; i++) {
|
|
4781
|
+
val = val << BigInt(8) | BigInt(bytes[i] ?? 0);
|
|
4782
|
+
}
|
|
4783
|
+
return val;
|
|
4784
|
+
}
|
|
4785
|
+
function buildDomainMessage(walletPubkey) {
|
|
4786
|
+
return [
|
|
4787
|
+
"Entros Protocol \u2014 Identity Baseline Key Derivation",
|
|
4788
|
+
"",
|
|
4789
|
+
"By signing this message, you authorize Entros Protocol to derive",
|
|
4790
|
+
"an encryption key for your on-chain identity baseline. This is",
|
|
4791
|
+
"not a transaction.",
|
|
4792
|
+
"",
|
|
4793
|
+
`Wallet: ${walletPubkey.toBase58()}`,
|
|
4794
|
+
"Version: 1",
|
|
4795
|
+
"Domain: entros.io"
|
|
4796
|
+
].join("\n");
|
|
4797
|
+
}
|
|
4798
|
+
async function deriveEncryptedBaselinePda(walletPubkey) {
|
|
4799
|
+
const { PublicKey: PK } = await import("@solana/web3.js");
|
|
4800
|
+
const programId = new PK(PROGRAM_IDS.entrosAnchor);
|
|
4801
|
+
return PK.findProgramAddressSync(
|
|
4802
|
+
[new TextEncoder().encode("encrypted_baseline"), walletPubkey.toBuffer()],
|
|
4803
|
+
programId
|
|
4804
|
+
);
|
|
4805
|
+
}
|
|
4806
|
+
async function deriveBaselineKey(wallet) {
|
|
4807
|
+
if (typeof wallet.signMessage !== "function") {
|
|
4808
|
+
throw new Error("wallet does not support signMessage");
|
|
4809
|
+
}
|
|
4810
|
+
const message = buildDomainMessage(wallet.publicKey);
|
|
4811
|
+
const signature = await wallet.signMessage(new TextEncoder().encode(message));
|
|
4812
|
+
if (!(signature instanceof Uint8Array) || signature.length !== 64) {
|
|
4813
|
+
throw new Error(
|
|
4814
|
+
`expected 64-byte Ed25519 signature, got ${signature?.length ?? "non-Uint8Array"}`
|
|
4815
|
+
);
|
|
4816
|
+
}
|
|
4817
|
+
const ikm = await crypto.subtle.importKey(
|
|
4818
|
+
"raw",
|
|
4819
|
+
signature,
|
|
4820
|
+
"HKDF",
|
|
4821
|
+
false,
|
|
4822
|
+
["deriveBits"]
|
|
4823
|
+
);
|
|
4824
|
+
const bits = await crypto.subtle.deriveBits(
|
|
4825
|
+
{
|
|
4826
|
+
name: "HKDF",
|
|
4827
|
+
hash: "SHA-256",
|
|
4828
|
+
salt: wallet.publicKey.toBytes(),
|
|
4829
|
+
info: new TextEncoder().encode("entros-protocol/identity-baseline/v1")
|
|
4830
|
+
},
|
|
4831
|
+
ikm,
|
|
4832
|
+
256
|
|
4833
|
+
);
|
|
4834
|
+
return crypto.subtle.importKey(
|
|
4835
|
+
"raw",
|
|
4836
|
+
bits,
|
|
4837
|
+
{ name: "AES-GCM" },
|
|
4838
|
+
false,
|
|
4839
|
+
["encrypt", "decrypt"]
|
|
4840
|
+
);
|
|
4841
|
+
}
|
|
4842
|
+
var baselineKeyCache = /* @__PURE__ */ new Map();
|
|
4843
|
+
async function getOrDeriveBaselineKey(wallet) {
|
|
4844
|
+
const pubkeyBase58 = wallet.publicKey.toBase58();
|
|
4845
|
+
const cached = baselineKeyCache.get(pubkeyBase58);
|
|
4846
|
+
if (cached) return cached;
|
|
4847
|
+
const pending = (async () => {
|
|
4848
|
+
try {
|
|
4849
|
+
return await deriveBaselineKey(wallet);
|
|
4850
|
+
} catch (err) {
|
|
4851
|
+
baselineKeyCache.delete(pubkeyBase58);
|
|
4852
|
+
throw err;
|
|
4853
|
+
}
|
|
4854
|
+
})();
|
|
4855
|
+
baselineKeyCache.set(pubkeyBase58, pending);
|
|
4856
|
+
return pending;
|
|
4857
|
+
}
|
|
4858
|
+
function clearBaselineKeyCache() {
|
|
4859
|
+
baselineKeyCache.clear();
|
|
4860
|
+
}
|
|
4861
|
+
function buildAAD(walletPubkey, baselinePda, commitment) {
|
|
4862
|
+
if (commitment.length !== 32) {
|
|
4863
|
+
throw new Error(`commitment must be 32 bytes, got ${commitment.length}`);
|
|
4864
|
+
}
|
|
4865
|
+
const aad = new Uint8Array(98);
|
|
4866
|
+
aad[0] = BLOB_VERSION;
|
|
4867
|
+
aad[1] = ALGORITHM_AES_256_GCM;
|
|
4868
|
+
aad.set(walletPubkey.toBytes(), 2);
|
|
4869
|
+
aad.set(baselinePda.toBytes(), 34);
|
|
4870
|
+
aad.set(commitment, 66);
|
|
4871
|
+
return aad;
|
|
4872
|
+
}
|
|
4873
|
+
async function encryptBaselineBlob(simhash2, salt, key, walletPubkey, baselinePda, commitment) {
|
|
4874
|
+
if (simhash2.length !== 32) {
|
|
4875
|
+
throw new Error(`simhash must be 32 bytes, got ${simhash2.length}`);
|
|
4876
|
+
}
|
|
4877
|
+
if (salt.length !== 32) {
|
|
4878
|
+
throw new Error(`salt must be 32 bytes, got ${salt.length}`);
|
|
4879
|
+
}
|
|
4880
|
+
const plaintext = new Uint8Array(PLAINTEXT_BYTES);
|
|
4881
|
+
plaintext.set(simhash2, 0);
|
|
4882
|
+
plaintext.set(salt, 32);
|
|
4883
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));
|
|
4884
|
+
const aad = buildAAD(walletPubkey, baselinePda, commitment);
|
|
4885
|
+
const ciphertextWithTag = new Uint8Array(
|
|
4886
|
+
await crypto.subtle.encrypt(
|
|
4887
|
+
{
|
|
4888
|
+
name: "AES-GCM",
|
|
4889
|
+
iv,
|
|
4890
|
+
additionalData: aad
|
|
4891
|
+
},
|
|
4892
|
+
key,
|
|
4893
|
+
plaintext
|
|
4894
|
+
)
|
|
4895
|
+
);
|
|
4896
|
+
const blob = new Uint8Array(ENCRYPTED_BASELINE_BLOB_BYTES);
|
|
4897
|
+
blob[0] = BLOB_VERSION;
|
|
4898
|
+
blob[1] = ALGORITHM_AES_256_GCM;
|
|
4899
|
+
blob.set(iv, HEADER_BYTES);
|
|
4900
|
+
blob.set(ciphertextWithTag, HEADER_BYTES + IV_BYTES);
|
|
4901
|
+
return blob;
|
|
4902
|
+
}
|
|
4903
|
+
var StaleEncryptedBaselineError = class extends Error {
|
|
4904
|
+
constructor(message) {
|
|
4905
|
+
super(message);
|
|
4906
|
+
this.name = "StaleEncryptedBaselineError";
|
|
4907
|
+
}
|
|
4908
|
+
};
|
|
4909
|
+
async function decryptBaselineBlob(blob, key, walletPubkey, baselinePda, commitment) {
|
|
4910
|
+
if (commitment.length !== 32) {
|
|
4911
|
+
throw new Error(`commitment must be 32 bytes, got ${commitment.length}`);
|
|
4912
|
+
}
|
|
4913
|
+
if (blob.length !== ENCRYPTED_BASELINE_BLOB_BYTES) {
|
|
4914
|
+
throw new Error(
|
|
4915
|
+
`blob must be ${ENCRYPTED_BASELINE_BLOB_BYTES} bytes, got ${blob.length}`
|
|
4916
|
+
);
|
|
4917
|
+
}
|
|
4918
|
+
if (blob[0] !== BLOB_VERSION) {
|
|
4919
|
+
throw new Error(`unsupported blob version: ${blob[0]}`);
|
|
4920
|
+
}
|
|
4921
|
+
if (blob[1] !== ALGORITHM_AES_256_GCM) {
|
|
4922
|
+
throw new Error(`unsupported algorithm id: ${blob[1]}`);
|
|
4923
|
+
}
|
|
4924
|
+
const iv = blob.slice(HEADER_BYTES, HEADER_BYTES + IV_BYTES);
|
|
4925
|
+
const ciphertextWithTag = blob.slice(
|
|
4926
|
+
HEADER_BYTES + IV_BYTES,
|
|
4927
|
+
ENCRYPTED_BASELINE_BLOB_BYTES
|
|
4928
|
+
);
|
|
4929
|
+
const aad = buildAAD(walletPubkey, baselinePda, commitment);
|
|
4930
|
+
let plaintext;
|
|
4931
|
+
try {
|
|
4932
|
+
plaintext = await crypto.subtle.decrypt(
|
|
4933
|
+
{
|
|
4934
|
+
name: "AES-GCM",
|
|
4935
|
+
iv,
|
|
4936
|
+
additionalData: aad
|
|
4937
|
+
},
|
|
4938
|
+
key,
|
|
4939
|
+
ciphertextWithTag
|
|
4940
|
+
);
|
|
4941
|
+
} catch (err) {
|
|
4942
|
+
if (err instanceof Error && err.name === "OperationError") {
|
|
4943
|
+
throw new StaleEncryptedBaselineError(
|
|
4944
|
+
"encrypted baseline auth-tag verification failed \u2014 blob is stale or AAD does not match"
|
|
4945
|
+
);
|
|
4946
|
+
}
|
|
4947
|
+
throw err;
|
|
4948
|
+
}
|
|
4949
|
+
const bytes = new Uint8Array(plaintext);
|
|
4950
|
+
return {
|
|
4951
|
+
simhash: bytes.slice(0, 32),
|
|
4952
|
+
salt: bytes.slice(32, 64)
|
|
4953
|
+
};
|
|
4954
|
+
}
|
|
4955
|
+
async function fetchEncryptedBaseline(walletPubkey, connection) {
|
|
4956
|
+
const [baselinePda] = await deriveEncryptedBaselinePda(walletPubkey);
|
|
4957
|
+
const accountInfo = await connection.getAccountInfo(baselinePda);
|
|
4958
|
+
if (!accountInfo) return null;
|
|
4959
|
+
const raw = accountInfo.data instanceof Uint8Array ? accountInfo.data : new Uint8Array(accountInfo.data);
|
|
4960
|
+
if (raw.length < 8 + ENCRYPTED_BASELINE_BLOB_BYTES + 1) {
|
|
4961
|
+
return null;
|
|
4962
|
+
}
|
|
4963
|
+
return raw.slice(8, 8 + ENCRYPTED_BASELINE_BLOB_BYTES);
|
|
4964
|
+
}
|
|
4965
|
+
|
|
4531
4966
|
// src/submit/wallet.ts
|
|
4967
|
+
async function buildSetEncryptedBaselineIx(anchorProgram, walletPubkey, blob) {
|
|
4968
|
+
if (blob.length !== ENCRYPTED_BASELINE_BLOB_BYTES) {
|
|
4969
|
+
throw new Error(
|
|
4970
|
+
`encrypted baseline blob must be ${ENCRYPTED_BASELINE_BLOB_BYTES} bytes, got ${blob.length}`
|
|
4971
|
+
);
|
|
4972
|
+
}
|
|
4973
|
+
const { PublicKey, SystemProgram } = await import("@solana/web3.js");
|
|
4974
|
+
const programId = new PublicKey(PROGRAM_IDS.entrosAnchor);
|
|
4975
|
+
const [identityPda] = PublicKey.findProgramAddressSync(
|
|
4976
|
+
[new TextEncoder().encode("identity"), walletPubkey.toBuffer()],
|
|
4977
|
+
programId
|
|
4978
|
+
);
|
|
4979
|
+
const [encryptedBaselinePda] = PublicKey.findProgramAddressSync(
|
|
4980
|
+
[new TextEncoder().encode("encrypted_baseline"), walletPubkey.toBuffer()],
|
|
4981
|
+
programId
|
|
4982
|
+
);
|
|
4983
|
+
return anchorProgram.methods.setEncryptedBaseline(Array.from(blob)).accounts({
|
|
4984
|
+
authority: walletPubkey,
|
|
4985
|
+
identityState: identityPda,
|
|
4986
|
+
encryptedBaseline: encryptedBaselinePda,
|
|
4987
|
+
systemProgram: SystemProgram.programId
|
|
4988
|
+
}).instruction();
|
|
4989
|
+
}
|
|
4532
4990
|
async function confirmAndCheck(connection, signature) {
|
|
4533
4991
|
if (!signature) {
|
|
4534
4992
|
throw new Error("confirmAndCheck called without a transaction signature");
|
|
@@ -4715,10 +5173,19 @@ async function submitViaWallet(proof, commitment, options) {
|
|
|
4715
5173
|
systemProgram: SystemProgram.programId
|
|
4716
5174
|
}).instruction();
|
|
4717
5175
|
const tx = new Transaction();
|
|
4718
|
-
|
|
5176
|
+
const computeUnitLimit = options.encryptedBaselineBlob ? 3e5 : 25e4;
|
|
5177
|
+
tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitLimit }));
|
|
4719
5178
|
tx.add(createChallengeIx);
|
|
4720
5179
|
tx.add(verifyProofIx);
|
|
4721
5180
|
tx.add(updateAnchorIx);
|
|
5181
|
+
if (options.encryptedBaselineBlob) {
|
|
5182
|
+
const setBaselineIx = await buildSetEncryptedBaselineIx(
|
|
5183
|
+
anchorProgram,
|
|
5184
|
+
provider.wallet.publicKey,
|
|
5185
|
+
options.encryptedBaselineBlob
|
|
5186
|
+
);
|
|
5187
|
+
tx.add(setBaselineIx);
|
|
5188
|
+
}
|
|
4722
5189
|
tx.feePayer = provider.wallet.publicKey;
|
|
4723
5190
|
tx.recentBlockhash = (await options.connection.getLatestBlockhash("confirmed")).blockhash;
|
|
4724
5191
|
txSig = await options.wallet.sendTransaction(tx, options.connection, {
|
|
@@ -4794,9 +5261,18 @@ async function submitViaWallet(proof, commitment, options) {
|
|
|
4794
5261
|
);
|
|
4795
5262
|
}
|
|
4796
5263
|
const tx = new Transaction();
|
|
4797
|
-
|
|
5264
|
+
const computeUnitLimit = options.encryptedBaselineBlob ? 25e4 : 2e5;
|
|
5265
|
+
tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitLimit }));
|
|
4798
5266
|
if (ed25519Ix) tx.add(ed25519Ix);
|
|
4799
5267
|
tx.add(mintAnchorIx);
|
|
5268
|
+
if (options.encryptedBaselineBlob) {
|
|
5269
|
+
const setBaselineIx = await buildSetEncryptedBaselineIx(
|
|
5270
|
+
anchorProgram,
|
|
5271
|
+
provider.wallet.publicKey,
|
|
5272
|
+
options.encryptedBaselineBlob
|
|
5273
|
+
);
|
|
5274
|
+
tx.add(setBaselineIx);
|
|
5275
|
+
}
|
|
4800
5276
|
tx.feePayer = provider.wallet.publicKey;
|
|
4801
5277
|
tx.recentBlockhash = (await options.connection.getLatestBlockhash("confirmed")).blockhash;
|
|
4802
5278
|
txSig = await options.wallet.sendTransaction(tx, options.connection, {
|
|
@@ -4851,8 +5327,16 @@ async function submitResetViaWallet(commitment, options) {
|
|
|
4851
5327
|
systemProgram: SystemProgram.programId
|
|
4852
5328
|
}).instruction();
|
|
4853
5329
|
const tx = new Transaction();
|
|
4854
|
-
tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units:
|
|
5330
|
+
tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units: 2e5 }));
|
|
4855
5331
|
tx.add(resetIx);
|
|
5332
|
+
if (options.encryptedBaselineBlob) {
|
|
5333
|
+
const setBaselineIx = await buildSetEncryptedBaselineIx(
|
|
5334
|
+
anchorProgram,
|
|
5335
|
+
provider.wallet.publicKey,
|
|
5336
|
+
options.encryptedBaselineBlob
|
|
5337
|
+
);
|
|
5338
|
+
tx.add(setBaselineIx);
|
|
5339
|
+
}
|
|
4856
5340
|
tx.feePayer = provider.wallet.publicKey;
|
|
4857
5341
|
tx.recentBlockhash = (await options.connection.getLatestBlockhash("confirmed")).blockhash;
|
|
4858
5342
|
const txSig = await options.wallet.sendTransaction(
|
|
@@ -5167,6 +5651,65 @@ async function loadVerificationData() {
|
|
|
5167
5651
|
return inMemoryStore;
|
|
5168
5652
|
}
|
|
5169
5653
|
}
|
|
5654
|
+
async function recoverBaselineFromChain(wallet, connection) {
|
|
5655
|
+
try {
|
|
5656
|
+
const identity = await fetchIdentityState(
|
|
5657
|
+
wallet.publicKey.toBase58(),
|
|
5658
|
+
connection
|
|
5659
|
+
);
|
|
5660
|
+
if (!identity) {
|
|
5661
|
+
return { recovered: false, reason: "no-on-chain-identity" };
|
|
5662
|
+
}
|
|
5663
|
+
const blob = await fetchEncryptedBaseline(wallet.publicKey, connection);
|
|
5664
|
+
if (!blob) {
|
|
5665
|
+
return { recovered: false, reason: "no-encrypted-baseline" };
|
|
5666
|
+
}
|
|
5667
|
+
let key;
|
|
5668
|
+
try {
|
|
5669
|
+
key = await getOrDeriveBaselineKey(wallet);
|
|
5670
|
+
} catch (err) {
|
|
5671
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
5672
|
+
return {
|
|
5673
|
+
recovered: false,
|
|
5674
|
+
reason: "signing-unavailable",
|
|
5675
|
+
detail
|
|
5676
|
+
};
|
|
5677
|
+
}
|
|
5678
|
+
const [baselinePda] = await deriveEncryptedBaselinePda(wallet.publicKey);
|
|
5679
|
+
let plaintext;
|
|
5680
|
+
try {
|
|
5681
|
+
plaintext = await decryptBaselineBlob(
|
|
5682
|
+
blob,
|
|
5683
|
+
key,
|
|
5684
|
+
wallet.publicKey,
|
|
5685
|
+
baselinePda,
|
|
5686
|
+
identity.currentCommitment
|
|
5687
|
+
);
|
|
5688
|
+
} catch (err) {
|
|
5689
|
+
if (err instanceof StaleEncryptedBaselineError) {
|
|
5690
|
+
return { recovered: false, reason: "stale-baseline" };
|
|
5691
|
+
}
|
|
5692
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
5693
|
+
return { recovered: false, reason: "unknown-error", detail };
|
|
5694
|
+
}
|
|
5695
|
+
const fingerprint = bytesToFingerprint(plaintext.simhash);
|
|
5696
|
+
const saltBigint = bytes32ToBigint(plaintext.salt);
|
|
5697
|
+
const commitmentBigint = bytes32ToBigint(identity.currentCommitment);
|
|
5698
|
+
await storeVerificationData({
|
|
5699
|
+
fingerprint,
|
|
5700
|
+
salt: saltBigint.toString(),
|
|
5701
|
+
commitment: commitmentBigint.toString(),
|
|
5702
|
+
timestamp: identity.lastVerificationTimestamp > 0 ? identity.lastVerificationTimestamp * 1e3 : Date.now()
|
|
5703
|
+
});
|
|
5704
|
+
sdkLog(
|
|
5705
|
+
"[Entros SDK] Recovered local baseline from on-chain EncryptedBaseline PDA"
|
|
5706
|
+
);
|
|
5707
|
+
return { recovered: true };
|
|
5708
|
+
} catch (err) {
|
|
5709
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
5710
|
+
return { recovered: false, reason: "unknown-error", detail };
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5170
5713
|
|
|
5171
5714
|
// src/pulse.ts
|
|
5172
5715
|
async function extractFeatures(data) {
|
|
@@ -5277,6 +5820,41 @@ async function extractFingerprintAndValidate(sensorData, config, walletAddress,
|
|
|
5277
5820
|
}
|
|
5278
5821
|
return { ok: true, features, f0Contour, accelMagnitude, fingerprint, tbh, signedReceipt };
|
|
5279
5822
|
}
|
|
5823
|
+
function resolveBaselineWallet(wallet) {
|
|
5824
|
+
if (!wallet) return null;
|
|
5825
|
+
const adapter = wallet.adapter ?? wallet;
|
|
5826
|
+
if (!adapter?.publicKey || typeof adapter.signMessage !== "function") {
|
|
5827
|
+
return null;
|
|
5828
|
+
}
|
|
5829
|
+
return {
|
|
5830
|
+
publicKey: adapter.publicKey,
|
|
5831
|
+
signMessage: adapter.signMessage.bind(adapter)
|
|
5832
|
+
};
|
|
5833
|
+
}
|
|
5834
|
+
async function buildEncryptedBaselineBlobBestEffort(wallet, fingerprint, salt, commitmentBytes) {
|
|
5835
|
+
const baselineWallet = resolveBaselineWallet(wallet);
|
|
5836
|
+
if (!baselineWallet) return void 0;
|
|
5837
|
+
try {
|
|
5838
|
+
const key = await getOrDeriveBaselineKey(baselineWallet);
|
|
5839
|
+
const [baselinePda] = await deriveEncryptedBaselinePda(baselineWallet.publicKey);
|
|
5840
|
+
const simhashBytes = fingerprintToBytes(fingerprint);
|
|
5841
|
+
const saltBytes = bigintToBytes32(salt);
|
|
5842
|
+
return await encryptBaselineBlob(
|
|
5843
|
+
simhashBytes,
|
|
5844
|
+
saltBytes,
|
|
5845
|
+
key,
|
|
5846
|
+
baselineWallet.publicKey,
|
|
5847
|
+
baselinePda,
|
|
5848
|
+
commitmentBytes
|
|
5849
|
+
);
|
|
5850
|
+
} catch (err) {
|
|
5851
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5852
|
+
sdkWarn(
|
|
5853
|
+
`[Entros SDK] Encrypted-baseline build skipped (cross-device recovery unavailable this session): ${msg}`
|
|
5854
|
+
);
|
|
5855
|
+
return void 0;
|
|
5856
|
+
}
|
|
5857
|
+
}
|
|
5280
5858
|
async function processSensorData(sensorData, config, wallet, connection, onProgress) {
|
|
5281
5859
|
const audioSamples = sensorData.audio?.samples.length ?? 0;
|
|
5282
5860
|
const motionSamples = sensorData.motion.length;
|
|
@@ -5348,7 +5926,7 @@ async function processSensorData(sensorData, config, wallet, connection, onProgr
|
|
|
5348
5926
|
}
|
|
5349
5927
|
const { fingerprint, tbh, features, signedReceipt } = extraction;
|
|
5350
5928
|
let isFirstVerification;
|
|
5351
|
-
|
|
5929
|
+
let previousData = await loadVerificationData();
|
|
5352
5930
|
if (wallet && connection) {
|
|
5353
5931
|
const walletPubkey = wallet.adapter?.publicKey ?? wallet.publicKey;
|
|
5354
5932
|
if (walletPubkey) {
|
|
@@ -5370,6 +5948,21 @@ async function processSensorData(sensorData, config, wallet, connection, onProgr
|
|
|
5370
5948
|
} else {
|
|
5371
5949
|
isFirstVerification = !previousData;
|
|
5372
5950
|
}
|
|
5951
|
+
if (!isFirstVerification && !previousData && wallet && connection) {
|
|
5952
|
+
const baselineWallet = resolveBaselineWallet(wallet);
|
|
5953
|
+
if (baselineWallet) {
|
|
5954
|
+
onProgress?.("Recovering baseline from chain...");
|
|
5955
|
+
const recovery = await recoverBaselineFromChain(baselineWallet, connection);
|
|
5956
|
+
if (recovery.recovered) {
|
|
5957
|
+
previousData = await loadVerificationData();
|
|
5958
|
+
sdkLog("[Entros SDK] On-chain encrypted baseline recovered");
|
|
5959
|
+
} else {
|
|
5960
|
+
sdkLog(
|
|
5961
|
+
`[Entros SDK] On-chain encrypted baseline recovery not available (${recovery.reason ?? "unknown"})`
|
|
5962
|
+
);
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5373
5966
|
if (!isFirstVerification && !previousData) {
|
|
5374
5967
|
return {
|
|
5375
5968
|
success: false,
|
|
@@ -5435,6 +6028,12 @@ async function processSensorData(sensorData, config, wallet, connection, onProgr
|
|
|
5435
6028
|
onProgress?.("Submitting to Solana...");
|
|
5436
6029
|
let submission;
|
|
5437
6030
|
if (wallet && connection) {
|
|
6031
|
+
const encryptedBaselineBlob = await buildEncryptedBaselineBlobBestEffort(
|
|
6032
|
+
wallet,
|
|
6033
|
+
tbh.fingerprint,
|
|
6034
|
+
tbh.salt,
|
|
6035
|
+
tbh.commitmentBytes
|
|
6036
|
+
);
|
|
5438
6037
|
if (isFirstVerification) {
|
|
5439
6038
|
submission = await submitViaWallet(
|
|
5440
6039
|
solanaProof ?? { proofBytes: new Uint8Array(0), publicInputs: [] },
|
|
@@ -5445,7 +6044,8 @@ async function processSensorData(sensorData, config, wallet, connection, onProgr
|
|
|
5445
6044
|
isFirstVerification: true,
|
|
5446
6045
|
relayerUrl: config.relayerUrl,
|
|
5447
6046
|
relayerApiKey: config.relayerApiKey,
|
|
5448
|
-
signedReceipt
|
|
6047
|
+
signedReceipt,
|
|
6048
|
+
encryptedBaselineBlob
|
|
5449
6049
|
}
|
|
5450
6050
|
);
|
|
5451
6051
|
} else {
|
|
@@ -5454,7 +6054,8 @@ async function processSensorData(sensorData, config, wallet, connection, onProgr
|
|
|
5454
6054
|
connection,
|
|
5455
6055
|
isFirstVerification: false,
|
|
5456
6056
|
relayerUrl: config.relayerUrl,
|
|
5457
|
-
relayerApiKey: config.relayerApiKey
|
|
6057
|
+
relayerApiKey: config.relayerApiKey,
|
|
6058
|
+
encryptedBaselineBlob
|
|
5458
6059
|
});
|
|
5459
6060
|
}
|
|
5460
6061
|
} else if (config.relayerUrl) {
|
|
@@ -5536,12 +6137,19 @@ async function processResetSensorData(sensorData, config, wallet, connection, on
|
|
|
5536
6137
|
};
|
|
5537
6138
|
}
|
|
5538
6139
|
const { tbh } = extraction;
|
|
6140
|
+
const encryptedBaselineBlob = await buildEncryptedBaselineBlobBestEffort(
|
|
6141
|
+
wallet,
|
|
6142
|
+
tbh.fingerprint,
|
|
6143
|
+
tbh.salt,
|
|
6144
|
+
tbh.commitmentBytes
|
|
6145
|
+
);
|
|
5539
6146
|
onProgress?.("Submitting reset to Solana...");
|
|
5540
6147
|
const submission = await submitResetViaWallet(tbh.commitmentBytes, {
|
|
5541
6148
|
wallet,
|
|
5542
6149
|
connection,
|
|
5543
6150
|
relayerUrl: config.relayerUrl,
|
|
5544
|
-
relayerApiKey: config.relayerApiKey
|
|
6151
|
+
relayerApiKey: config.relayerApiKey,
|
|
6152
|
+
encryptedBaselineBlob
|
|
5545
6153
|
});
|
|
5546
6154
|
if (submission.success) {
|
|
5547
6155
|
try {
|
|
@@ -6429,6 +7037,7 @@ async function fetchChallenge(executorUrl, walletAddress, apiKey) {
|
|
|
6429
7037
|
DEFAULT_CAPTURE_MS,
|
|
6430
7038
|
DEFAULT_MIN_DISTANCE,
|
|
6431
7039
|
DEFAULT_THRESHOLD,
|
|
7040
|
+
ENCRYPTED_BASELINE_BLOB_BYTES,
|
|
6432
7041
|
FINGERPRINT_BITS,
|
|
6433
7042
|
MAX_CAPTURE_MS,
|
|
6434
7043
|
MIN_AUDIO_SAMPLES,
|
|
@@ -6440,14 +7049,19 @@ async function fetchChallenge(executorUrl, walletAddress, apiKey) {
|
|
|
6440
7049
|
PulseSDK,
|
|
6441
7050
|
PulseSession,
|
|
6442
7051
|
SPEAKER_FEATURE_COUNT,
|
|
7052
|
+
StaleEncryptedBaselineError,
|
|
6443
7053
|
TOUCH_FEATURE_COUNT,
|
|
6444
7054
|
attestAgentOperator,
|
|
6445
|
-
autocorrelation,
|
|
6446
7055
|
bigintToBytes32,
|
|
7056
|
+
bytes32ToBigint,
|
|
7057
|
+
bytesToFingerprint,
|
|
7058
|
+
clearBaselineKeyCache,
|
|
6447
7059
|
computeCommitment,
|
|
6448
|
-
|
|
7060
|
+
decryptBaselineBlob,
|
|
7061
|
+
deriveBaselineKey,
|
|
7062
|
+
deriveEncryptedBaselinePda,
|
|
6449
7063
|
encodeAudioAsBase64,
|
|
6450
|
-
|
|
7064
|
+
encryptBaselineBlob,
|
|
6451
7065
|
extractAccelerationMagnitude,
|
|
6452
7066
|
extractMotionFeatures,
|
|
6453
7067
|
extractMouseDynamics,
|
|
@@ -6455,7 +7069,9 @@ async function fetchChallenge(executorUrl, walletAddress, apiKey) {
|
|
|
6455
7069
|
extractSpeakerFeaturesDetailed,
|
|
6456
7070
|
extractTouchFeatures,
|
|
6457
7071
|
fetchChallenge,
|
|
7072
|
+
fetchEncryptedBaseline,
|
|
6458
7073
|
fetchIdentityState,
|
|
7074
|
+
fingerprintToBytes,
|
|
6459
7075
|
fuseFeatures,
|
|
6460
7076
|
fuseRawFeatures,
|
|
6461
7077
|
generateLissajousPoints,
|
|
@@ -6467,22 +7083,20 @@ async function fetchChallenge(executorUrl, walletAddress, apiKey) {
|
|
|
6467
7083
|
generateSolanaProof,
|
|
6468
7084
|
generateTBH,
|
|
6469
7085
|
getAgentHumanOperator,
|
|
7086
|
+
getOrDeriveBaselineKey,
|
|
6470
7087
|
hammingDistance,
|
|
6471
|
-
kurtosis,
|
|
6472
7088
|
loadVerificationData,
|
|
6473
|
-
mean,
|
|
6474
7089
|
packBits,
|
|
6475
7090
|
prepareCircuitInput,
|
|
6476
7091
|
randomLissajousParams,
|
|
7092
|
+
recoverBaselineFromChain,
|
|
6477
7093
|
serializeProof,
|
|
6478
7094
|
simhash,
|
|
6479
|
-
skewness,
|
|
6480
7095
|
storeVerificationData,
|
|
6481
7096
|
submitResetViaWallet,
|
|
6482
7097
|
submitViaRelayer,
|
|
6483
7098
|
submitViaWallet,
|
|
6484
7099
|
toBigEndian32,
|
|
6485
|
-
variance,
|
|
6486
7100
|
verifyEntrosAttestation
|
|
6487
7101
|
});
|
|
6488
7102
|
//# sourceMappingURL=index.js.map
|