@orangecheck/me-client 0.32.2 → 0.32.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{identity-1VYMOhzV.d.mts → identity-6pjtyKYh.d.mts} +1 -1
- package/dist/{identity-1VYMOhzV.d.ts → identity-6pjtyKYh.d.ts} +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +74 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +74 -22
- package/dist/index.mjs.map +1 -1
- package/dist/integrator.js.map +1 -1
- package/dist/integrator.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +72 -21
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +72 -21
- package/dist/server.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @orangecheck/me-client
|
|
2
2
|
|
|
3
|
-
> **Full reference:** [
|
|
3
|
+
> **Full reference:** [ochk.io/docs/sdk/me-client](https://ochk.io/docs/sdk/me-client) — auto-generated from the TypeScript source on every release.
|
|
4
4
|
> Hand-written prose below is the high-level overview; the docs site is the source of truth for every export, type, and signature.
|
|
5
5
|
|
|
6
6
|
|
|
@@ -153,7 +153,7 @@ const unsubscribe = onTelemetry((event) => {
|
|
|
153
153
|
});
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
See [
|
|
156
|
+
See [ochk.app/pricing](https://ochk.app/pricing) for what each kind of event pays and what you never pay for, and [ochk.io/docs/me/sdk](https://ochk.io/docs/me/sdk) for the full SDK reference.
|
|
157
157
|
|
|
158
158
|
## Types
|
|
159
159
|
|
|
@@ -170,7 +170,7 @@ import type {
|
|
|
170
170
|
} from '@orangecheck/me-client';
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
These mirror what the me.ochk.io API accepts and returns. A change to the API ships here in the next minor.
|
|
174
174
|
|
|
175
175
|
## Server-side verification
|
|
176
176
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { v as verifyActivityAttestation, r as refreshEnvelopeJwks } from './identity-
|
|
2
|
-
export { A as ActivityAttestation, a as ActivityAttestationBundle, b as ActivityVerifyCheck, c as ActivityVerifyResult, V as VerifyActivityOptions, i as identity } from './identity-
|
|
1
|
+
import { v as verifyActivityAttestation, r as refreshEnvelopeJwks } from './identity-6pjtyKYh.mjs';
|
|
2
|
+
export { A as ActivityAttestation, a as ActivityAttestationBundle, b as ActivityVerifyCheck, c as ActivityVerifyResult, V as VerifyActivityOptions, i as identity } from './identity-6pjtyKYh.mjs';
|
|
3
3
|
import { B as BillableEvent, E as EventKey, I as IntegratorPriceConfig, T as TelemetryEvent, S as SignInOptions, a as Session, P as PaymentAuthorizeOptions, b as PaymentResult, V as ValidationResult, f as fromTemplate, g as getArchetypeTemplate, A as ArchetypeTemplate, F as Federation } from './integrator-C-enR55c.mjs';
|
|
4
4
|
export { c as ALL_EVENT_SUBTYPES, d as ARCHETYPE_TEMPLATES, e as AgentClassOverride, h as AttestTier, C as ClassASubtype, i as ClassBSubtype, j as ClassCSubtype, k as ComputedFees, D as DropCadence, l as DropClosedWebhookPayload, m as DropResponseBlock, n as DropScheduleSummary, o as EVENT_SUBTYPES, p as EventClass, q as EventSubtype, r as EventSubtypeMetadata, s as FederationStatus, t as IntegratorArchetype, u as IntegratorEventConfig, M as MAX_DROP_WINDOW_DAYS, v as MIN_INTEGRATOR_PRICE_SATS, w as PLATFORM_FEE_POLICY, x as SessionPolicy, y as SigningMethod, z as SiteFeeShape, G as SystemWebhookPayload, W as WebhookHeaders, H as WebhookPayload, J as computeFees, K as subtypesForClass, L as validateIntegratorConfig } from './integrator-C-enR55c.mjs';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { v as verifyActivityAttestation, r as refreshEnvelopeJwks } from './identity-
|
|
2
|
-
export { A as ActivityAttestation, a as ActivityAttestationBundle, b as ActivityVerifyCheck, c as ActivityVerifyResult, V as VerifyActivityOptions, i as identity } from './identity-
|
|
1
|
+
import { v as verifyActivityAttestation, r as refreshEnvelopeJwks } from './identity-6pjtyKYh.js';
|
|
2
|
+
export { A as ActivityAttestation, a as ActivityAttestationBundle, b as ActivityVerifyCheck, c as ActivityVerifyResult, V as VerifyActivityOptions, i as identity } from './identity-6pjtyKYh.js';
|
|
3
3
|
import { B as BillableEvent, E as EventKey, I as IntegratorPriceConfig, T as TelemetryEvent, S as SignInOptions, a as Session, P as PaymentAuthorizeOptions, b as PaymentResult, V as ValidationResult, f as fromTemplate, g as getArchetypeTemplate, A as ArchetypeTemplate, F as Federation } from './integrator-C-enR55c.js';
|
|
4
4
|
export { c as ALL_EVENT_SUBTYPES, d as ARCHETYPE_TEMPLATES, e as AgentClassOverride, h as AttestTier, C as ClassASubtype, i as ClassBSubtype, j as ClassCSubtype, k as ComputedFees, D as DropCadence, l as DropClosedWebhookPayload, m as DropResponseBlock, n as DropScheduleSummary, o as EVENT_SUBTYPES, p as EventClass, q as EventSubtype, r as EventSubtypeMetadata, s as FederationStatus, t as IntegratorArchetype, u as IntegratorEventConfig, M as MAX_DROP_WINDOW_DAYS, v as MIN_INTEGRATOR_PRICE_SATS, w as PLATFORM_FEE_POLICY, x as SessionPolicy, y as SigningMethod, z as SiteFeeShape, G as SystemWebhookPayload, W as WebhookHeaders, H as WebhookPayload, J as computeFees, K as subtypesForClass, L as validateIntegratorConfig } from './integrator-C-enR55c.js';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -1037,6 +1037,7 @@ async function defaultLive() {
|
|
|
1037
1037
|
var federations = { list, live, get, defaultLive };
|
|
1038
1038
|
|
|
1039
1039
|
// src/scope.ts
|
|
1040
|
+
var CONSENT_ORIGIN = "https://ochk.app";
|
|
1040
1041
|
var VALID_SCOPES = [
|
|
1041
1042
|
"bitcoin_address",
|
|
1042
1043
|
"email",
|
|
@@ -1092,7 +1093,7 @@ function request(scopes2, options) {
|
|
|
1092
1093
|
if (typeof window === "undefined") {
|
|
1093
1094
|
throw new Error("oc.scope.request: must be called in a browser environment");
|
|
1094
1095
|
}
|
|
1095
|
-
const origin2 = options.origin ??
|
|
1096
|
+
const origin2 = options.origin ?? CONSENT_ORIGIN;
|
|
1096
1097
|
const url = new URL("/me/scope-grant", origin2);
|
|
1097
1098
|
url.searchParams.set("project_key", options.project_key);
|
|
1098
1099
|
url.searchParams.set("scopes", scopes2.join(","));
|
|
@@ -1234,33 +1235,85 @@ async function verifyEd255192(key, sig, msg) {
|
|
|
1234
1235
|
return false;
|
|
1235
1236
|
}
|
|
1236
1237
|
}
|
|
1238
|
+
var SIGNED_FIELDS = [
|
|
1239
|
+
"v",
|
|
1240
|
+
"kind",
|
|
1241
|
+
"did_oc",
|
|
1242
|
+
"event_count",
|
|
1243
|
+
"human_event_count",
|
|
1244
|
+
"lifetime_sats",
|
|
1245
|
+
"distinct_integrator_count",
|
|
1246
|
+
"oldest_event_at",
|
|
1247
|
+
"active_days",
|
|
1248
|
+
"computed_at",
|
|
1249
|
+
"expires_at"
|
|
1250
|
+
];
|
|
1251
|
+
var COUNTS = [
|
|
1252
|
+
"event_count",
|
|
1253
|
+
"human_event_count",
|
|
1254
|
+
"lifetime_sats",
|
|
1255
|
+
"distinct_integrator_count",
|
|
1256
|
+
"active_days"
|
|
1257
|
+
];
|
|
1258
|
+
function readSignedAttestation(canonical, id) {
|
|
1259
|
+
const text = new TextDecoder().decode(canonical);
|
|
1260
|
+
let parsed;
|
|
1261
|
+
try {
|
|
1262
|
+
parsed = JSON.parse(text);
|
|
1263
|
+
} catch {
|
|
1264
|
+
return null;
|
|
1265
|
+
}
|
|
1266
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
1267
|
+
const o = parsed;
|
|
1268
|
+
if (o.v !== 1 || o.kind !== "oc-me-activity" || typeof o.did_oc !== "string") return null;
|
|
1269
|
+
const countsOk = COUNTS.every((k) => {
|
|
1270
|
+
const n = o[k];
|
|
1271
|
+
return typeof n === "number" && Number.isSafeInteger(n) && n >= 0;
|
|
1272
|
+
});
|
|
1273
|
+
if (!countsOk) return null;
|
|
1274
|
+
if (o.oldest_event_at !== null && typeof o.oldest_event_at !== "string") return null;
|
|
1275
|
+
if (typeof o.computed_at !== "string" || typeof o.expires_at !== "string") return null;
|
|
1276
|
+
const ordered = Object.fromEntries(SIGNED_FIELDS.map((k) => [k, o[k]]));
|
|
1277
|
+
if (JSON.stringify(ordered) !== text) return null;
|
|
1278
|
+
return { id, ...ordered };
|
|
1279
|
+
}
|
|
1280
|
+
function sameAttestation(copy, signed) {
|
|
1281
|
+
const c = copy;
|
|
1282
|
+
const v = signed;
|
|
1283
|
+
return ["id", ...SIGNED_FIELDS].every((k) => c[k] === v[k]);
|
|
1284
|
+
}
|
|
1237
1285
|
async function verifyActivityAttestation(bundle, options = {}) {
|
|
1238
1286
|
const checks = [];
|
|
1239
|
-
const shapeOk = !!bundle && typeof bundle === "object" && typeof bundle.sig === "string" && typeof bundle.kid === "string" && typeof bundle.canonical_b64 === "string" &&
|
|
1287
|
+
const shapeOk = !!bundle && typeof bundle === "object" && typeof bundle.sig === "string" && typeof bundle.kid === "string" && typeof bundle.canonical_b64 === "string" && (bundle.attestation === void 0 || !!bundle.attestation && typeof bundle.attestation === "object");
|
|
1240
1288
|
checks.push({
|
|
1241
1289
|
ok: shapeOk,
|
|
1242
|
-
label: "bundle shape \xB7 sig / kid / canonical_b64
|
|
1290
|
+
label: "bundle shape \xB7 sig / kid / canonical_b64"
|
|
1243
1291
|
});
|
|
1244
1292
|
if (!shapeOk) {
|
|
1245
1293
|
return { ok: false, reason: "bundle shape invalid", checks };
|
|
1246
1294
|
}
|
|
1247
|
-
const a = bundle.attestation;
|
|
1248
1295
|
const canonical = base64ToBytes(bundle.canonical_b64);
|
|
1249
1296
|
checks.push({
|
|
1250
1297
|
ok: canonical !== null,
|
|
1251
1298
|
label: "canonical_b64 decodes",
|
|
1252
1299
|
detail: canonical ? `${canonical.length} bytes` : "invalid base64"
|
|
1253
1300
|
});
|
|
1254
|
-
if (!canonical) return { ok: false, reason: "canonical_b64 invalid base64", checks
|
|
1255
|
-
const
|
|
1256
|
-
const
|
|
1257
|
-
|
|
1301
|
+
if (!canonical) return { ok: false, reason: "canonical_b64 invalid base64", checks };
|
|
1302
|
+
const computedId = bytesToHex(await sha256(canonical));
|
|
1303
|
+
const signed = readSignedAttestation(canonical, computedId);
|
|
1304
|
+
checks.push({
|
|
1305
|
+
ok: signed !== null,
|
|
1306
|
+
label: "canonical_bytes are an oc-me-activity attestation in canonical form"
|
|
1307
|
+
});
|
|
1308
|
+
if (!signed) return { ok: false, reason: "canonical bytes are not an activity attestation", checks };
|
|
1309
|
+
const copy = bundle.attestation;
|
|
1310
|
+
const copyOk = copy === void 0 || sameAttestation(copy, signed);
|
|
1258
1311
|
checks.push({
|
|
1259
|
-
ok:
|
|
1260
|
-
label: "sha256(canonical_bytes)
|
|
1261
|
-
detail:
|
|
1312
|
+
ok: copyOk,
|
|
1313
|
+
label: "attestation === the signed bytes, id = sha256(canonical_bytes)",
|
|
1314
|
+
detail: copyOk ? computedId : "the readable copy differs from what was signed"
|
|
1262
1315
|
});
|
|
1263
|
-
if (!
|
|
1316
|
+
if (!copyOk) return { ok: false, reason: "attestation does not match the signed bytes", checks };
|
|
1264
1317
|
let key = null;
|
|
1265
1318
|
if (options.jwk) {
|
|
1266
1319
|
if (options.jwk.kid !== bundle.kid) {
|
|
@@ -1269,7 +1322,7 @@ async function verifyActivityAttestation(bundle, options = {}) {
|
|
|
1269
1322
|
label: "JWK with matching kid present",
|
|
1270
1323
|
detail: `provided jwk.kid=${options.jwk.kid} but bundle.kid=${bundle.kid}`
|
|
1271
1324
|
});
|
|
1272
|
-
return { ok: false, reason: "kid mismatch with provided jwk", checks
|
|
1325
|
+
return { ok: false, reason: "kid mismatch with provided jwk", checks };
|
|
1273
1326
|
}
|
|
1274
1327
|
try {
|
|
1275
1328
|
key = await importJWK(options.jwk, "EdDSA");
|
|
@@ -1280,7 +1333,7 @@ async function verifyActivityAttestation(bundle, options = {}) {
|
|
|
1280
1333
|
label: "JWK with matching kid present",
|
|
1281
1334
|
detail: `provided jwk failed import: ${err.message}`
|
|
1282
1335
|
});
|
|
1283
|
-
return { ok: false, reason: "provided jwk failed import", checks
|
|
1336
|
+
return { ok: false, reason: "provided jwk failed import", checks };
|
|
1284
1337
|
}
|
|
1285
1338
|
} else {
|
|
1286
1339
|
const issuer = options.issuer ?? DEFAULT_ISSUER2;
|
|
@@ -1299,7 +1352,7 @@ async function verifyActivityAttestation(bundle, options = {}) {
|
|
|
1299
1352
|
detail: key ? `kid ${bundle.kid}` : `no JWK with kid ${bundle.kid} at ${issuer}${ENVELOPE_JWKS_PATH}`
|
|
1300
1353
|
});
|
|
1301
1354
|
if (!key) {
|
|
1302
|
-
return { ok: false, reason: `kid ${bundle.kid} not in envelope JWKS`, checks
|
|
1355
|
+
return { ok: false, reason: `kid ${bundle.kid} not in envelope JWKS`, checks };
|
|
1303
1356
|
}
|
|
1304
1357
|
} catch (err) {
|
|
1305
1358
|
checks.push({
|
|
@@ -1310,8 +1363,7 @@ async function verifyActivityAttestation(bundle, options = {}) {
|
|
|
1310
1363
|
return {
|
|
1311
1364
|
ok: false,
|
|
1312
1365
|
reason: `envelope JWKS unavailable: ${err.message}`,
|
|
1313
|
-
checks
|
|
1314
|
-
attestation: a
|
|
1366
|
+
checks
|
|
1315
1367
|
};
|
|
1316
1368
|
}
|
|
1317
1369
|
}
|
|
@@ -1322,7 +1374,7 @@ async function verifyActivityAttestation(bundle, options = {}) {
|
|
|
1322
1374
|
label: "ed25519.verify(sig, canonical_bytes, jwk.public)",
|
|
1323
1375
|
detail: "malformed sig (expected hex)"
|
|
1324
1376
|
});
|
|
1325
|
-
return { ok: false, reason: "malformed sig", checks
|
|
1377
|
+
return { ok: false, reason: "malformed sig", checks };
|
|
1326
1378
|
}
|
|
1327
1379
|
const sigOk = await verifyEd255192(key, sigBytes, canonical);
|
|
1328
1380
|
checks.push({
|
|
@@ -1330,17 +1382,17 @@ async function verifyActivityAttestation(bundle, options = {}) {
|
|
|
1330
1382
|
label: "ed25519.verify(sig, canonical_bytes, jwk.public)",
|
|
1331
1383
|
detail: sigOk ? "signature valid" : "signature does not match"
|
|
1332
1384
|
});
|
|
1333
|
-
if (!sigOk) return { ok: false, reason: "signature does not match", checks
|
|
1385
|
+
if (!sigOk) return { ok: false, reason: "signature does not match", checks };
|
|
1334
1386
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
1335
|
-
const expiresMs = Date.parse(
|
|
1387
|
+
const expiresMs = Date.parse(signed.expires_at);
|
|
1336
1388
|
const freshOk = Number.isFinite(expiresMs) && expiresMs > now.getTime();
|
|
1337
1389
|
checks.push({
|
|
1338
1390
|
ok: freshOk,
|
|
1339
1391
|
label: "now < attestation.expires_at",
|
|
1340
1392
|
detail: freshOk ? `expires ${new Date(expiresMs).toISOString()}` : "attestation has expired"
|
|
1341
1393
|
});
|
|
1342
|
-
if (!freshOk) return { ok: false, reason: "attestation has expired", checks
|
|
1343
|
-
return { ok: true, attestation:
|
|
1394
|
+
if (!freshOk) return { ok: false, reason: "attestation has expired", checks };
|
|
1395
|
+
return { ok: true, attestation: signed, checks };
|
|
1344
1396
|
}
|
|
1345
1397
|
async function refreshEnvelopeJwks(issuer = DEFAULT_ISSUER2) {
|
|
1346
1398
|
jwksCache2.delete(issuer);
|