@private.me/xbind 3.0.1 → 3.0.3
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 +2419 -216
- package/README.md.backup +2121 -0
- package/dist-standalone/_deps/shared/cjs/errors.js +1 -1
- package/dist-standalone/_deps/shared/cjs/index.js +1 -1
- package/dist-standalone/_deps/shared/cjs/types.js +1 -1
- package/dist-standalone/_deps/shared/errors.js +1 -1
- package/dist-standalone/_deps/shared/index.js +1 -1
- package/dist-standalone/_deps/shared/types.js +1 -1
- package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
- package/dist-standalone/_deps/xchange/errors.js +1 -1
- package/dist-standalone/_deps/xchange/index.js +1 -1
- package/dist-standalone/_deps/xchange/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/xchange.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
- package/dist-standalone/_deps/xregistry/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/index.js +1 -1
- package/dist-standalone/_deps/xregistry/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/types.js +1 -1
- package/dist-standalone/agent-call.d.ts +2 -2
- package/dist-standalone/agent-call.js +1 -1
- package/dist-standalone/agent.d.ts +2 -0
- package/dist-standalone/agent.js +1 -1
- package/dist-standalone/async-iterators.d.ts +3 -3
- package/dist-standalone/backup.js +1 -1
- package/dist-standalone/cjs/agent-call.js +1 -1
- package/dist-standalone/cjs/agent.js +1 -1
- package/dist-standalone/cjs/backup.js +1 -1
- package/dist-standalone/cjs/cli/init.js +1 -1
- package/dist-standalone/cjs/connection-pool.js +1 -1
- package/dist-standalone/cjs/crypto-utils.js +1 -1
- package/dist-standalone/cjs/debug-mode.js +1 -1
- package/dist-standalone/cjs/email-transport.js +1 -1
- package/dist-standalone/cjs/errors.js +1 -1
- package/dist-standalone/cjs/http-compat.js +1 -1
- package/dist-standalone/cjs/index.js +1 -1
- package/dist-standalone/cjs/lazy-init.js +1 -1
- package/dist-standalone/cjs/loopback-transport.js +1 -0
- package/dist-standalone/cjs/mdns-discovery.js +1 -1
- package/dist-standalone/cjs/plugins/logging.js +1 -1
- package/dist-standalone/cjs/runtime/edge.js +1 -1
- package/dist-standalone/cjs/security-policy.js +1 -1
- package/dist-standalone/cjs/serialization.js +1 -1
- package/dist-standalone/cjs/transport.js +1 -1
- package/dist-standalone/cjs/trust-registry.js +1 -1
- package/dist-standalone/cjs/vault-store-loader.js +1 -1
- package/dist-standalone/cjs/version-info.js +1 -1
- package/dist-standalone/cjs/xfetch.js +1 -1
- package/dist-standalone/cli/init.js +1 -1
- package/dist-standalone/cli/setup.js +1 -1
- package/dist-standalone/cli/xbind.js +1 -1
- package/dist-standalone/connection-pool.js +1 -1
- package/dist-standalone/crypto-utils.d.ts +2 -7
- package/dist-standalone/crypto-utils.js +1 -1
- package/dist-standalone/debug-mode.js +1 -1
- package/dist-standalone/email-transport.d.ts +2 -2
- package/dist-standalone/email-transport.js +1 -1
- package/dist-standalone/errors.d.ts +13 -3
- package/dist-standalone/errors.js +1 -1
- package/dist-standalone/gateway-state.d.ts +1 -1
- package/dist-standalone/health-check.d.ts +5 -1
- package/dist-standalone/http-compat.d.ts +1 -1
- package/dist-standalone/http-compat.js +1 -1
- package/dist-standalone/index.d.ts +15 -4
- package/dist-standalone/index.js +1 -1
- package/dist-standalone/lazy-init.d.ts +11 -6
- package/dist-standalone/lazy-init.js +1 -1
- package/dist-standalone/loopback-transport.d.ts +87 -0
- package/dist-standalone/loopback-transport.js +1 -0
- package/dist-standalone/mdns-discovery.js +1 -1
- package/dist-standalone/plugins/logging.js +1 -1
- package/dist-standalone/plugins/metrics.d.ts +4 -4
- package/dist-standalone/runtime/edge.js +1 -1
- package/dist-standalone/runtime/react-native.d.ts +1 -1
- package/dist-standalone/security-policy.js +1 -1
- package/dist-standalone/serialization.js +1 -1
- package/dist-standalone/transport.js +1 -1
- package/dist-standalone/trust-registry.d.ts +3 -3
- package/dist-standalone/trust-registry.js +1 -1
- package/dist-standalone/vault-store-loader.d.ts +9 -0
- package/dist-standalone/vault-store-loader.js +1 -1
- package/dist-standalone/version-info.js +1 -1
- package/dist-standalone/xfetch.js +1 -1
- package/package.json +4 -13
- package/share1.dat +0 -0
- package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
- package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
- package/dist-standalone/_deps/shared/cjs/package.json +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
- package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
- package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
- package/dist-standalone/cjs/package.json +0 -3
- package/dist-standalone/package.json +0 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Capability=void 0,exports.getVersion=getVersion,exports.hasCapability=hasCapability,exports.getCapabilities=getCapabilities,exports.getDeprecationInfo=getDeprecationInfo,exports.warnIfDeprecated=warnIfDeprecated,exports.parseVersion=parseVersion,exports.compareVersions=compareVersions,exports.checkCompatibility=checkCompatibility,exports.getMinimumVersionFor=getMinimumVersionFor,exports.assertMinimumVersion=assertMinimumVersion;const logger_js_1=require("./logger.js"),logger=(0,logger_js_1.createLogger)("version-info");var Capability;!function(e){e.ENVELOPE_V1="envelope-v1",e.ENVELOPE_V2="envelope-v2",e.ENVELOPE_V3="envelope-v3",e.ENVELOPE_V4="envelope-v4",e.ML_KEM_768="ml-kem-768",e.ML_DSA_65="ml-dsa-65",e.X25519_ECDH="x25519-ecdh",e.ED25519_SIG="ed25519-sig",e.XORIDA="xorida",e.SPLIT_CHANNEL="split-channel",e.TRUST_REGISTRY="trust-registry",e.SERVICE_DISCOVERY="service-discovery",e.INVITE_SYSTEM="invite-system",e.AGENT_CALL="agent-call",e.XFETCH="xfetch",e.DUAL_MODE="dual-mode",e.BACKUP_RESTORE="backup-restore",e.CORRELATION_ID="correlation-id",e.STRUCTURED_LOGGING="structured-logging",e.DID_SUCCESSION="did-succession",e.GATEWAY_STATE="gateway-state",e.SUBSCRIPTION_PROOF="subscription-proof",e.POLICY_ENGINE="policy-engine",e.APPROVAL_FLOW="approval-flow",e.GUARDRAILS="guardrails",e.HTTP_COMPAT="http-compat",e.DID_WEB="did-web",e.DID_PRIVATEME="did:privateme",e.REDIS_NONCE="redis-nonce",e.RETRY_TRANSPORT="retry-transport"}(Capability||(exports.Capability=Capability={}));const VERSION_METADATA={semver:"3.0.
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Capability=void 0,exports.getVersion=getVersion,exports.hasCapability=hasCapability,exports.getCapabilities=getCapabilities,exports.getDeprecationInfo=getDeprecationInfo,exports.warnIfDeprecated=warnIfDeprecated,exports.parseVersion=parseVersion,exports.compareVersions=compareVersions,exports.checkCompatibility=checkCompatibility,exports.getMinimumVersionFor=getMinimumVersionFor,exports.assertMinimumVersion=assertMinimumVersion;const logger_js_1=require("./logger.js"),logger=(0,logger_js_1.createLogger)("version-info");var Capability;!function(e){e.ENVELOPE_V1="envelope-v1",e.ENVELOPE_V2="envelope-v2",e.ENVELOPE_V3="envelope-v3",e.ENVELOPE_V4="envelope-v4",e.ML_KEM_768="ml-kem-768",e.ML_DSA_65="ml-dsa-65",e.X25519_ECDH="x25519-ecdh",e.ED25519_SIG="ed25519-sig",e.XORIDA="xorida",e.SPLIT_CHANNEL="split-channel",e.TRUST_REGISTRY="trust-registry",e.SERVICE_DISCOVERY="service-discovery",e.INVITE_SYSTEM="invite-system",e.AGENT_CALL="agent-call",e.XFETCH="xfetch",e.DUAL_MODE="dual-mode",e.BACKUP_RESTORE="backup-restore",e.CORRELATION_ID="correlation-id",e.STRUCTURED_LOGGING="structured-logging",e.DID_SUCCESSION="did-succession",e.GATEWAY_STATE="gateway-state",e.SUBSCRIPTION_PROOF="subscription-proof",e.POLICY_ENGINE="policy-engine",e.APPROVAL_FLOW="approval-flow",e.GUARDRAILS="guardrails",e.HTTP_COMPAT="http-compat",e.DID_WEB="did-web",e.DID_PRIVATEME="did:privateme",e.REDIS_NONCE="redis-nonce",e.RETRY_TRANSPORT="retry-transport"}(Capability||(exports.Capability=Capability={}));const VERSION_METADATA={semver:"3.0.3",major:3,minor:0,patch:3,prerelease:void 0,build:void 0,features:[Capability.ENVELOPE_V1,Capability.ENVELOPE_V2,Capability.ENVELOPE_V3,Capability.ENVELOPE_V4,Capability.ML_KEM_768,Capability.ML_DSA_65,Capability.X25519_ECDH,Capability.ED25519_SIG,Capability.XORIDA,Capability.SPLIT_CHANNEL,Capability.TRUST_REGISTRY,Capability.SERVICE_DISCOVERY,Capability.INVITE_SYSTEM,Capability.AGENT_CALL,Capability.XFETCH,Capability.DUAL_MODE,Capability.BACKUP_RESTORE,Capability.CORRELATION_ID,Capability.STRUCTURED_LOGGING,Capability.DID_SUCCESSION,Capability.GATEWAY_STATE,Capability.SUBSCRIPTION_PROOF,Capability.POLICY_ENGINE,Capability.APPROVAL_FLOW,Capability.GUARDRAILS,Capability.HTTP_COMPAT,Capability.DID_WEB,Capability.DID_PRIVATEME,Capability.REDIS_NONCE,Capability.RETRY_TRANSPORT],deprecated:[{name:"envelope-v1",since:"1.2.0",removedIn:"2.0.0",migration:"Use createEnvelopeV2() or higher for split-channel support",docs:"https://private.me/docs/xbind/migration-v2"}],buildDate:(new Date).toISOString(),nodeVersion:process.version};function getVersion(){return Object.freeze({...VERSION_METADATA})}function hasCapability(e){return VERSION_METADATA.features.includes(e)}function getCapabilities(){return Object.freeze([...VERSION_METADATA.features])}function getDeprecationInfo(e){return VERSION_METADATA.deprecated.find(i=>i.name===e)}const warnedFeatures=new Set;function warnIfDeprecated(e){if(warnedFeatures.has(e))return;const i=getDeprecationInfo(e);if(!i)return;warnedFeatures.add(e);const r=[`Feature "${e}" is deprecated since v${i.since}`,i.removedIn?`and will be removed in v${i.removedIn}.`:".",i.migration].join(" ");logger.warn(r,{feature:e,deprecatedSince:i.since,removedIn:i.removedIn,docs:i.docs}),"undefined"!=typeof console&&console.warn&&(console.warn(`[xBind] ${r}`),i.docs&&console.warn(`[xBind] See: ${i.docs}`))}function parseVersion(e){const i=e.match(/^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/);if(!(i&&i[1]&&i[2]&&i[3]))throw new Error(`Invalid semantic version: ${e}`);return{major:parseInt(i[1],10),minor:parseInt(i[2],10),patch:parseInt(i[3],10),prerelease:i[4]||void 0,build:i[5]||void 0}}function compareVersions(e,i){const r=parseVersion(e),a=parseVersion(i);if(r.major<a.major)return-1;if(r.major>a.major)return 1;if(r.minor<a.minor)return-1;if(r.minor>a.minor)return 1;if(r.patch<a.patch)return-1;if(r.patch>a.patch)return 1;if(r.prerelease&&!a.prerelease)return-1;if(!r.prerelease&&a.prerelease)return 1;if(r.prerelease&&a.prerelease){if(r.prerelease<a.prerelease)return-1;if(r.prerelease>a.prerelease)return 1}return 0}function checkCompatibility(e){const i=VERSION_METADATA.semver;if(e.startsWith("^")){const r=e.slice(1),a=parseVersion(r);return parseVersion(i).major!==a.major?{compatible:!1,message:`Incompatible major version. Required: ^${r}, Current: ${i}`,severity:"error",required:e,actual:i}:compareVersions(i,r)<0?{compatible:!1,message:`SDK version too old. Required: ^${r}, Current: ${i}`,severity:"error",required:e,actual:i}:{compatible:!0,message:`Compatible (${i} satisfies ^${r})`,severity:"info",required:e,actual:i}}if(e.startsWith("~")){const r=e.slice(1),a=parseVersion(r),t=parseVersion(i);return t.major!==a.major||t.minor!==a.minor?{compatible:!1,message:`Incompatible version. Required: ~${r}, Current: ${i}`,severity:"error",required:e,actual:i}:compareVersions(i,r)<0?{compatible:!1,message:`SDK version too old. Required: ~${r}, Current: ${i}`,severity:"error",required:e,actual:i}:{compatible:!0,message:`Compatible (${i} satisfies ~${r})`,severity:"info",required:e,actual:i}}let r,a,t;try{r=compareVersions(i,e)}catch{return{compatible:!1,message:`Invalid version format: ${e}`,severity:"error",required:e,actual:i}}if(0===r)return{compatible:!0,message:`Exact version match (${i})`,severity:"info",required:e,actual:i};if(r<0)return{compatible:!1,message:`SDK version too old. Required: ${e}, Current: ${i}`,severity:"error",required:e,actual:i};try{a=parseVersion(e),t=parseVersion(i)}catch{return{compatible:!0,message:`Compatible (${i} is newer than ${e})`,severity:"info",required:e,actual:i}}return t.major>a.major?{compatible:!1,message:`Breaking changes in SDK. Required: ${e}, Current: ${i}`,severity:"warning",required:e,actual:i}:{compatible:!0,message:`Compatible (${i} is newer than ${e})`,severity:"info",required:e,actual:i}}function getMinimumVersionFor(e){return{[Capability.ENVELOPE_V1]:"1.0.0",[Capability.ENVELOPE_V2]:"1.1.0",[Capability.ENVELOPE_V3]:"1.2.0",[Capability.ENVELOPE_V4]:"1.3.0",[Capability.ML_KEM_768]:"1.2.0",[Capability.ML_DSA_65]:"1.3.0",[Capability.X25519_ECDH]:"1.0.0",[Capability.ED25519_SIG]:"1.0.0",[Capability.XORIDA]:"1.0.0",[Capability.SPLIT_CHANNEL]:"1.1.0",[Capability.TRUST_REGISTRY]:"1.0.0",[Capability.SERVICE_DISCOVERY]:"1.1.0",[Capability.INVITE_SYSTEM]:"1.1.0",[Capability.AGENT_CALL]:"1.0.0",[Capability.XFETCH]:"1.2.0",[Capability.DUAL_MODE]:"1.2.0",[Capability.BACKUP_RESTORE]:"1.3.0",[Capability.CORRELATION_ID]:"1.3.0",[Capability.STRUCTURED_LOGGING]:"1.3.0",[Capability.DID_SUCCESSION]:"1.2.0",[Capability.GATEWAY_STATE]:"1.2.0",[Capability.SUBSCRIPTION_PROOF]:"1.2.0",[Capability.POLICY_ENGINE]:"1.1.0",[Capability.APPROVAL_FLOW]:"1.1.0",[Capability.GUARDRAILS]:"1.2.0",[Capability.HTTP_COMPAT]:"1.2.0",[Capability.DID_WEB]:"1.1.0",[Capability.DID_PRIVATEME]:"1.2.0",[Capability.REDIS_NONCE]:"1.1.0",[Capability.RETRY_TRANSPORT]:"1.1.0"}[e]}function assertMinimumVersion(e,i){const r=checkCompatibility(e);if(!r.compatible&&"error"===r.severity){const a=i?`${i} requires xBind >= ${e} (current: ${VERSION_METADATA.semver})`:r.message;throw new Error(a)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.xfetch=xfetch,exports.isXBindSupported=isXBindSupported,exports.getXBindCapability=getXBindCapability;const agent_js_1=require("./agent.js"),agent_call_js_1=require("./agent-call.js");async function checkXBindSupport(t){try{const e=await fetch(t,{method:"OPTIONS",headers:{"X-Capability-Check":"xbind"}});return"true"===e.headers.get("X-xBind-Support")?{supported:!0,endpoint:e.headers.get("X-xBind-Endpoint")||void 0,peerDID:e.headers.get("X-xBind-DID")||void 0,version:e.headers.get("X-xBind-Version")||void 0}:{supported:!1}}catch
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.xfetch=xfetch,exports.isXBindSupported=isXBindSupported,exports.getXBindCapability=getXBindCapability;const agent_js_1=require("./agent.js"),agent_call_js_1=require("./agent-call.js");async function checkXBindSupport(t){try{const e=await fetch(t,{method:"OPTIONS",headers:{"X-Capability-Check":"xbind"}});return"true"===e.headers.get("X-xBind-Support")?{supported:!0,endpoint:e.headers.get("X-xBind-Endpoint")||void 0,peerDID:e.headers.get("X-xBind-DID")||void 0,version:e.headers.get("X-xBind-Version")||void 0}:{supported:!1}}catch{return{supported:!1}}}async function sendViaXBind(t,e,r,n){const o=Date.now();if(!e.peerDID)throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,"Server supports xBind but did not provide X-xBind-DID header",{url:t,capability:e});const a=e.peerDID,i=e.endpoint||t,s=new Uint8Array(16);crypto.getRandomValues(s);const c=Array.from(s).map(t=>t.toString(16).padStart(2,"0")).join(""),d=`xfetch_${Date.now()}_${c}`,l={correlationId:d,method:r.method||"GET",url:t,headers:r.headers||{},body:r.body?"string"==typeof r.body?r.body:JSON.stringify(r.body):void 0};return new Promise((e,s)=>{const c=setTimeout(()=>{s(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.TIMEOUT,"xBind request timed out waiting for response",{url:t,correlationId:d,timeout:r.timeout||3e4}))},r.timeout||3e4);(async()=>{try{const p=await n.send({to:a,payload:l,scope:"xfetch",action:"http_request"});if(!p.ok)return clearTimeout(c),void s(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,`Failed to send xBind request: ${p.error}`,{url:t,error:p.error}));const u=`${i}/response/${d}`,_=100,g=(r.timeout||3e4)/_;for(let t=0;t<g;t++){await new Promise(t=>setTimeout(t,_));try{const t=await fetch(u);if(200===t.status){clearTimeout(c);const r=Date.now()-o;return void e(Object.assign(t,{usedXBind:!0,transport:{protocol:"xbind",latency:r,peerDID:a}}))}}catch{continue}}clearTimeout(c),s(new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.TIMEOUT,"Response not available after polling",{url:t,correlationId:d,polls:g}))}catch(e){clearTimeout(c),s(e instanceof agent_call_js_1.AgentError?e:new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,"xBind request failed",{url:t,error:String(e)}))}})()})}async function sendViaHTTP(t,e){const r=Date.now(),{forceXBind:n,disableXBind:o,agent:a,retry:i,...s}=e,c=await fetch(t,s),d=Date.now()-r;return Object.assign(c,{usedXBind:!1,transport:{protocol:t.startsWith("https")?"https":"http",latency:d}})}async function withRetry(t,e){const r=e?.maxAttempts??3,n=e?.initialDelay??1e3,o=e?.multiplier??2;let a,i=n;for(let e=1;e<=r;e++)try{return await t()}catch(t){if(a=t instanceof Error?t:new Error(String(t)),t instanceof Response&&t.status>=400&&t.status<500)throw t;e<r&&(await new Promise(t=>setTimeout(t,i)),i*=o)}throw a}async function xfetch(t,e={}){let r;try{r=new URL(t)}catch(e){throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.INVALID_PARAMS,`Invalid URL: ${t}`,{url:t,error:e})}if(!["http:","https:"].includes(r.protocol))throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.INVALID_PARAMS,`Unsupported protocol: ${r.protocol}`,{url:t,protocol:r.protocol});const n=e.timeout??3e4,o=new AbortController,a=setTimeout(()=>o.abort(),n);try{const r=e.signal?AbortSignal.any?.([e.signal,o.signal])??o.signal:o.signal,n={...e,signal:r};if(e.disableXBind)return await withRetry(()=>sendViaHTTP(t,n),e.retry);const a=await checkXBindSupport(t);if(e.forceXBind&&!a.supported)throw new agent_call_js_1.AgentError(agent_call_js_1.AgentErrorCode.NETWORK_ERROR,`xBind required but endpoint does not support it: ${t}`,{url:t,forceXBind:!0,capability:a});if(a.supported){const r=e.agent??await agent_js_1.Agent.from({identity:"ephemeral",identityTTL:36e5});return await withRetry(()=>sendViaXBind(t,a,n,r),e.retry)}return await withRetry(()=>sendViaHTTP(t,n),e.retry)}finally{clearTimeout(a)}}async function isXBindSupported(t){return(await checkXBindSupport(t)).supported}async function getXBindCapability(t){return checkXBindSupport(t)}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{parseArgs}from"node:util";import*as fs from"node:fs";import*as path from"node:path";import{spawn}from"node:child_process";import*as readline from"node:readline/promises";import{stdin as input,stdout as output}from"node:process";import{InviteService}from"../invite.js";function getTemplateDir(){let e=__dirname;for(;"/"!==e;){if(fs.existsSync(path.join(e,"package.json")))return path.join(e,"templates");e=path.dirname(e)}return path.join(__dirname,"../../templates")}const TEMPLATES={"node-typescript":{name:"Node.js + TypeScript",description:"Node.js with TypeScript, best for backend services",packageManager:"npm",entryPoint:"src/index.ts",startCommand:"npm run dev"},"node-javascript":{name:"Node.js + JavaScript",description:"Node.js with JavaScript, minimal setup",packageManager:"npm",entryPoint:"src/index.js",startCommand:"npm start"},deno:{name:"Deno",description:"Modern TypeScript runtime",packageManager:"deno",entryPoint:"mod.ts",startCommand:"deno run --allow-net --allow-env --allow-read mod.ts"},"cloudflare-worker":{name:"Cloudflare Worker",description:"Edge runtime on Cloudflare",packageManager:"npm",entryPoint:"src/index.ts",startCommand:"npm run dev"},"vercel-function":{name:"Vercel Function",description:"Serverless function on Vercel",packageManager:"npm",entryPoint:"api/xbind.ts",startCommand:"npm run dev"}};class Spinner{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];currentFrame=0;intervalId;message;constructor(e){this.message=e}start(){this.intervalId=setInterval(()=>{const e=this.frames[this.currentFrame];process.stdout.write(`\r${e} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed(e){this.stop(),process.stdout.write(`\r✅ ${e??this.message}\n`)}fail(e){this.stop(),process.stdout.write(`\r❌ ${e??this.message}\n`)}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}}function normalizeInviteUrl(e,t){return e.startsWith("http://")||e.startsWith("https://")?e:(e.startsWith("XBD-"),`${t}/invite/${e}`)}function isValidProjectName(e){return/^[a-z0-9-_]+$/i.test(e)&&e.length>0&&e.length<=100}async function prompt(e,t){const n=readline.createInterface({input:input,output:output}),r=await n.question(t?`${e} (${t}): `:`${e}: `);return n.close(),r.trim()||t||""}async function select(e,t,n=0){console.log(e),t.forEach((e,t)=>{const r=t===n?"→":" ";console.log(` ${r} ${t+1}. ${e.label} - ${e.description}`)});const r=readline.createInterface({input:input,output:output}),i=await r.question(`Select (1-${t.length}): `);r.close();const o=parseInt(i.trim(),10)-1;return o>=0&&o<t.length?t[o]?.value??t[n]?.value??"":t[n]?.value??""}function runCommand(e,t,n){return new Promise((r,i)=>{const o=spawn(e,t,{cwd:n,stdio:"ignore",shell:!0});o.on("close",e=>{0===e?r():i(new Error(`Command failed with code ${e??"unknown"}`))}),o.on("error",i)})}async function copyTemplate(e,t,n){const r=path.join(getTemplateDir(),e),i=await fs.promises.readdir(r,{recursive:!0,withFileTypes:!0});for(const e of i)if(e.isFile()){const i=e.parentPath||e.path||r,o=path.relative(r,path.join(i,e.name)),s=path.join(r,o),a=path.join(t,o);await fs.promises.mkdir(path.dirname(a),{recursive:!0});let c=await fs.promises.readFile(s,"utf-8");n&&(c=c.replace(/{{INVITE_URL}}/g,n.url),c=c.replace(/{{INVITE_ID}}/g,n.id),c=c.replace(/{{SERVICE_NAME}}/g,n.from.name),c=c.replace(/{{SERVICE_DID}}/g,n.from.did),c=c.replace(/{{SERVICE_ENDPOINT}}/g,n.from.endpoint)),await fs.promises.writeFile(a,c,"utf-8")}}async function installDependencies(e,t){"npm"===t&&await runCommand("npm",["install"],e)}export async function initCommand(e={}){const t=e.registryUrl||"https://xbind.to";let n,r;if(e.invite){r=normalizeInviteUrl(e.invite,t);const i=new Spinner("Fetching invite details...");i.start();try{const e=new InviteService({inviteApiUrl:t}),o=await e.get(r);if(!o.ok)return i.fail(`Failed to fetch invite: ${o.error.message}`),o.error.hint&&console.error(`Hint: ${o.error.hint}`),void(process.exitCode=1);if(n=o.value,!n)return i.fail("Invalid invite data received"),void(process.exitCode=1);i.succeed(`Connected to ${n.from.name}`)}catch(e){return i.fail("Failed to fetch invite details"),console.error(e instanceof Error?e.message:String(e)),void(process.exitCode=1)}}let i=e.name,o=e.runtime;if(e.yes)i=i||"my-xbind-app",o=o||"node-typescript";else{if(!i){const e=n?`connect-${n.from.name}`:"my-xbind-app";i=await prompt("Project name",e)}o||(o=await select("\nSelect runtime:",Object.entries(TEMPLATES).map(([e,t])=>({value:e,label:t.name,description:t.description})),0))}if(!isValidProjectName(i))return console.error("❌ Invalid project name. Use only letters, numbers, hyphens, and underscores."),void(process.exitCode=1);const s=path.resolve(process.cwd(),i);if(fs.existsSync(s))return console.error(`❌ Directory "${i}" already exists.`),void(process.exitCode=1);if(!o||!TEMPLATES[o])return console.error("❌ Invalid runtime selection."),void(process.exitCode=1);const a=TEMPLATES[o];console.log(`\n📦 Creating ${a.name} project: ${i}`);const c=new Spinner("Creating project structure...");c.start();try{await fs.promises.mkdir(s,{recursive:!0}),await copyTemplate(o,s,n),c.succeed("Project structure created")}catch(e){return c.fail("Failed to create project structure"),console.error(e instanceof Error?e.message:String(e)),void(process.exitCode=1)}if("none"!==a.packageManager&&"test"!==process.env.NODE_ENV){const e=new Spinner("Installing dependencies...");e.start();try{await installDependencies(s,a.packageManager),e.succeed("Dependencies installed")}catch
|
|
2
|
+
import{parseArgs}from"node:util";import*as fs from"node:fs";import*as path from"node:path";import{spawn}from"node:child_process";import*as readline from"node:readline/promises";import{stdin as input,stdout as output}from"node:process";import{InviteService}from"../invite.js";function getTemplateDir(){let e=__dirname;for(;"/"!==e;){if(fs.existsSync(path.join(e,"package.json")))return path.join(e,"templates");e=path.dirname(e)}return path.join(__dirname,"../../templates")}const TEMPLATES={"node-typescript":{name:"Node.js + TypeScript",description:"Node.js with TypeScript, best for backend services",packageManager:"npm",entryPoint:"src/index.ts",startCommand:"npm run dev"},"node-javascript":{name:"Node.js + JavaScript",description:"Node.js with JavaScript, minimal setup",packageManager:"npm",entryPoint:"src/index.js",startCommand:"npm start"},deno:{name:"Deno",description:"Modern TypeScript runtime",packageManager:"deno",entryPoint:"mod.ts",startCommand:"deno run --allow-net --allow-env --allow-read mod.ts"},"cloudflare-worker":{name:"Cloudflare Worker",description:"Edge runtime on Cloudflare",packageManager:"npm",entryPoint:"src/index.ts",startCommand:"npm run dev"},"vercel-function":{name:"Vercel Function",description:"Serverless function on Vercel",packageManager:"npm",entryPoint:"api/xbind.ts",startCommand:"npm run dev"}};class Spinner{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];currentFrame=0;intervalId;message;constructor(e){this.message=e}start(){this.intervalId=setInterval(()=>{const e=this.frames[this.currentFrame];process.stdout.write(`\r${e} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed(e){this.stop(),process.stdout.write(`\r✅ ${e??this.message}\n`)}fail(e){this.stop(),process.stdout.write(`\r❌ ${e??this.message}\n`)}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}}function normalizeInviteUrl(e,t){return e.startsWith("http://")||e.startsWith("https://")?e:(e.startsWith("XBD-"),`${t}/invite/${e}`)}function isValidProjectName(e){return/^[a-z0-9-_]+$/i.test(e)&&e.length>0&&e.length<=100}async function prompt(e,t){const n=readline.createInterface({input:input,output:output}),r=await n.question(t?`${e} (${t}): `:`${e}: `);return n.close(),r.trim()||t||""}async function select(e,t,n=0){console.log(e),t.forEach((e,t)=>{const r=t===n?"→":" ";console.log(` ${r} ${t+1}. ${e.label} - ${e.description}`)});const r=readline.createInterface({input:input,output:output}),i=await r.question(`Select (1-${t.length}): `);r.close();const o=parseInt(i.trim(),10)-1;return o>=0&&o<t.length?t[o]?.value??t[n]?.value??"":t[n]?.value??""}function runCommand(e,t,n){return new Promise((r,i)=>{const o=spawn(e,t,{cwd:n,stdio:"ignore",shell:!0});o.on("close",e=>{0===e?r():i(new Error(`Command failed with code ${e??"unknown"}`))}),o.on("error",i)})}async function copyTemplate(e,t,n){const r=path.join(getTemplateDir(),e),i=await fs.promises.readdir(r,{recursive:!0,withFileTypes:!0});for(const e of i)if(e.isFile()){const i=e.parentPath||e.path||r,o=path.relative(r,path.join(i,e.name)),s=path.join(r,o),a=path.join(t,o);await fs.promises.mkdir(path.dirname(a),{recursive:!0});let c=await fs.promises.readFile(s,"utf-8");n&&(c=c.replace(/{{INVITE_URL}}/g,n.url),c=c.replace(/{{INVITE_ID}}/g,n.id),c=c.replace(/{{SERVICE_NAME}}/g,n.from.name),c=c.replace(/{{SERVICE_DID}}/g,n.from.did),c=c.replace(/{{SERVICE_ENDPOINT}}/g,n.from.endpoint)),await fs.promises.writeFile(a,c,"utf-8")}}async function installDependencies(e,t){"npm"===t&&await runCommand("npm",["install"],e)}export async function initCommand(e={}){const t=e.registryUrl||"https://xbind.to";let n,r;if(e.invite){r=normalizeInviteUrl(e.invite,t);const i=new Spinner("Fetching invite details...");i.start();try{const e=new InviteService({inviteApiUrl:t}),o=await e.get(r);if(!o.ok)return i.fail(`Failed to fetch invite: ${o.error.message}`),o.error.hint&&console.error(`Hint: ${o.error.hint}`),void(process.exitCode=1);if(n=o.value,!n)return i.fail("Invalid invite data received"),void(process.exitCode=1);i.succeed(`Connected to ${n.from.name}`)}catch(e){return i.fail("Failed to fetch invite details"),console.error(e instanceof Error?e.message:String(e)),void(process.exitCode=1)}}let i=e.name,o=e.runtime;if(e.yes)i=i||"my-xbind-app",o=o||"node-typescript";else{if(!i){const e=n?`connect-${n.from.name}`:"my-xbind-app";i=await prompt("Project name",e)}o||(o=await select("\nSelect runtime:",Object.entries(TEMPLATES).map(([e,t])=>({value:e,label:t.name,description:t.description})),0))}if(!isValidProjectName(i))return console.error("❌ Invalid project name. Use only letters, numbers, hyphens, and underscores."),void(process.exitCode=1);const s=path.resolve(process.cwd(),i);if(fs.existsSync(s))return console.error(`❌ Directory "${i}" already exists.`),void(process.exitCode=1);if(!o||!TEMPLATES[o])return console.error("❌ Invalid runtime selection."),void(process.exitCode=1);const a=TEMPLATES[o];console.log(`\n📦 Creating ${a.name} project: ${i}`);const c=new Spinner("Creating project structure...");c.start();try{await fs.promises.mkdir(s,{recursive:!0}),await copyTemplate(o,s,n),c.succeed("Project structure created")}catch(e){return c.fail("Failed to create project structure"),console.error(e instanceof Error?e.message:String(e)),void(process.exitCode=1)}if("none"!==a.packageManager&&"test"!==process.env.NODE_ENV){const e=new Spinner("Installing dependencies...");e.start();try{await installDependencies(s,a.packageManager),e.succeed("Dependencies installed")}catch{e.fail("Failed to install dependencies"),console.error("You can install them manually later.")}}if(n||r){const e=n?.url||r||"";process.env.DEBUG_CLI&&console.log("[DEBUG] Writing .env file:",{invite:!!n,inviteUrl:r,finalInviteUrl:e,projectPath:s}),e&&await fs.promises.writeFile(path.join(s,".env"),`XBIND_INVITE_CODE=${e}\n`,"utf-8")}else process.env.DEBUG_CLI&&console.log("[DEBUG] Not writing .env file:",{invite:!!n,inviteUrl:r});console.log("\n✅ Ready!\n"),console.log("Next steps:"),console.log(` cd ${i}`),console.log(` ${a.startCommand}`),n?(console.log(`\n🔗 Connected to: ${n.from.name}`),console.log(` DID: ${n.from.did}`)):console.log("\n💡 To connect to a service, get an invite code and update .env file.")}export async function main(e=process.argv.slice(2)){const{values:t}=parseArgs({args:e,options:{invite:{type:"string",short:"i"},name:{type:"string",short:"n"},runtime:{type:"string",short:"r"},yes:{type:"boolean",short:"y"},"registry-url":{type:"string"},help:{type:"boolean",short:"h"}}});t.help?console.log("\nXBind CLI - One-Line M2M Setup\n\nUsage:\n npx xbind-init [options]\n\nOptions:\n -i, --invite <url> Invite URL or code\n -n, --name <name> Project name\n -r, --runtime <runtime> Runtime template (node-typescript, node-javascript, deno, cloudflare-worker, vercel-function)\n -y, --yes Skip interactive prompts (use defaults)\n --registry-url <url> Custom registry URL (default: https://xbind.to)\n -h, --help Show this help message\n\nExamples:\n npx xbind-init --invite https://xbind.to/invite/XBD-abc123\n npx xbind-init --invite XBD-abc123 --name my-app --runtime node-typescript\n npx xbind-init --yes\n ".trim()):await initCommand({invite:t.invite,name:t.name,runtime:t.runtime,yes:t.yes,"registry-url":t["registry-url"]})}const isDirectRun=process.argv[1]?.endsWith("init.ts")||process.argv[1]?.endsWith("init.js");isDirectRun&&main().catch(e=>{console.error("Fatal:",e instanceof Error?e.message:String(e)),process.exitCode=1});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{parseArgs}from"node:util";import*as fs from"node:fs";import*as path from"node:path";import*as os from"node:os";import*as readline from"node:readline/promises";import{stdin as input,stdout as output}from"node:process";import{randomBytes}from"node:crypto";import{ExitCode,Colors}from"./types.js";function getIdentityPath(){return path.join(os.homedir(),".xbind","identity.json")}async function ensureXBindDir(){const e=path.join(os.homedir(),".xbind");try{await fs.promises.mkdir(e,{recursive:!0,mode:448})}catch(e){throw new Error(`Cannot create .xbind directory: ${e.message}`)}}async function identityExists(){try{return await fs.promises.access(getIdentityPath(),fs.constants.F_OK),!0}catch{return!1}}async function readIdentity(){try{const e=await fs.promises.readFile(getIdentityPath(),"utf-8");return JSON.parse(e)}catch{return null}}async function writeIdentity(e){await ensureXBindDir(),await fs.promises.writeFile(getIdentityPath(),JSON.stringify(e,null,2),{mode:384})}class Spinner{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];currentFrame=0;intervalId;message;useColors;constructor(e,t=!0){this.message=e,this.useColors=t&&process.stdout.isTTY}start(){this.intervalId=setInterval(()=>{const e=this.frames[this.currentFrame];process.stdout.write(`\r${e} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed(e){this.stop();const t=this.useColors?`${Colors.GREEN}✅${Colors.RESET}`:"✅";process.stdout.write(`\r${t} ${e??this.message}\n`)}fail(e){this.stop();const t=this.useColors?`${Colors.RED}❌${Colors.RESET}`:"❌";process.stdout.write(`\r${t} ${e??this.message}\n`)}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}}async function prompt(e,t){const o=readline.createInterface({input:input,output:output}),r=await o.question(t?`${e} (${t}): `:`${e}: `);return o.close(),r.trim()||t||""}function isValidEmail(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function isValidServiceName(e){return/^[a-zA-Z][a-zA-Z0-9-]{2,63}$/.test(e)}async function generateDID(){const{generateIdentity:e}=await import("../identity.js"),t=await e();if(!t.ok)throw new Error("Failed to generate identity");const o=t.value,r=new Uint8Array(await crypto.subtle.exportKey("raw",o.publicKey)),n=await crypto.subtle.exportKey("jwk",o.privateKey);if(!n.d)throw new Error("Failed to export private key");const s=Buffer.from(r).toString("base64"),i=n.d;return{did:o.did,publicKey:s,privateKey:i}}function generateDeploymentID(){const e=new Date;return`DEP-${e.getUTCFullYear()}${String(e.getUTCMonth()+1).padStart(2,"0")}-${randomBytes(5).toString("hex").toUpperCase()}`}async function createServerAccount(e,t,o,r){const n=`${r}/auth/signup`;try{const r=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:e,deploymentId:t,email:o,method:"code"})});if(!r.ok){return{success:!1,error:await r.json().catch(()=>({code:"UNKNOWN",message:`Server returned ${r.status}`}))}}return{success:!0,account:(await r.json()).account}}catch(e){return{success:!1,error:{code:"NETWORK_ERROR",message:e instanceof Error?e.message:"Network request failed",hint:"Check that the server is running and accessible"}}}}async function sendVerificationCode(e,t){const o=`${t}/auth/send-verification-code`;try{const t=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e})});if(!t.ok){return{success:!1,error:(await t.json().catch(()=>({message:`HTTP ${t.status}`}))).message}}return{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Network error"}}}async function verifyEmailCode(e,t,o){const r=`${o}/auth/verify-email-code`;try{const o=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,code:t})});if(!o.ok){return{success:!1,error:(await o.json().catch(()=>({message:`HTTP ${o.status}`}))).message}}return{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Network error"}}}function outputSuccess(e,t){const o=t?Colors.GREEN:"",r=t?Colors.GRAY:"",n=t?Colors.BLUE:"",s=t?Colors.RESET:"";console.log(`${o}✅ Identity created successfully${s}\n`),console.log(`Service Name: ${e.name}`),console.log(`DID: ${o}${e.did}${s}`),console.log(`DeploymentID: ${e.deploymentId}`),console.log(`Email: ${e.email} ${e.emailVerified?o+"(verified)"+s:r+"(unverified)"+s}`),console.log(`Storage: ${r}${getIdentityPath()}${s}\n`),console.log(`${n}ℹ️ Next steps:${s}`),console.log(" 1. Connect to a service: xbind connect <service-name>"),console.log(" 2. Generate an invite: xbind invite <service-name>"),console.log(" 3. Check connection status: xbind status")}function outputSuccessJSON(e){console.log(JSON.stringify({status:"initialized",did:e.did,deploymentId:e.deploymentId,name:e.name,email:e.email,emailVerified:e.emailVerified,storagePath:getIdentityPath(),createdAt:e.createdAt}))}function outputError(e,t,o,r=!0){const n=r?Colors.RED:"",s=(r&&Colors.GRAY,r?Colors.BLUE:""),i=r?Colors.RESET:"";console.error(`${n}❌ Error: ${e}${i}`),t&&console.error(`\n${t}`),o&&console.error(`\n${s}ℹ️ ${o}${i}`)}export async function setupCommand(e={}){const t=!e["no-color"]&&process.stdout.isTTY,o=e["api-url"]||process.env.XBIND_API_URL||"http://localhost:3001";if(!e.force&&await identityExists()){const e=await readIdentity();outputError("Identity already exists",`An xBind identity is already configured for this device.\n\nStorage: ${getIdentityPath()}\nDID: ${e?.did||"unknown"}`,"To create a new identity, use:\n xbind setup --force",t),process.exit(ExitCode.USER_ERROR)}let r=e.name;if(!r){const e=`xbind-${Date.now()}`;r=await prompt("Service name",e)}isValidServiceName(r)||(outputError("Invalid service name","Service names must:\n • Start with a letter\n • Contain only letters, numbers, hyphens\n • Be 3-64 characters long\n\nExample: billing-service, api-v2, payments-prod",void 0,t),process.exit(ExitCode.USER_ERROR));let n=e.email;n||(n=await prompt("Email address")),isValidEmail(n)||(outputError("Invalid email format","Email must be a valid email address.\n\nExample: user@example.com",void 0,t),process.exit(ExitCode.USER_ERROR));const s=new Spinner("Generating DID...",t);let i;e.json||s.start();try{i=await generateDID(),e.json||s.succeed("DID generated")}catch(o){e.json||s.fail("Failed to generate DID"),outputError("DID generation failed",o instanceof Error?o.message:"Unknown error","Ensure crypto dependencies are installed",t),process.exit(ExitCode.SYSTEM_ERROR)}const a=generateDeploymentID(),c=new Spinner("Creating account on server...",t);e.json||c.start();const d=await createServerAccount(i.did,a,n,o);d.success||(e.json||c.fail("Failed to create account"),outputError(d.error?.code||"Account creation failed",d.error?.message,d.error?.hint||`Check server at ${o}`,t),process.exit(ExitCode.SYSTEM_ERROR)),e.json||c.succeed("Account created on server");const l=new Spinner("Sending verification email...",t);e.json||l.start();const u=await sendVerificationCode(n,o);if(u.success){if(e.json||l.succeed("Verification email sent"),!e.json){const e=t?Colors.CYAN:"",o=t?Colors.RESET:"";console.log(`\n${e}→ Check your email for a 6-digit verification code${o}`)}const r=await prompt("Enter verification code (or press Enter to skip)");if(r){const s=new Spinner("Verifying code...",t);e.json||s.start();const i=await verifyEmailCode(n,r,o);i.success?e.json||s.succeed("Email verified"):(e.json||s.fail("Verification failed"),outputError("Invalid verification code",i.error,"You can verify later using: xbind verify-email",t))}}else e.json||l.fail("Failed to send verification email"),outputError("Email verification failed",u.error,"You can verify later using: xbind verify-email",t);const p={did:i.did,deploymentId:a,name:r,email:n,emailVerified:d.account?.emailVerified||!1,publicKey:i.publicKey,privateKey:i.privateKey,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()};try{await writeIdentity(p)}catch(e){outputError("Failed to save identity",e instanceof Error?e.message:"Unknown error",`Check permissions on ${getIdentityPath()}`,t),process.exit(ExitCode.SYSTEM_ERROR)}e.json?outputSuccessJSON(p):(console.log(""),outputSuccess(p,t))}export async function main(e=process.argv.slice(2)){const{values:t}=parseArgs({args:e,options:{name:{type:"string",short:"n"},email:{type:"string",short:"e"},pair:{type:"boolean",short:"p"},force:{type:"boolean",short:"f"},"api-url":{type:"string"},json:{type:"boolean"},"no-color":{type:"boolean"},debug:{type:"boolean"},help:{type:"boolean",short:"h"}}});if(t.help)console.log("\nxBind Setup - Create Deployment Identity\n\nUsage:\n xbind setup [options]\n\nOptions:\n -n, --name <string> Service name (default: xbind-<timestamp>)\n -e, --email <email> Email address for account\n -p, --pair Display QR code for mobile pairing\n -f, --force Overwrite existing identity\n --api-url <url> Server API URL (default: http://localhost:3001)\n --json Output JSON only (no human-readable text)\n --no-color Disable colored output\n --debug Show detailed error information\n -h, --help Show this help message\n\nExamples:\n xbind setup --name billing-service\n xbind setup --name my-app --email user@example.com\n xbind setup --force\n ".trim());else try{await setupCommand({name:t.name,email:t.email,pair:t.pair,force:t.force,"api-url":t["api-url"],json:t.json,"no-color":t["no-color"],debug:t.debug})}catch(e){const o=!t["no-color"]&&process.stderr.isTTY,r=o?Colors.RED:"",n=o?Colors.RESET:"";console.error(`${r}❌ Fatal error: ${e instanceof Error?e.message:String(e)}${n}`),t.debug&&e instanceof Error&&e.stack&&console.error(e.stack),process.exit(ExitCode.SYSTEM_ERROR)}}const isDirectRun=process.argv[1]?.endsWith("setup.ts")||process.argv[1]?.endsWith("setup.js");isDirectRun&&main().catch(e=>{console.error("Fatal:",e instanceof Error?e.message:String(e)),process.exitCode=ExitCode.SYSTEM_ERROR});
|
|
2
|
+
import{parseArgs}from"node:util";import*as fs from"node:fs";import*as path from"node:path";import*as os from"node:os";import*as readline from"node:readline/promises";import{stdin as input,stdout as output}from"node:process";import{randomBytes}from"node:crypto";import{ExitCode,Colors}from"./types.js";function getIdentityPath(){return path.join(os.homedir(),".xbind","identity.json")}async function ensureXBindDir(){const e=path.join(os.homedir(),".xbind");try{await fs.promises.mkdir(e,{recursive:!0,mode:448})}catch(e){throw new Error(`Cannot create .xbind directory: ${e.message}`)}}async function identityExists(){try{return await fs.promises.access(getIdentityPath(),fs.constants.F_OK),!0}catch{return!1}}async function readIdentity(){try{const e=await fs.promises.readFile(getIdentityPath(),"utf-8");return JSON.parse(e)}catch{return null}}async function writeIdentity(e){await ensureXBindDir(),await fs.promises.writeFile(getIdentityPath(),JSON.stringify(e,null,2),{mode:384})}class Spinner{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];currentFrame=0;intervalId;message;useColors;constructor(e,t=!0){this.message=e,this.useColors=t&&process.stdout.isTTY}start(){this.intervalId=setInterval(()=>{const e=this.frames[this.currentFrame];process.stdout.write(`\r${e} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed(e){this.stop();const t=this.useColors?`${Colors.GREEN}✅${Colors.RESET}`:"✅";process.stdout.write(`\r${t} ${e??this.message}\n`)}fail(e){this.stop();const t=this.useColors?`${Colors.RED}❌${Colors.RESET}`:"❌";process.stdout.write(`\r${t} ${e??this.message}\n`)}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0)}}async function prompt(e,t){const o=readline.createInterface({input:input,output:output}),r=await o.question(t?`${e} (${t}): `:`${e}: `);return o.close(),r.trim()||t||""}function isValidEmail(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function isValidServiceName(e){return/^[a-zA-Z][a-zA-Z0-9-]{2,63}$/.test(e)}async function generateDID(){const{generateIdentity:e}=await import("../identity.js"),t=await e();if(!t.ok)throw new Error("Failed to generate identity");const o=t.value,r=new Uint8Array(await crypto.subtle.exportKey("raw",o.publicKey)),n=await crypto.subtle.exportKey("jwk",o.privateKey);if(!n.d)throw new Error("Failed to export private key");const s=Buffer.from(r).toString("base64"),i=n.d;return{did:o.did,publicKey:s,privateKey:i}}function generateDeploymentID(){const e=new Date;return`DEP-${e.getUTCFullYear()}${String(e.getUTCMonth()+1).padStart(2,"0")}-${randomBytes(5).toString("hex").toUpperCase()}`}async function createServerAccount(e,t,o,r){const n=`${r}/auth/signup`;try{const r=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:e,deploymentId:t,email:o,method:"code"})});if(!r.ok){return{success:!1,error:await r.json().catch(()=>({code:"UNKNOWN",message:`Server returned ${r.status}`}))}}return{success:!0,account:(await r.json()).account}}catch(e){return{success:!1,error:{code:"NETWORK_ERROR",message:e instanceof Error?e.message:"Network request failed",hint:"Check that the server is running and accessible"}}}}async function sendVerificationCode(e,t){const o=`${t}/auth/send-verification-code`;try{const t=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e})});if(!t.ok){return{success:!1,error:(await t.json().catch(()=>({message:`HTTP ${t.status}`}))).message}}return{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Network error"}}}async function verifyEmailCode(e,t,o){const r=`${o}/auth/verify-email-code`;try{const o=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,code:t})});if(!o.ok){return{success:!1,error:(await o.json().catch(()=>({message:`HTTP ${o.status}`}))).message}}return{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Network error"}}}function outputSuccess(e,t){const o=t?Colors.GREEN:"",r=t?Colors.GRAY:"",n=t?Colors.BLUE:"",s=t?Colors.RESET:"";console.log(`${o}✅ Identity created successfully${s}\n`),console.log(`Service Name: ${e.name}`),console.log(`DID: ${o}${e.did}${s}`),console.log(`DeploymentID: ${e.deploymentId}`),console.log(`Email: ${e.email} ${e.emailVerified?o+"(verified)"+s:r+"(unverified)"+s}`),console.log(`Storage: ${r}${getIdentityPath()}${s}\n`),console.log(`${n}ℹ️ Next steps:${s}`),console.log(" 1. Connect to a service: xbind connect <service-name>"),console.log(" 2. Generate an invite: xbind invite <service-name>"),console.log(" 3. Check connection status: xbind status")}function outputSuccessJSON(e){console.log(JSON.stringify({status:"initialized",did:e.did,deploymentId:e.deploymentId,name:e.name,email:e.email,emailVerified:e.emailVerified,storagePath:getIdentityPath(),createdAt:e.createdAt}))}function outputError(e,t,o,r=!0){const n=r?Colors.RED:"",s=r?Colors.BLUE:"",i=r?Colors.RESET:"";console.error(`${n}❌ Error: ${e}${i}`),t&&console.error(`\n${t}`),o&&console.error(`\n${s}ℹ️ ${o}${i}`)}export async function setupCommand(e={}){const t=!e["no-color"]&&process.stdout.isTTY,o=e["api-url"]||process.env.XBIND_API_URL||"http://localhost:3001";if(!e.force&&await identityExists()){const e=await readIdentity();outputError("Identity already exists",`An xBind identity is already configured for this device.\n\nStorage: ${getIdentityPath()}\nDID: ${e?.did||"unknown"}`,"To create a new identity, use:\n xbind setup --force",t),process.exit(ExitCode.USER_ERROR)}let r=e.name;if(!r){const e=`xbind-${Date.now()}`;r=await prompt("Service name",e)}isValidServiceName(r)||(outputError("Invalid service name","Service names must:\n • Start with a letter\n • Contain only letters, numbers, hyphens\n • Be 3-64 characters long\n\nExample: billing-service, api-v2, payments-prod",void 0,t),process.exit(ExitCode.USER_ERROR));let n=e.email;n||(n=await prompt("Email address")),isValidEmail(n)||(outputError("Invalid email format","Email must be a valid email address.\n\nExample: user@example.com",void 0,t),process.exit(ExitCode.USER_ERROR));const s=new Spinner("Generating DID...",t);let i;e.json||s.start();try{i=await generateDID(),e.json||s.succeed("DID generated")}catch(o){e.json||s.fail("Failed to generate DID"),outputError("DID generation failed",o instanceof Error?o.message:"Unknown error","Ensure crypto dependencies are installed",t),process.exit(ExitCode.SYSTEM_ERROR)}const a=generateDeploymentID(),c=new Spinner("Creating account on server...",t);e.json||c.start();const d=await createServerAccount(i.did,a,n,o);d.success||(e.json||c.fail("Failed to create account"),outputError(d.error?.code||"Account creation failed",d.error?.message,d.error?.hint||`Check server at ${o}`,t),process.exit(ExitCode.SYSTEM_ERROR)),e.json||c.succeed("Account created on server");const l=new Spinner("Sending verification email...",t);e.json||l.start();const u=await sendVerificationCode(n,o);if(u.success){if(e.json||l.succeed("Verification email sent"),!e.json){const e=t?Colors.CYAN:"",o=t?Colors.RESET:"";console.log(`\n${e}→ Check your email for a 6-digit verification code${o}`)}const r=await prompt("Enter verification code (or press Enter to skip)");if(r){const s=new Spinner("Verifying code...",t);e.json||s.start();const i=await verifyEmailCode(n,r,o);i.success?e.json||s.succeed("Email verified"):(e.json||s.fail("Verification failed"),outputError("Invalid verification code",i.error,"You can verify later using: xbind verify-email",t))}}else e.json||l.fail("Failed to send verification email"),outputError("Email verification failed",u.error,"You can verify later using: xbind verify-email",t);const p={did:i.did,deploymentId:a,name:r,email:n,emailVerified:d.account?.emailVerified||!1,publicKey:i.publicKey,privateKey:i.privateKey,createdAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()};try{await writeIdentity(p)}catch(e){outputError("Failed to save identity",e instanceof Error?e.message:"Unknown error",`Check permissions on ${getIdentityPath()}`,t),process.exit(ExitCode.SYSTEM_ERROR)}e.json?outputSuccessJSON(p):(console.log(""),outputSuccess(p,t))}export async function main(e=process.argv.slice(2)){const{values:t}=parseArgs({args:e,options:{name:{type:"string",short:"n"},email:{type:"string",short:"e"},pair:{type:"boolean",short:"p"},force:{type:"boolean",short:"f"},"api-url":{type:"string"},json:{type:"boolean"},"no-color":{type:"boolean"},debug:{type:"boolean"},help:{type:"boolean",short:"h"}}});if(t.help)console.log("\nxBind Setup - Create Deployment Identity\n\nUsage:\n xbind setup [options]\n\nOptions:\n -n, --name <string> Service name (default: xbind-<timestamp>)\n -e, --email <email> Email address for account\n -p, --pair Display QR code for mobile pairing\n -f, --force Overwrite existing identity\n --api-url <url> Server API URL (default: http://localhost:3001)\n --json Output JSON only (no human-readable text)\n --no-color Disable colored output\n --debug Show detailed error information\n -h, --help Show this help message\n\nExamples:\n xbind setup --name billing-service\n xbind setup --name my-app --email user@example.com\n xbind setup --force\n ".trim());else try{await setupCommand({name:t.name,email:t.email,pair:t.pair,force:t.force,"api-url":t["api-url"],json:t.json,"no-color":t["no-color"],debug:t.debug})}catch(e){const o=!t["no-color"]&&process.stderr.isTTY,r=o?Colors.RED:"",n=o?Colors.RESET:"";console.error(`${r}❌ Fatal error: ${e instanceof Error?e.message:String(e)}${n}`),t.debug&&e instanceof Error&&e.stack&&console.error(e.stack),process.exit(ExitCode.SYSTEM_ERROR)}}const isDirectRun=process.argv[1]?.endsWith("setup.ts")||process.argv[1]?.endsWith("setup.js");isDirectRun&&main().catch(e=>{console.error("Fatal:",e instanceof Error?e.message:String(e)),process.exitCode=ExitCode.SYSTEM_ERROR});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{parseArgs}from"node:util";import{ExitCode,Colors}from"./types.js";function showHelp(){console.log("\nxBind CLI - Identity-Based M2M Authentication\n\nUsage:\n xbind <command> [options]\n\nCommands:\n setup Create deployment identity (DID + DeploymentID)\n connect Connect to a service (TODO)\n invite Generate viral invite link (TODO)\n list List all active connections (TODO)\n status Display connection status (TODO)\n migrate Scan codebase for API keys (TODO)\n trial Activate 3-month free trial (TODO)\n deploy Deploy proprietary algorithms (TODO)\n server Start agent relay server (TODO)\n revoke Revoke connection (TODO)\n backup Export/import identity (TODO)\n debug Diagnostic information (TODO)\n\nGlobal Options:\n --json Output JSON only (no human-readable text)\n --no-color Disable colored output\n --debug Show detailed error information\n -h, --help Show this help message\n\nExamples:\n xbind setup --name my-service\n xbind setup --email user@example.com --force\n xbind connect payments-service\n xbind status\n\nDocumentation:\n https://private.me/docs/xbind\n ".trim())}function showVersion(){console.log("xBind CLI v1.3.0")}async function main(){const e=process.argv.slice(2);if(0===e.length)return void showHelp();const{values:o,positionals:n}=parseArgs({args:e,options:{help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"},json:{type:"boolean"},"no-color":{type:"boolean"},debug:{type:"boolean"}},allowPositionals:!0,strict:!1});if(o.help)return void showHelp();if(o.version)return void showVersion();const t=n[0];if(t)switch(t){case"setup":{const{main:o}=await import("./setup.js");await o(e.slice(1));break}case"connect":case"invite":case"list":case"status":case"migrate":case"trial":case"deploy":case"server":case"revoke":case"backup":case"debug":{const e=!o["no-color"]&&process.stderr.isTTY,n=e?Colors.YELLOW:"",s=e?Colors.RESET:"";console.error(`${n}⚠️ Command "${t}" not yet implemented${s}`),console.error("\nAvailable commands:"),console.error(" • setup - Create deployment identity (IMPLEMENTED)"),console.error("\nComing soon: connect, invite, list, status, migrate, trial, deploy, server, revoke, backup, debug"),process.exit(ExitCode.USER_ERROR)}default:{const e=!o["no-color"]&&process.stderr.isTTY,n=e?Colors.RED:"",s=e?Colors.RESET:"";console.error(`${n}❌ Error: Unknown command "${t}"${s}`),console.error('\nRun "xbind --help" to see available commands.'),process.exit(ExitCode.USER_ERROR)}}else showHelp()}main().catch(e=>{console.error("Fatal error:",e instanceof Error?e.message:String(e)),process.exit(ExitCode.SYSTEM_ERROR)});
|
|
2
|
+
import{parseArgs}from"node:util";import{ExitCode,Colors}from"./types.js";function showHelp(){console.log("\nxBind CLI - Identity-Based M2M Authentication\n\nUsage:\n xbind <command> [options]\n\nCommands:\n setup Create deployment identity (DID + DeploymentID)\n connect Connect to a service (TODO)\n invite Generate viral invite link (TODO)\n list List all active connections (TODO)\n status Display connection status (TODO)\n migrate Scan codebase for API keys (TODO)\n trial Activate 3-month free trial (TODO)\n deploy Deploy proprietary algorithms (TODO)\n server Start agent relay server (TODO)\n revoke Revoke connection (TODO)\n backup Export/import identity (TODO)\n debug Diagnostic information (TODO)\n\nGlobal Options:\n --json Output JSON only (no human-readable text)\n --no-color Disable colored output\n --debug Show detailed error information\n -h, --help Show this help message\n\nExamples:\n xbind setup --name my-service\n xbind setup --email user@example.com --force\n xbind connect payments-service\n xbind status\n\nDocumentation:\n https://private.me/docs/xbind\n ".trim())}function showVersion(){console.log("xBind CLI v1.3.0")}async function main(){const e=process.argv.slice(2);if(0===e.length)return void showHelp();const{values:o,positionals:n}=parseArgs({args:e,options:{help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"},json:{type:"boolean"},"no-color":{type:"boolean"},debug:{type:"boolean"}},allowPositionals:!0,strict:!1});if(o.help)return void showHelp();if(o.version)return void showVersion();const t=n[0];if(t)switch(t){case"setup":{const{main:o}=await import("./setup.js");await o(e.slice(1));break}case"connect":case"invite":case"list":case"status":case"migrate":case"trial":case"deploy":case"server":case"revoke":case"backup":case"debug":{const e=!o["no-color"]&&process.stderr.isTTY,n=e?Colors.YELLOW:"",s=e?Colors.RESET:"";console.error(`${n}⚠️ Command "${t}" not yet implemented${s}`),console.error("\nAvailable commands:"),console.error(" • setup - Create deployment identity (IMPLEMENTED)"),console.error("\nComing soon: connect, invite, list, status, migrate, trial, deploy, server, revoke, backup, debug"),process.exit(ExitCode.USER_ERROR);break}default:{const e=!o["no-color"]&&process.stderr.isTTY,n=e?Colors.RED:"",s=e?Colors.RESET:"";console.error(`${n}❌ Error: Unknown command "${t}"${s}`),console.error('\nRun "xbind --help" to see available commands.'),process.exit(ExitCode.USER_ERROR)}}else showHelp()}main().catch(e=>{console.error("Fatal error:",e instanceof Error?e.message:String(e)),process.exit(ExitCode.SYSTEM_ERROR)});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export class ConnectionPool{options;connections=new Map;metrics;cleanupInterval=null;constructor(t={}){this.options={maxConnections:t.maxConnections??10,minConnections:t.minConnections??2,keepAliveTimeout:t.keepAliveTimeout??3e4,idleTimeout:t.idleTimeout??6e4,requestTimeout:t.requestTimeout??3e4,enableMetrics:t.enableMetrics??!0,retryOnFailure:t.retryOnFailure??!0,maxRetries:t.maxRetries??3},this.metrics={totalRequests:0,reuseCount:0,failedRequests:0,requestDurations:[],byOrigin:new Map},this.startCleanup()}async fetch(t,e){const s=Date.now(),n=this.getOrigin(t);try{const o=await this.acquireConnection(n);this.options.enableMetrics&&(this.metrics.totalRequests++,o.requestCount>0&&this.metrics.reuseCount++);const i={...e,signal:e?.signal??o.controller.signal,keepalive:!0},r=await fetch(t,i);if(o.requestCount++,o.lastUsedAt=Date.now(),o.state="idle",this.options.enableMetrics){const t=Date.now()-s;this.recordMetrics(n,t)}return r}catch(s){if(this.options.enableMetrics&&this.metrics.failedRequests++,this.options.retryOnFailure&&!0!==e?.signal?.aborted)return this.retryRequest(t,e,1);throw s}}async retryRequest(t,e,s){if(s>this.options.maxRetries)throw new Error(`Request failed after ${this.options.maxRetries} retries: ${t}`);const n=100*Math.pow(2,s-1);await new Promise(t=>setTimeout(t,n));const o=this.getOrigin(t);try{const s=await this.acquireConnection(o),n={...e,signal:e?.signal??s.controller.signal,keepalive:!0},i=await fetch(t,n);return s.requestCount++,s.lastUsedAt=Date.now(),s.state="idle",i}catch
|
|
1
|
+
export class ConnectionPool{options;connections=new Map;metrics;cleanupInterval=null;constructor(t={}){this.options={maxConnections:t.maxConnections??10,minConnections:t.minConnections??2,keepAliveTimeout:t.keepAliveTimeout??3e4,idleTimeout:t.idleTimeout??6e4,requestTimeout:t.requestTimeout??3e4,enableMetrics:t.enableMetrics??!0,retryOnFailure:t.retryOnFailure??!0,maxRetries:t.maxRetries??3},this.metrics={totalRequests:0,reuseCount:0,failedRequests:0,requestDurations:[],byOrigin:new Map},this.startCleanup()}async fetch(t,e){const s=Date.now(),n=this.getOrigin(t);try{const o=await this.acquireConnection(n);this.options.enableMetrics&&(this.metrics.totalRequests++,o.requestCount>0&&this.metrics.reuseCount++);const i={...e,signal:e?.signal??o.controller.signal,keepalive:!0},r=await fetch(t,i);if(o.requestCount++,o.lastUsedAt=Date.now(),o.state="idle",this.options.enableMetrics){const t=Date.now()-s;this.recordMetrics(n,t)}return r}catch(s){if(this.options.enableMetrics&&this.metrics.failedRequests++,this.options.retryOnFailure&&!0!==e?.signal?.aborted)return this.retryRequest(t,e,1);throw s}}async retryRequest(t,e,s){if(s>this.options.maxRetries)throw new Error(`Request failed after ${this.options.maxRetries} retries: ${t}`);const n=100*Math.pow(2,s-1);await new Promise(t=>setTimeout(t,n));const o=this.getOrigin(t);try{const s=await this.acquireConnection(o),n={...e,signal:e?.signal??s.controller.signal,keepalive:!0},i=await fetch(t,n);return s.requestCount++,s.lastUsedAt=Date.now(),s.state="idle",i}catch{if(s>=this.options.maxRetries)throw new Error(`Request failed after ${this.options.maxRetries} retries: ${t}`);return this.retryRequest(t,e,s+1)}}async acquireConnection(t){let e=this.connections.get(t);e||(e=[],this.connections.set(t,e));const s=e.find(t=>"idle"===t.state);if(s)return s.state="active",s;if(e.length<this.options.maxConnections){const s=this.createConnection(t);return e.push(s),s}return this.waitForConnection(t)}async waitForConnection(t){const e=Date.now(),s=this.options.requestTimeout;for(;Date.now()-e<s;){const e=this.connections.get(t);if(!e)throw new Error(`Connection pool for ${t} disappeared`);const s=e.find(t=>"idle"===t.state);if(s)return s.state="active",s;await new Promise(t=>setTimeout(t,10))}throw new Error(`Timeout waiting for connection to ${t} after ${s}ms`)}createConnection(t){const e=new Uint8Array(8);crypto.getRandomValues(e);return{id:`conn_${Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}`,origin:t,createdAt:Date.now(),lastUsedAt:Date.now(),requestCount:0,state:"active",controller:new AbortController}}getOrigin(t){try{const e=new URL(t);return`${e.protocol}//${e.host}`}catch{throw new Error(`Invalid URL: ${t}`)}}recordMetrics(t,e){this.metrics.requestDurations.push(e),this.metrics.requestDurations.length>1e3&&this.metrics.requestDurations.shift();let s=this.metrics.byOrigin.get(t);s||(s={requests:0,durations:[]},this.metrics.byOrigin.set(t,s)),s.requests++,s.durations.push(e),s.durations.length>100&&s.durations.shift()}getMetrics(){let t=0,e=0,s=0;const n=new Map;for(const[o,i]of this.connections.entries()){t+=i.length,e+=i.filter(t=>"active"===t.state).length,s+=i.filter(t=>"idle"===t.state).length;const r=this.metrics.byOrigin.get(o);if(r){const t=r.durations.length>0?r.durations.reduce((t,e)=>t+e,0)/r.durations.length:0;n.set(o,{connections:i.length,requests:r.requests,avgDuration:Math.round(t)})}}const o=this.metrics.requestDurations.length>0?Math.round(this.metrics.requestDurations.reduce((t,e)=>t+e,0)/this.metrics.requestDurations.length):0,i=this.metrics.totalRequests>0?this.metrics.reuseCount/this.metrics.totalRequests:0;return{totalConnections:t,activeConnections:e,idleConnections:s,totalRequests:this.metrics.totalRequests,reuseCount:this.metrics.reuseCount,failedRequests:this.metrics.failedRequests,avgRequestDuration:o,hitRate:i,byOrigin:n}}resetMetrics(){this.metrics={totalRequests:0,reuseCount:0,failedRequests:0,requestDurations:[],byOrigin:new Map}}startCleanup(){this.cleanupInterval=setInterval(()=>{this.cleanup()},1e4)}cleanup(){const t=Date.now();for(const[e,s]of this.connections.entries()){const n=s.filter(e=>t-e.lastUsedAt>this.options.idleTimeout&&"idle"===e.state?(e.controller.abort(),e.state="closed",!1):"closed"!==e.state);for(;n.length<this.options.minConnections&&n.length<this.options.maxConnections;){const t=this.createConnection(e);t.state="idle",n.push(t)}n.length>0?this.connections.set(e,n):this.connections.delete(e)}}cleanupNow(){this.cleanup()}async close(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=null);for(const[t,e]of this.connections.entries())for(const t of e)t.controller.abort(),t.state="closed";this.connections.clear()}getConnectionCount(t){const e=this.connections.get(t);return e?e.length:0}getOrigins(){return Array.from(this.connections.keys())}isHealthy(){const t=this.getMetrics();return!((t.totalRequests>0?t.failedRequests/t.totalRequests:0)>.1)&&!(t.avgRequestDuration>5e3)}}let globalPool=null;export function getGlobalPool(t){return globalPool||(globalPool=new ConnectionPool(t)),globalPool}export async function resetGlobalPool(){globalPool&&(await globalPool.close(),globalPool=null)}
|
|
@@ -29,15 +29,11 @@ export declare function formatShareHeader(data: string): string;
|
|
|
29
29
|
export declare function parseShareHeader(input: string): string;
|
|
30
30
|
/** Check if string has branded IDA5 share header */
|
|
31
31
|
export declare function hasShareHeader(input: string): boolean;
|
|
32
|
-
|
|
33
|
-
* Vault-gated XorIDA functions (loaded dynamically from payment-gated Vault Store).
|
|
34
|
-
* These are re-exported from vault-store-loader for convenience.
|
|
35
|
-
*/
|
|
36
|
-
import { getCrypto, loadCryptoPackage, isCryptoLoaded } from './vault-store-loader.js';
|
|
32
|
+
export { loadCryptoPackage, getCrypto, isCryptoLoaded, setMockCrypto, clearCryptoCache } from './vault-store-loader.js';
|
|
37
33
|
/** Split data using XorIDA (vault-gated, requires payment) */
|
|
38
34
|
export declare function splitXorIDA(data: Uint8Array, totalShares: number, requiredShares: number): Uint8Array[];
|
|
39
35
|
/** Reconstruct data from XorIDA shares (vault-gated, requires payment) */
|
|
40
|
-
export declare function reconstructXorIDA(shares: Uint8Array[], indices: number[],
|
|
36
|
+
export declare function reconstructXorIDA(shares: Uint8Array[], indices: number[], totalShares: number, requiredShares: number): Uint8Array;
|
|
41
37
|
/** Get next odd prime >= n (vault-gated utility) */
|
|
42
38
|
export declare function nextOddPrime(n: number): number;
|
|
43
39
|
/** PKCS7 padding (vault-gated utility) */
|
|
@@ -57,4 +53,3 @@ export declare function generateHMAC(data: Uint8Array): Promise<{
|
|
|
57
53
|
}>;
|
|
58
54
|
/** Verify HMAC-SHA256 (vault-gated utility) */
|
|
59
55
|
export declare function verifyHMAC(key: Uint8Array, data: Uint8Array, expectedHmac: Uint8Array): Promise<boolean>;
|
|
60
|
-
export { loadCryptoPackage, getCrypto, isCryptoLoaded };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function toBase64(r){if("undefined"!=typeof Buffer)return Buffer.from(r).toString("base64");const t=String.fromCharCode(...r);return btoa(t)}export function fromBase64(r){if("undefined"!=typeof Buffer)return new Uint8Array(Buffer.from(r,"base64"));const t=atob(r),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}export function toBase64Url(r){return toBase64(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}export function fromBase64Url(r){let t=r.replace(/-/g,"+").replace(/_/g,"/");for(;t.length%4;)t+="=";return fromBase64(t)}export function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const r=new Uint8Array(16);crypto.getRandomValues(r),r[6]=15&r[6]|64,r[8]=63&r[8]|128;const t=Array.from(r).map(r=>r.toString(16).padStart(2,"0")).join("");return`${t.substring(0,8)}-${t.substring(8,12)}-${t.substring(12,16)}-${t.substring(16,20)}-${t.substring(20)}`}const START_MARKER="Encrypted://",END_MARKER="=> Generated by Xecret (TM)",BRAND_PREFIX="Xecret (TM) -> PRIVATE .ME (R) -> IDA5 -> ";export function formatShareHeader(r){return`${BRAND_PREFIX}${START_MARKER} ${r} ${END_MARKER}`}export function parseShareHeader(r){const t=r.indexOf(START_MARKER);if(t<0)return r.trim();const e=t+12,o=r.indexOf(END_MARKER,e);return o<0?r.trim():r.substring(e,o).trim()}export function hasShareHeader(r){return r.includes(START_MARKER)&&r.includes(END_MARKER)}import{getCrypto
|
|
1
|
+
export function toBase64(r){if("undefined"!=typeof Buffer)return Buffer.from(r).toString("base64");const t=String.fromCharCode(...r);return btoa(t)}export function fromBase64(r){if("undefined"!=typeof Buffer)return new Uint8Array(Buffer.from(r,"base64"));const t=atob(r),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}export function toBase64Url(r){return toBase64(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}export function fromBase64Url(r){let t=r.replace(/-/g,"+").replace(/_/g,"/");for(;t.length%4;)t+="=";return fromBase64(t)}export function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const r=new Uint8Array(16);crypto.getRandomValues(r),r[6]=15&r[6]|64,r[8]=63&r[8]|128;const t=Array.from(r).map(r=>r.toString(16).padStart(2,"0")).join("");return`${t.substring(0,8)}-${t.substring(8,12)}-${t.substring(12,16)}-${t.substring(16,20)}-${t.substring(20)}`}const START_MARKER="Encrypted://",END_MARKER="=> Generated by Xecret (TM)",BRAND_PREFIX="Xecret (TM) -> PRIVATE .ME (R) -> IDA5 -> ";export function formatShareHeader(r){return`${BRAND_PREFIX}${START_MARKER} ${r} ${END_MARKER}`}export function parseShareHeader(r){const t=r.indexOf(START_MARKER);if(t<0)return r.trim();const e=t+12,o=r.indexOf(END_MARKER,e);return o<0?r.trim():r.substring(e,o).trim()}export function hasShareHeader(r){return r.includes(START_MARKER)&&r.includes(END_MARKER)}import{getCrypto}from"./vault-store-loader.js";export{loadCryptoPackage,getCrypto,isCryptoLoaded,setMockCrypto,clearCryptoCache}from"./vault-store-loader.js";export function splitXorIDA(r,t,e){const o=getCrypto();if(!o)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return o.splitXorIDA(r,t,e)}export function reconstructXorIDA(r,t,e,o){const n=getCrypto();if(!n)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return n.reconstructXorIDA(r,t,e,o)}export function nextOddPrime(r){const t=getCrypto();if(!t)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return t.nextOddPrime(r)}export function pkcs7Pad(r,t){const e=getCrypto();if(!e)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return e.pkcs7Pad(r,t)}export function pkcs7Unpad(r,t){const e=getCrypto();if(!e)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return e.pkcs7Unpad(r,t)}export async function generateHMAC(r){const t=getCrypto();if(!t)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return t.generateHMAC(r)}export async function verifyHMAC(r,t,e){const o=getCrypto();if(!o)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return o.verifyHMAC(r,t,e)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,LogLevel}from"./logger.js";class DebugModeState{enabled=!1;options={};measurements=[];networkTraces=[];cryptoTraces=[];stateSnapshots=[];activeTimers=new Map}const globalDebugState=new DebugModeState;export function enableDebugMode(e={}){globalDebugState.enabled=!0,globalDebugState.options={verbose:e.verbose??!1,traceNetwork:e.traceNetwork??!1,traceCrypto:e.traceCrypto??!1,profile:e.profile??!1,trackMemory:e.trackMemory??!1,traceState:e.traceState??!1,output:e.output??console.log,filters:e.filters};const t=createLogger("debug-mode");t.setLevel(LogLevel.DEBUG),t.info("Debug mode enabled",{options:globalDebugState.options})}export function disableDebugMode(){globalDebugState.enabled=!1,globalDebugState.measurements=[],globalDebugState.networkTraces=[],globalDebugState.cryptoTraces=[],globalDebugState.stateSnapshots=[],globalDebugState.activeTimers.clear();createLogger("debug-mode").info("Debug mode disabled")}export function isDebugEnabled(){return globalDebugState.enabled}export function getDebugOptions(){return{...globalDebugState.options}}export function createDebugLogger(e){const t=createLogger(e);return globalDebugState.enabled&&globalDebugState.options.verbose&&t.setLevel(LogLevel.DEBUG),{...t,trace(e,o){if(globalDebugState.enabled&&globalDebugState.options.verbose){if(globalDebugState.options.filters){const{include:t,exclude:o}=globalDebugState.options.filters;if(t&&!t.some(t=>t.test(e)))return;if(o&&o.some(t=>t.test(e)))return}t.debug(e,o)}}}}export function startProfiling(e,t){if(!globalDebugState.enabled||!globalDebugState.options.profile)return;const o=performance.now();globalDebugState.activeTimers.set(e,{startTime:o,context:t});createDebugLogger("profiler").trace(`[PROFILE] Starting: ${e}`,t)}export function endProfiling(e,t){if(!globalDebugState.enabled||!globalDebugState.options.profile)return;const o=globalDebugState.activeTimers.get(e);if(!o){return void createDebugLogger("profiler").warn(`[PROFILE] No start time found for: ${e}`)}const r=performance.now(),a=r-o.startTime,s=t??o.context;let n,u,g;if(globalDebugState.options.trackMemory&&"undefined"!=typeof process&&process.memoryUsage){u=process.memoryUsage().heapUsed,n=u,g=0}const l={operation:e,startTime:o.startTime,endTime:r,duration:a,memoryBefore:n,memoryAfter:u,memoryDelta:g,context:s};globalDebugState.measurements.push(l),globalDebugState.activeTimers.delete(e);createDebugLogger("profiler").trace(`[PROFILE] Completed: ${e} (${a.toFixed(2)}ms)`,{duration:a,memoryDelta:g,...t})}export function getPerformanceMeasurements(){return[...globalDebugState.measurements]}export function clearPerformanceMeasurements(){globalDebugState.measurements=[],globalDebugState.activeTimers.clear()}export function traceNetworkRequest(e,t,o,r,a){if(!globalDebugState.enabled||!globalDebugState.options.traceNetwork)return;const s={id:e,method:t,url:o,requestHeaders:redactHeaders(r),requestBody:truncateBody(a),startTime:performance.now()};globalDebugState.networkTraces.push(s);createDebugLogger("network").trace(`[NETWORK] ${t} ${o}`,{requestId:e,headers:s.requestHeaders,bodyLength:a?.length??0})}export function traceNetworkResponse(e,t,o,r,a){if(!globalDebugState.enabled||!globalDebugState.options.traceNetwork)return;const s=globalDebugState.networkTraces.find(t=>t.id===e);if(!s)return;s.endTime=performance.now(),s.duration=s.endTime-s.startTime,s.status=t,s.responseHeaders=o?redactHeaders(o):void 0,s.responseBody=truncateBody(r),s.error=a;createDebugLogger("network").trace(`[NETWORK] Response ${t??"ERROR"} (${s.duration.toFixed(2)}ms)`,{requestId:e,status:t,duration:s.duration,error:a})}export function getNetworkTraces(){return[...globalDebugState.networkTraces]}export function clearNetworkTraces(){globalDebugState.networkTraces=[]}export function traceCryptoOperation(e,t,o,r,a,s,n){if(!globalDebugState.enabled||!globalDebugState.options.traceCrypto)return;const u={operation:e,algorithm:t,inputSize:o,outputSize:r,duration:a??0,success:s??!0,error:n,timestamp:Date.now()};globalDebugState.cryptoTraces.push(u);createDebugLogger("crypto").trace(`[CRYPTO] ${e} (${t})`,{inputSize:o,outputSize:r,duration:a,success:s,error:n})}export function getCryptoTraces(){return[...globalDebugState.cryptoTraces]}export function clearCryptoTraces(){globalDebugState.cryptoTraces=[]}export function dumpState(e){const t={did:e.did,identityMode:
|
|
1
|
+
import{createLogger,LogLevel}from"./logger.js";class DebugModeState{enabled=!1;options={};measurements=[];networkTraces=[];cryptoTraces=[];stateSnapshots=[];activeTimers=new Map}const globalDebugState=new DebugModeState;export function enableDebugMode(e={}){globalDebugState.enabled=!0,globalDebugState.options={verbose:e.verbose??!1,traceNetwork:e.traceNetwork??!1,traceCrypto:e.traceCrypto??!1,profile:e.profile??!1,trackMemory:e.trackMemory??!1,traceState:e.traceState??!1,output:e.output??console.log,filters:e.filters};const t=createLogger("debug-mode");t.setLevel(LogLevel.DEBUG),t.info("Debug mode enabled",{options:globalDebugState.options})}export function disableDebugMode(){globalDebugState.enabled=!1,globalDebugState.measurements=[],globalDebugState.networkTraces=[],globalDebugState.cryptoTraces=[],globalDebugState.stateSnapshots=[],globalDebugState.activeTimers.clear();createLogger("debug-mode").info("Debug mode disabled")}export function isDebugEnabled(){return globalDebugState.enabled}export function getDebugOptions(){return{...globalDebugState.options}}export function createDebugLogger(e){const t=createLogger(e);return globalDebugState.enabled&&globalDebugState.options.verbose&&t.setLevel(LogLevel.DEBUG),{...t,trace(e,o){if(globalDebugState.enabled&&globalDebugState.options.verbose){if(globalDebugState.options.filters){const{include:t,exclude:o}=globalDebugState.options.filters;if(t&&!t.some(t=>t.test(e)))return;if(o&&o.some(t=>t.test(e)))return}t.debug(e,o)}}}}export function startProfiling(e,t){if(!globalDebugState.enabled||!globalDebugState.options.profile)return;const o=performance.now();globalDebugState.activeTimers.set(e,{startTime:o,context:t});createDebugLogger("profiler").trace(`[PROFILE] Starting: ${e}`,t)}export function endProfiling(e,t){if(!globalDebugState.enabled||!globalDebugState.options.profile)return;const o=globalDebugState.activeTimers.get(e);if(!o){return void createDebugLogger("profiler").warn(`[PROFILE] No start time found for: ${e}`)}const r=performance.now(),a=r-o.startTime,s=t??o.context;let n,u,g;if(globalDebugState.options.trackMemory&&"undefined"!=typeof process&&process.memoryUsage){u=process.memoryUsage().heapUsed,n=u,g=0}const l={operation:e,startTime:o.startTime,endTime:r,duration:a,memoryBefore:n,memoryAfter:u,memoryDelta:g,context:s};globalDebugState.measurements.push(l),globalDebugState.activeTimers.delete(e);createDebugLogger("profiler").trace(`[PROFILE] Completed: ${e} (${a.toFixed(2)}ms)`,{duration:a,memoryDelta:g,...t})}export function getPerformanceMeasurements(){return[...globalDebugState.measurements]}export function clearPerformanceMeasurements(){globalDebugState.measurements=[],globalDebugState.activeTimers.clear()}export function traceNetworkRequest(e,t,o,r,a){if(!globalDebugState.enabled||!globalDebugState.options.traceNetwork)return;const s={id:e,method:t,url:o,requestHeaders:redactHeaders(r),requestBody:truncateBody(a),startTime:performance.now()};globalDebugState.networkTraces.push(s);createDebugLogger("network").trace(`[NETWORK] ${t} ${o}`,{requestId:e,headers:s.requestHeaders,bodyLength:a?.length??0})}export function traceNetworkResponse(e,t,o,r,a){if(!globalDebugState.enabled||!globalDebugState.options.traceNetwork)return;const s=globalDebugState.networkTraces.find(t=>t.id===e);if(!s)return;s.endTime=performance.now(),s.duration=s.endTime-s.startTime,s.status=t,s.responseHeaders=o?redactHeaders(o):void 0,s.responseBody=truncateBody(r),s.error=a;createDebugLogger("network").trace(`[NETWORK] Response ${t??"ERROR"} (${s.duration.toFixed(2)}ms)`,{requestId:e,status:t,duration:s.duration,error:a})}export function getNetworkTraces(){return[...globalDebugState.networkTraces]}export function clearNetworkTraces(){globalDebugState.networkTraces=[]}export function traceCryptoOperation(e,t,o,r,a,s,n){if(!globalDebugState.enabled||!globalDebugState.options.traceCrypto)return;const u={operation:e,algorithm:t,inputSize:o,outputSize:r,duration:a??0,success:s??!0,error:n,timestamp:Date.now()};globalDebugState.cryptoTraces.push(u);createDebugLogger("crypto").trace(`[CRYPTO] ${e} (${t})`,{inputSize:o,outputSize:r,duration:a,success:s,error:n})}export function getCryptoTraces(){return[...globalDebugState.cryptoTraces]}export function clearCryptoTraces(){globalDebugState.cryptoTraces=[]}export function dumpState(e){const t=e,o={did:e.did,identityMode:t.identityMode??"persistent",registered:t.registered??!1,registryUrl:t.registry?.url,nonceStoreType:t.nonceStore?.constructor?.name??"unknown",nonceCount:t.nonceStore?.size??0,transportType:t.transport?.constructor?.name??"unknown",securityPolicy:{level:t.securityPolicy?.level??"unknown",replayWindow:t.securityPolicy?.replayWindow??0,timestampTolerance:t.securityPolicy?.timestampTolerance??0},postQuantum:t.postQuantum??!1,memoryUsage:"undefined"!=typeof process&&process.memoryUsage?process.memoryUsage().heapUsed:void 0,timestamp:Date.now()};globalDebugState.enabled&&globalDebugState.options.traceState&&globalDebugState.stateSnapshots.push(o);return createDebugLogger("state").trace("[STATE] Agent snapshot",o),o}export function getStateSnapshots(){return[...globalDebugState.stateSnapshots]}export function clearStateSnapshots(){globalDebugState.stateSnapshots=[]}export function exportDebugData(){const e={enabled:globalDebugState.enabled,options:globalDebugState.options,measurements:globalDebugState.measurements,networkTraces:globalDebugState.networkTraces,cryptoTraces:globalDebugState.cryptoTraces,stateSnapshots:globalDebugState.stateSnapshots,exportedAt:(new Date).toISOString()};return JSON.stringify(e,null,2)}export function clearAllDebugData(){clearPerformanceMeasurements(),clearNetworkTraces(),clearCryptoTraces(),clearStateSnapshots()}function redactHeaders(e){const t={},o=new Set(["authorization","cookie","set-cookie","x-api-key","x-auth-token"]);for(const[r,a]of Object.entries(e)){const e=r.toLowerCase();o.has(e)?t[r]="[REDACTED]":t[r]=a}return t}function truncateBody(e){if(!e)return;const t=1e3;return e.length<=t?e:e.substring(0,t)+`... (${e.length-t} more bytes)`}export function generateDebugReport(){const e=[];if(e.push("=".repeat(80)),e.push("xBind Debug Report"),e.push("=".repeat(80)),e.push(""),e.push(`Generated: ${(new Date).toISOString()}`),e.push("Debug Mode: "+(globalDebugState.enabled?"ENABLED":"DISABLED")),e.push(""),globalDebugState.measurements.length>0){e.push("Performance Measurements:"),e.push("-".repeat(80));for(const t of globalDebugState.measurements)e.push(` ${t.operation}: ${t.duration.toFixed(2)}ms`),void 0!==t.memoryDelta&&e.push(` Memory: ${formatBytes(t.memoryDelta)}`);e.push("")}if(globalDebugState.networkTraces.length>0){e.push("Network Traces:"),e.push("-".repeat(80));for(const t of globalDebugState.networkTraces)e.push(` ${t.method} ${t.url}`),t.status&&e.push(` Status: ${t.status}`),t.duration&&e.push(` Duration: ${t.duration.toFixed(2)}ms`),t.error&&e.push(` Error: ${t.error}`);e.push("")}if(globalDebugState.cryptoTraces.length>0){e.push("Crypto Operations:"),e.push("-".repeat(80));for(const t of globalDebugState.cryptoTraces)e.push(` ${t.operation} (${t.algorithm})`),e.push(` Input: ${formatBytes(t.inputSize)}`),t.outputSize&&e.push(` Output: ${formatBytes(t.outputSize)}`),e.push(` Duration: ${t.duration.toFixed(2)}ms`),e.push(` Success: ${t.success}`),t.error&&e.push(` Error: ${t.error}`);e.push("")}if(globalDebugState.stateSnapshots.length>0){e.push("State Snapshots:"),e.push("-".repeat(80));const t=globalDebugState.stateSnapshots[globalDebugState.stateSnapshots.length-1];t&&(e.push(` DID: ${t.did}`),e.push(` Mode: ${t.identityMode}`),e.push(` Registered: ${t.registered}`),e.push(` Post-Quantum: ${t.postQuantum}`),e.push(` Nonce Count: ${t.nonceCount}`),t.memoryUsage&&e.push(` Memory Usage: ${formatBytes(t.memoryUsage)}`)),e.push("")}return e.push("=".repeat(80)),e.join("\n")}function formatBytes(e){if(0===e)return"0 B";const t=Math.floor(Math.log(Math.abs(e))/Math.log(1024));return`${(e/Math.pow(1024,t)).toFixed(2)} ${["B","KB","MB","GB"][t]}`}
|
|
@@ -82,7 +82,7 @@ export declare class EmailTransport implements XailTransportAdapter {
|
|
|
82
82
|
* @param recipientDid - Recipient DID (email address for email transport)
|
|
83
83
|
* @returns Result with void on success
|
|
84
84
|
*/
|
|
85
|
-
send(envelope: any,
|
|
85
|
+
send(envelope: any, _recipientDid: string): Promise<Result<void, TransportError>>;
|
|
86
86
|
/**
|
|
87
87
|
* Validate email address format.
|
|
88
88
|
*
|
|
@@ -131,7 +131,7 @@ export declare class EmailTransport implements XailTransportAdapter {
|
|
|
131
131
|
*
|
|
132
132
|
* @param handler - Envelope handler (unused)
|
|
133
133
|
*/
|
|
134
|
-
onReceive(
|
|
134
|
+
onReceive(_handler: EnvelopeHandler): void;
|
|
135
135
|
/**
|
|
136
136
|
* Shut down the transport (close SMTP connection).
|
|
137
137
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ok,err}from"./_deps/shared/index.js";import{renderInviteEmail}from"./email-templates.js";import nodemailer from"nodemailer";export class EmailTransport{config;transporter;rateLimits;constructor(t){this.config={...t,rateLimit:t.rateLimit??10,tokenExpiryHours:t.tokenExpiryHours??48},this.transporter=nodemailer.createTransport({host:this.config.smtpHost,port:this.config.smtpPort,secure:!1,auth:{user:this.config.smtpUser,pass:this.config.smtpPass}}),this.rateLimits=new Map}async send(t,e){const{from:r,to:i,payload:s}=t;if(!this.isValidEmail(i))return err("SEND_FAILED");if(!this.checkRateLimit(r).ok)return err("SEND_FAILED");try{const e=await this.generateInviteToken(t),o=`${this.config.acceptBaseUrl}/${e}`,a=renderInviteEmail({agentName:s.agentName||r,did:r,acceptUrl:o,message:s.message});return await this.transporter.sendMail({from:`"${this.config.fromName}" <${this.config.fromEmail}>`,to:i,subject:`${s.agentName||"Agent"} wants to connect`,html:a}),this.incrementRateLimit(r),ok(void 0)}catch
|
|
1
|
+
import{ok,err}from"./_deps/shared/index.js";import{renderInviteEmail}from"./email-templates.js";import nodemailer from"nodemailer";export class EmailTransport{config;transporter;rateLimits;constructor(t){this.config={...t,rateLimit:t.rateLimit??10,tokenExpiryHours:t.tokenExpiryHours??48},this.transporter=nodemailer.createTransport({host:this.config.smtpHost,port:this.config.smtpPort,secure:!1,auth:{user:this.config.smtpUser,pass:this.config.smtpPass}}),this.rateLimits=new Map}async send(t,e){const{from:r,to:i,payload:s}=t;if(!this.isValidEmail(i))return err("SEND_FAILED");if(!this.checkRateLimit(r).ok)return err("SEND_FAILED");try{const e=await this.generateInviteToken(t),o=`${this.config.acceptBaseUrl}/${e}`,a=renderInviteEmail({agentName:s.agentName||r,did:r,acceptUrl:o,message:s.message});return await this.transporter.sendMail({from:`"${this.config.fromName}" <${this.config.fromEmail}>`,to:i,subject:`${s.agentName||"Agent"} wants to connect`,html:a}),this.incrementRateLimit(r),ok(void 0)}catch{return err("NETWORK_ERROR")}}isValidEmail(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}checkRateLimit(t){const e=Date.now(),r=this.rateLimits.get(t);return r?e>=r.resetAt?(this.rateLimits.delete(t),ok(void 0)):r.count>=this.config.rateLimit?err(void 0):ok(void 0):ok(void 0)}incrementRateLimit(t){const e=Date.now(),r=this.rateLimits.get(t);r?r.count+=1:this.rateLimits.set(t,{count:1,resetAt:e+36e5})}async generateInviteToken(t){const e={from:t.from,publicKey:t.payload.publicKey,endpoint:t.payload.endpoint,timestamp:Date.now(),expiresAt:Date.now()+60*this.config.tokenExpiryHours*60*1e3},r=JSON.stringify(e);return Buffer.from(r).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async verify(){try{return await this.transporter.verify(),ok(void 0)}catch{return err("NETWORK_ERROR")}}async close(){this.transporter.close()}onReceive(t){}dispose(){this.transporter.close()}}
|
|
@@ -57,18 +57,28 @@ export declare class VaultStoreError extends XBindError {
|
|
|
57
57
|
export declare class QuotaExceededError extends XBindBillingError {
|
|
58
58
|
/** Upgrade URL for Pro tier */
|
|
59
59
|
readonly upgradeUrl: string;
|
|
60
|
-
constructor(message: string, upgradeUrl?: string);
|
|
60
|
+
constructor(code: string, message: string, upgradeUrl?: string);
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
63
|
* Create detailed error information for a given error code.
|
|
64
64
|
*
|
|
65
|
+
* Implements white paper's "Developer experience focus - structured error details".
|
|
66
|
+
* Every error includes:
|
|
67
|
+
* - code: Machine-readable identifier (e.g., 'INVALID_DID')
|
|
68
|
+
* - message: Human-readable description of the failure
|
|
69
|
+
* - cause: Root cause explanation (from 'hint' field)
|
|
70
|
+
* - resolution: Actionable suggestion for resolution (from 'suggested_action')
|
|
71
|
+
* - field: Specific field that caused the error (when applicable)
|
|
72
|
+
* - docs: Documentation URL for additional context
|
|
73
|
+
*
|
|
65
74
|
* @param code - Error code (e.g., 'INVALID_DID')
|
|
66
|
-
* @param additionalContext - Optional context (field name, custom hint)
|
|
67
|
-
* @returns ACIErrorDetail with code, message,
|
|
75
|
+
* @param additionalContext - Optional context (field name, custom hint/resolution)
|
|
76
|
+
* @returns ACIErrorDetail with code, message, cause, resolution, field, and docs
|
|
68
77
|
*/
|
|
69
78
|
export declare function createXBindErrorDetail(code: string, additionalContext?: {
|
|
70
79
|
field?: string;
|
|
71
80
|
hint?: string;
|
|
81
|
+
resolution?: string;
|
|
72
82
|
}): ACIErrorDetail;
|
|
73
83
|
/**
|
|
74
84
|
* Convert a string error code to a typed XBindError instance.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDetailedError}from"./_deps/ux-helpers/index.js";const DOC_BASE="https://private.me/docs/xbind";export class XBindError extends Error{code;subCode;docUrl;constructor(e,t,i){super(t),this.name="XBindError";const r=e.split(":");this.code=r[0]??e,this.subCode=r.length>1?r.slice(1).join(":"):void 0,this.docUrl=i}}export class XBindIdentityError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#identity`),this.name="XBindIdentityError"}}export class XBindEnvelopeError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#envelope`),this.name="XBindEnvelopeError"}}export class XBindTransportError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#transport`),this.name="XBindTransportError"}}export class XBindRegistryError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#registry`),this.name="XBindRegistryError"}}export class XBindKeyAgreementError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#key-agreement`),this.name="XBindKeyAgreementError"}}export class XBindSplitChannelError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#split-channel`),this.name="XBindSplitChannelError"}}export class XBindAgentError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#agent`),this.name="XBindAgentError"}}export class XBindBillingError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#billing`),this.name="XBindBillingError"}}export class VaultStoreError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#vault-store`),this.name="VaultStoreError"}}export class QuotaExceededError extends XBindBillingError{upgradeUrl;constructor(e,t){super("QUOTA_EXCEEDED",e),this.name="QuotaExceededError",this.upgradeUrl=t||"https://private.me/subscribe?product=xbind&tier=pro"}}export function createXBindErrorDetail(e,t){const i=e.split(":")[0]??e,r=ERROR_DETAILS[i];return r?createDetailedError(e,r.message,{hint:t?.hint??r.hint,field:t?.field??r.field,docs:r.docs}):createDetailedError(e,`XBind error: ${e}`,{docs:DOC_BASE})}const ERROR_DETAILS={KEYGEN_FAILED:{message:"Key generation failed",hint:"Verify Web Crypto API available: Run in HTTPS/localhost (browser) or Node.js 15+ (server). Check browser console for WebCryptoAPI warnings.",suggested_action:"Verify runtime environment supports Web Crypto API and retry key generation",severity:"critical",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},SIGN_FAILED:{message:"Signing failed",hint:"Verify private key format is PKCS8 and was imported with extractable:true flag. Check key is not corrupted.",suggested_action:"Verify private key is valid and properly imported with extractable flag",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},VERIFY_FAILED:{message:"Signature verification failed",hint:"Confirm sender public key matches signer identity. Verify message and signature were not truncated or modified in transit.",suggested_action:"Verify sender public key and message integrity before retrying",severity:"critical",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},INVALID_DID:{message:"DID format is invalid",hint:'DID must start with "did:" followed by method name (e.g., did:key:z6Mk...). Use validateDID() helper to check format.',field:"did",suggested_action:"Use validateDID() helper to verify format before processing",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},INVALID_KEY_LENGTH:{message:"Key material has incorrect length",hint:"X25519 keys must be exactly 32 bytes. Log key.length to verify. Check base64 decoding is correct.",suggested_action:"Verify key is exactly 32 bytes and properly base64-decoded",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InvalidParameterValue",grpc:3,http:400},EXPORT_FAILED:{message:"PKCS8 export failed",hint:"Key must be created with extractable:true flag. See https://mdn.io/SubtleCrypto.exportKey for details.",suggested_action:"Create key with extractable:true flag and verify Web Crypto API support",severity:"medium",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},IMPORT_FAILED:{message:"PKCS8 import failed",hint:"Verify PKCS8 format (PEM or raw bytes), algorithm matches (Ed25519/X25519), and key data is not corrupted.",suggested_action:"Validate PKCS8 format and verify key data is not corrupted",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},INVALID_VERSION:{message:"Unsupported envelope version",hint:"This SDK supports versions v1-v4. Check envelope.version field and update SDK or request sender upgrade.",field:"version",suggested_action:"Update SDK or request sender to use compatible version (v1-v4)",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},INVALID_ALG:{message:"Unknown encryption algorithm",hint:"Only AES-256-GCM is supported. Verify envelope.alg value and check sender SDK version.",field:"alg",suggested_action:"Verify sender uses AES-256-GCM algorithm",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},INVALID_NONCE:{message:"Nonce is missing or invalid",hint:"Nonce must be exactly 12 bytes and properly base64-encoded. Ensure nonce is unique per envelope.",field:"nonce",suggested_action:"Verify nonce is 12 bytes and properly base64-encoded",severity:"critical",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},INVALID_FIELDS:{message:"Required envelope fields are missing",hint:"Envelope must have: version, alg, nonce, ciphertext, tag, sender, recipient. Check none are null/undefined.",suggested_action:"Validate all required envelope fields are present",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},ENCRYPT_FAILED:{message:"AES-256-GCM encryption failed",hint:"Verify shared key is exactly 32 bytes, nonce is 12 bytes, and plaintext is valid UTF-8.",suggested_action:"Verify key is 32 bytes and nonce is 12 bytes before encryption",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"InternalFailure",grpc:13,http:500},DECRYPT_FAILED:{message:"Decryption failed",hint:"Verify you are using the correct decryption key. Check ciphertext and authentication tag are not corrupted in transit.",suggested_action:"Verify correct key and check ciphertext integrity",severity:"critical",docs:`${DOC_BASE}#envelope`,aws:"InternalFailure",grpc:13,http:500},PARSE_FAILED:{message:"Envelope deserialization failed",hint:"Validate JSON structure for syntax errors. Check for truncation or corruption. Verify base64 fields are properly encoded.",suggested_action:"Validate JSON structure and check for data corruption",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},SEND_FAILED:{message:"Message send failed",hint:"Check network connectivity and recipient registration. Use exponential backoff retry (2s, 4s, 8s).",suggested_action:"Check network connectivity and retry with exponential backoff",severity:"high",docs:`${DOC_BASE}#transport`,aws:"ServiceUnavailable",grpc:14,http:503},NETWORK_ERROR:{message:"Network request failed",hint:"Verify internet connection and DNS resolution. Ping registry endpoint to check availability.",suggested_action:"Verify internet connection and implement exponential backoff retry",severity:"high",docs:`${DOC_BASE}#transport`,aws:"ServiceUnavailable",grpc:14,http:503},RECIPIENT_UNREACHABLE:{message:"Recipient is unreachable",hint:"Verify recipient email address is correct and recipient is registered with xBind. Ask recipient to verify registration.",field:"to",suggested_action:"Verify recipient is registered with xBind and online",severity:"medium",docs:`${DOC_BASE}#transport`,aws:"ServiceUnavailable",grpc:14,http:503},TIMEOUT:{message:"Transport operation timed out",hint:"Check network latency and registry responsiveness. Increase timeout threshold if needed (default: 30s).",suggested_action:"Increase timeout threshold and check network latency",severity:"medium",docs:`${DOC_BASE}#transport`,aws:"RequestTimeout",grpc:4,http:408},NOT_FOUND:{message:"Agent not found in trust registry",hint:"Recipient may not be registered with xBind yet. Ask recipient to register or verify email address is correct.",field:"to",suggested_action:"Ask recipient to register with xBind",severity:"medium",docs:`${DOC_BASE}#registry`,aws:"ResourceNotFoundException",grpc:5,http:404},ALREADY_REGISTERED:{message:"Agent is already registered",hint:"Use updateAgent() instead of registerAgent() to update existing registration with new keys or metadata.",suggested_action:"Use updateAgent() instead of registerAgent()",severity:"low",docs:`${DOC_BASE}#registry`,aws:"ResourceAlreadyExists",grpc:6,http:409},REVOKED:{message:"Agent has been revoked from the registry",hint:"Contact registry administrator to determine revocation reason and request re-registration if accidental.",suggested_action:"Contact registry administrator to resolve revocation",severity:"high",docs:`${DOC_BASE}#registry`,aws:"AccessDenied",grpc:7,http:403},DERIVE_FAILED:{message:"ECDH key derivation failed",hint:"Verify peer public key is valid X25519 (32 bytes) and not corrupted. Check algorithm is X25519 ECDH.",suggested_action:"Verify peer public key is valid X25519 and not corrupted",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},KEM_ENCAPSULATE_FAILED:{message:"ML-KEM-768 encapsulation failed",hint:"Verify recipient ML-KEM-768 public key is valid and properly formatted. Confirm post-quantum support is enabled.",suggested_action:"Verify recipient ML-KEM-768 public key and post-quantum support",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},KEM_DECAPSULATE_FAILED:{message:"ML-KEM-768 decapsulation failed",hint:"Verify ciphertext is not truncated and matches this secret key. Confirm ML-KEM library is initialized.",suggested_action:"Verify ciphertext integrity and ML-KEM secret key",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},HKDF_FAILED:{message:"HKDF key derivation failed",hint:"Verify ECDH and KEM shared secrets are valid. Ensure SHA-256 is available and HKDF input size is correct.",suggested_action:"Verify shared secrets are valid and SHA-256 is available",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},MLKEM_NOT_AVAILABLE:{message:"ML-KEM-768 key not available",hint:"Enable post-quantum support: Agent.create({postQuantum: true}). Regenerate identity with PQ keys enabled.",suggested_action:"Create agent with postQuantum: true",severity:"medium",docs:`${DOC_BASE}#key-agreement`},PQ_SIGN_FAILED:{message:"ML-DSA-65 signing failed",hint:"Actions: (1) Verify ML-DSA-65 secret key is valid and not corrupted, (2) Check post-quantum support is enabled, (3) Ensure message to sign is not empty, (4) Review ML-DSA library logs",suggested_action:"Verify ML-DSA-65 secret key and post-quantum support",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},PQ_VERIFY_FAILED:{message:"ML-DSA-65 verification failed",hint:"Actions: (1) Verify public key matches signer, (2) Check signature format and encoding, (3) Confirm message matches what was signed, (4) Ensure post-quantum keys are synchronized",suggested_action:"Verify signer public key and signature format",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},SPLIT_FAILED:{message:"XorIDA split failed",hint:"Verify threshold >= 2 and <= shareCount. Ensure payload < 1MB. Check system has sufficient memory.",suggested_action:"Verify threshold parameters and payload size",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"InternalFailure",grpc:13,http:500},INSUFFICIENT_SHARES:{message:"Not enough shares to reconstruct",hint:"Log current share count and compare to threshold requirement. Collect more shares from recipients matching the split group ID.",suggested_action:"Collect more shares to meet threshold requirement",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"ValidationException",grpc:3,http:400},INCONSISTENT_SHARES:{message:"Shares have mismatched group IDs or lengths",hint:"Verify all shares have matching group IDs and identical lengths. Discard mismatched shares and request correct ones.",suggested_action:"Verify all shares are from the same split operation",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"ValidationException",grpc:3,http:400},HMAC_VERIFICATION_FAILED:{message:"Share HMAC check failed",hint:"Share may be corrupted in transit or tampered with. Request fresh share from sender using same HMAC key.",suggested_action:"Request fresh share from sender",severity:"critical",docs:`${DOC_BASE}#split-channel`,aws:"UnauthorizedOperation",grpc:16,http:401},UNPAD_FAILED:{message:"Padding removal failed after reconstruction",hint:"Verify reconstruction succeeded and data is valid UTF-8. Check padding algorithm is PKCS7.",suggested_action:"Verify reconstruction succeeded and data is valid UTF-8",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"InternalFailure",grpc:13,http:500},INVALID_SHARE_DATA:{message:"Share data is malformed",hint:"Verify share is valid base64 and has correct structure. Log raw bytes to inspect. Request correctly-formatted share.",suggested_action:"Verify share is valid base64 and request correctly-formatted share",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"ValidationException",grpc:3,http:400},XCHANGE_KEYGEN_FAILED:{message:"Xchange key generation failed",hint:"Verify Web Crypto API available (HTTPS/localhost). Check runtime supports key generation with sufficient entropy.",suggested_action:"Verify Web Crypto API available and retry",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"InternalFailure",grpc:13,http:500},XCHANGE_ENCRYPT_FAILED:{message:"Xchange bundle encryption failed",hint:"Verify payload < 64KB, encryption key is 32 bytes, and bundle structure is valid.",suggested_action:"Verify payload size and encryption key length",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"InternalFailure",grpc:13,http:500},XCHANGE_DECRYPT_FAILED:{message:"Xchange bundle decryption failed",hint:"Verify decryption key matches encryption key and bundle integrity is valid (auth tag correct).",suggested_action:"Verify reconstruction completed and decryption key is correct",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"InternalFailure",grpc:13,http:500},INVALID_BUNDLE:{message:"Xchange bundle is malformed",hint:"Verify bundle size >= 60 bytes (32B key + 12B IV + 16B tag). Check structure and request correctly-formed bundle.",suggested_action:"Verify bundle size and request correctly-formed bundle",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"ValidationException",grpc:3,http:400},IDENTITY_FAILED:{message:"Agent identity creation failed",hint:"Verify Web Crypto API is available (HTTPS/localhost context, Node.js 15+, or modern browser).",suggested_action:"Verify Web Crypto API available and retry agent initialization",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"InternalFailure",grpc:13,http:500},REGISTRATION_FAILED:{message:"Agent registration with trust registry failed",hint:"Verify registry URL is reachable and auth token is valid and not expired. Check registry status page.",suggested_action:"Verify registry URL and auth token, then retry with exponential backoff",severity:"high",docs:`${DOC_BASE}#agent`,aws:"ServiceUnavailable",grpc:14,http:503},RECIPIENT_NOT_FOUND:{message:"Recipient agent not found in registry",hint:"Verify recipient email/DID is correct. Ask recipient to register with xBind first. Allow time for registration to propagate.",field:"to",suggested_action:"Ask recipient to register with xBind",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"ResourceNotFoundException",grpc:5,http:404},RECIPIENT_REVOKED:{message:"Recipient agent has been revoked",hint:"Inform recipient to contact registry administrator to determine revocation reason and request re-registration if accidental.",field:"to",suggested_action:"Inform recipient to contact registry administrator",severity:"high",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},KEY_AGREEMENT_FAILED:{message:"ECDH key agreement with recipient failed",hint:"Verify recipient public key is valid X25519 (32 bytes). Request fresh key from recipient.",suggested_action:"Request fresh key from recipient",severity:"high",docs:`${DOC_BASE}#agent`,aws:"InternalFailure",grpc:13,http:500},ENVELOPE_FAILED:{message:"Envelope creation failed",hint:"Verify payload < 10MB, recipient DID is valid, sender identity is set, and all required fields present.",suggested_action:"Verify payload size and recipient DID",severity:"high",docs:`${DOC_BASE}#agent`,aws:"InternalFailure",grpc:13,http:500},VERIFICATION_FAILED:{message:"Incoming envelope verification failed",hint:"Verify sender DID is in trust registry, sender signature is valid, and sender is not revoked. Review trust policy settings.",suggested_action:"Verify sender is in trust registry and not revoked",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"UnauthorizedOperation",grpc:16,http:401},REPLAY_DETECTED:{message:"Duplicate nonce detected — possible replay attack",hint:"DISCARD MESSAGE immediately for security. Log nonce and sender DID. Alert user to potential attack.",suggested_action:"DISCARD MESSAGE and alert user to potential replay attack",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},SCOPE_DENIED:{message:"Sender does not have permission for the requested scope",hint:"Verify scope value is correct. Contact registry admin to grant sender permission for requested scope.",field:"scope",suggested_action:"Contact registry admin to grant permission",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},RECEIVER_SCOPE_DENIED:{message:"Recipient does not accept messages with this scope",hint:"Ask recipient to enable this scope in their settings. Verify scope matches recipient policy.",field:"scope",suggested_action:"Ask recipient to enable scope in settings",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},TIMESTAMP_EXPIRED:{message:"Envelope timestamp is outside the allowed window",hint:"Synchronize system clocks using NTP. Check time difference between sender and receiver.",suggested_action:"Synchronize system clocks using NTP",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"RequestExpired",grpc:9,http:412},INCOMPATIBLE_VERSION:{message:"Client version is incompatible with server",hint:"Update xBind SDK to latest version. Check minimum supported version in documentation.",suggested_action:"Update xBind SDK to latest version",severity:"high",docs:`${DOC_BASE}#agent`,aws:"ValidationException",grpc:3,http:400},FEATURE_NOT_SUPPORTED:{message:"Requested feature is not supported",hint:"Verify SDK version supports this feature and it is available in current plan. Consider upgrading.",suggested_action:"Check feature availability in current plan or SDK version",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"ValidationException",grpc:12,http:501},QUOTA_EXCEEDED:{message:"Operation quota exceeded",hint:"Check usage against plan limits. Implement rate limiting or upgrade to higher tier plan.",suggested_action:"Implement rate limiting or upgrade plan",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"ThrottlingException",grpc:8,http:429},ACCOUNT_SUSPENDED:{message:"Account has been suspended",hint:"Contact support to determine suspension reason. Review terms of service and resolve any payment or policy issues.",suggested_action:"Contact support to resolve suspension",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"AccessDeniedException",grpc:7,http:403},ACCOUNT_NOT_FOUND:{message:"Account does not exist",hint:"Verify account identifier is correct. Check if account was deleted. Create new account if needed.",suggested_action:"Verify account identifier or create new account",severity:"high",docs:`${DOC_BASE}#agent`,aws:"ResourceNotFoundException",grpc:5,http:404},BILLING_FAILURE:{message:"Billing operation failed",hint:"Verify payment method is valid and not expired. Check Stripe account status. Review billing logs.",suggested_action:"Verify payment method and check billing logs",severity:"high",docs:`${DOC_BASE}#billing`,aws:"RequestLimitExceeded",grpc:8,http:402},PAYMENT_REQUIRED:{message:"Payment required to access this resource",hint:"Add payment method in account settings and subscribe to appropriate tier.",suggested_action:"Add payment method and subscribe to access this resource",severity:"medium",docs:`${DOC_BASE}#billing`,aws:"AccessDenied",grpc:7,http:402},SUBSCRIPTION_REQUIRED:{message:"Valid subscription required",hint:"Subscribe to a paid tier in account settings. Verify subscription is active and not expired.",suggested_action:"Subscribe to a paid tier to access this feature",severity:"medium",docs:`${DOC_BASE}#billing`,aws:"AccessDenied",grpc:7,http:403},TIER_LIMIT_EXCEEDED:{message:"Current tier usage limit exceeded",hint:"Check current usage vs tier limits. Upgrade to higher tier for increased limits or wait for monthly reset.",suggested_action:"Upgrade to higher tier or wait for limit reset",severity:"medium",docs:`${DOC_BASE}#billing`,aws:"RequestLimitExceeded",grpc:8,http:403},VERIFICATION_REQUIRED:{message:"Account verification required",hint:"Complete email and payment method verification. Check account verification status in settings.",suggested_action:"Complete account verification steps in settings",severity:"high",docs:`${DOC_BASE}#billing`,aws:"AccessDenied",grpc:7,http:403},VAULT_FETCH_FAILED:{message:"Failed to fetch crypto package from Vault Store",hint:"Check network connectivity to private.me. Verify Vault Store endpoint is reachable. Try again in a few moments.",suggested_action:"Verify network connectivity and retry with exponential backoff",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"ServiceUnavailable",grpc:14,http:503},VAULT_AUTH_FAILED:{message:"Vault Store authentication failed",hint:"DID signature verification failed. Verify agent identity is valid and properly initialized. Check system clock is synchronized.",suggested_action:"Verify agent identity and synchronize system clock (NTP)",severity:"critical",docs:`${DOC_BASE}#vault-store`,aws:"UnauthorizedOperation",grpc:16,http:401},VAULT_QUOTA_EXCEEDED:{message:"Monthly usage quota exceeded",hint:"Free tier allows 100,000 operations per month (120,000 with grace buffer). Upgrade to Pro tier for unlimited access at $5 per 100K operations.",suggested_action:"Upgrade to Pro tier: https://private.me/subscribe?product=xbind&tier=pro",severity:"medium",docs:`${DOC_BASE}#vault-store`,aws:"RequestLimitExceeded",grpc:8,http:402},VAULT_PAYMENT_REQUIRED:{message:"Payment required to access Vault Store",hint:"Subscription expired or payment method failed. Update payment method and verify subscription is active.",suggested_action:"Update payment method and verify subscription status",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"AccessDenied",grpc:7,http:451},VAULT_LOAD_FAILED:{message:"Failed to load crypto package",hint:"Crypto bundle evaluation failed. This may indicate corrupted bundle or incompatible version. Contact support if issue persists.",suggested_action:"Clear cache and retry. Contact support if issue persists.",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"InternalFailure",grpc:13,http:500},VAULT_INVALID_RESPONSE:{message:"Invalid response from Vault Store",hint:"Server returned malformed data. This may indicate version mismatch or server issue. Try updating SDK or contact support.",suggested_action:"Update xBind SDK to latest version or contact support",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"InternalFailure",grpc:13,http:500}},ERROR_MESSAGES={KEYGEN_FAILED:[XBindIdentityError,"Key generation failed. Actions: (1) Verify Web Crypto API is available in HTTPS or localhost, (2) Check runtime is Node.js 15+ or modern browser, (3) Retry initialization."],SIGN_FAILED:[XBindIdentityError,"Signing failed. Actions: (1) Verify private key is valid and not corrupted, (2) Check key was properly imported, (3) Ensure key is extractable."],VERIFY_FAILED:[XBindIdentityError,"Signature verification failed. Actions: (1) Confirm public key matches signer, (2) Check message integrity, (3) Verify signature format is valid base64."],INVALID_DID:[XBindIdentityError,"The DID string is malformed. Actions: (1) Verify format: did:key:z6Mk..., (2) Check no extra whitespace, (3) Use validateDID() helper."],INVALID_KEY_LENGTH:[XBindKeyAgreementError,"Key material is the wrong length. Actions: (1) Verify X25519 key is exactly 32 bytes, (2) Check base64 decoding, (3) Log key.length to confirm."],EXPORT_FAILED:[XBindIdentityError,"PKCS8 export failed. Actions: (1) Create key with extractable:true, (2) Check Web Crypto support, (3) See: https://mdn.io/SubtleCrypto.exportKey."],IMPORT_FAILED:[XBindIdentityError,"PKCS8 import failed. Actions: (1) Validate PKCS8 format (PEM or bytes), (2) Decode base64 if needed, (3) Check algorithm (Ed25519/X25519)."],INVALID_VERSION:[XBindEnvelopeError,"Unsupported envelope version. Actions: (1) Check envelope.version field, (2) Verify sender uses v1-v4, (3) Request sender SDK update."],INVALID_ALG:[XBindEnvelopeError,'Unknown encryption algorithm. Actions: (1) Verify envelope.alg === "AES-256-GCM", (2) Log alg value to debug, (3) Check sender SDK version.'],INVALID_NONCE:[XBindEnvelopeError,"Nonce is missing or invalid. Actions: (1) Verify nonce exists and is 12 bytes, (2) Check base64 decoding, (3) Inspect replay buffer."],INVALID_FIELDS:[XBindEnvelopeError,"Required envelope fields are missing. Actions: (1) Verify sender/recipient DIDs, (2) Check payload exists, (3) Validate: version, alg, nonce, ciphertext, tag."],ENCRYPT_FAILED:[XBindEnvelopeError,"AES-256-GCM encryption failed. Actions: (1) Verify key is exactly 32 bytes, (2) Check plaintext is valid, (3) Ensure nonce is 12 bytes."],DECRYPT_FAILED:[XBindEnvelopeError,"Decryption failed. Actions: (1) Verify correct key is being used, (2) Check ciphertext integrity, (3) Confirm auth tag is valid."],PARSE_FAILED:[XBindEnvelopeError,"Envelope deserialization failed. Actions: (1) Validate JSON structure, (2) Check for truncation, (3) Verify base64 encoding of fields."],SEND_FAILED:[XBindTransportError,"Message send failed. Actions: (1) Check network connectivity (ping registry), (2) Verify recipient address, (3) Confirm recipient registered, (4) Retry with backoff."],NETWORK_ERROR:[XBindTransportError,"Network request failed. Actions: (1) Verify internet connection, (2) Check DNS resolution, (3) Ping registry endpoint, (4) Implement exponential backoff (2s, 4s, 8s)."],RECIPIENT_UNREACHABLE:[XBindTransportError,"Recipient is unreachable. Actions: (1) Verify recipient email is correct, (2) Check if recipient is registered, (3) Confirm recipient is online, (4) Provide human follow-up."],TIMEOUT:[XBindTransportError,"Transport operation timed out. Actions: (1) Increase timeout threshold, (2) Check network latency, (3) Verify registry responsiveness, (4) Retry operation."],NOT_FOUND:[XBindRegistryError,"Agent not found in trust registry. Actions: (1) Ask recipient to register with xBind, (2) Verify recipient email/DID, (3) Check registration status, (4) Retry after propagation."],ALREADY_REGISTERED:[XBindRegistryError,"Agent is already registered. Actions: (1) Use updateAgent() instead, (2) Provide new keys or metadata, (3) Verify DID matches existing entry."],REVOKED:[XBindRegistryError,"Agent has been revoked from the registry. Actions: (1) Contact registry admin, (2) Check revocation reason, (3) Request re-registration if accidental."],DERIVE_FAILED:[XBindKeyAgreementError,"ECDH key derivation failed. Actions: (1) Verify peer public key is valid X25519 (32 bytes), (2) Check key is not corrupted, (3) Confirm X25519 ECDH support."],KEM_ENCAPSULATE_FAILED:[XBindKeyAgreementError,"ML-KEM-768 encapsulation failed. Actions: (1) Verify recipient key is valid ML-KEM-768, (2) Check key format, (3) Confirm post-quantum support enabled."],KEM_DECAPSULATE_FAILED:[XBindKeyAgreementError,"ML-KEM-768 decapsulation failed. Actions: (1) Verify ciphertext integrity, (2) Check secret key is valid, (3) Confirm ciphertext matches key."],HKDF_FAILED:[XBindKeyAgreementError,"HKDF key derivation failed. Actions: (1) Verify both shared secrets are valid, (2) Check HKDF input size, (3) Ensure SHA-256 support."],MLKEM_NOT_AVAILABLE:[XBindKeyAgreementError,"ML-KEM-768 key not available. Actions: (1) Create agent with postQuantum: true, (2) Check runtime supports ML-KEM-768, (3) Regenerate identity with PQ enabled."],PQ_SIGN_FAILED:[XBindIdentityError,"ML-DSA-65 signing failed. Actions: (1) Verify secret key is valid, (2) Check post-quantum support enabled, (3) Ensure message is not empty."],PQ_VERIFY_FAILED:[XBindIdentityError,"ML-DSA-65 verification failed. Actions: (1) Verify public key matches signer, (2) Check signature format, (3) Confirm message integrity."],SPLIT_FAILED:[XBindSplitChannelError,"XorIDA split failed. Actions: (1) Verify threshold <= shareCount, (2) Check threshold >= 2, (3) Validate payload < 1MB."],INSUFFICIENT_SHARES:[XBindSplitChannelError,"Not enough shares to reconstruct. Actions: (1) Log number of shares collected, (2) Check threshold requirement, (3) Collect more shares."],INCONSISTENT_SHARES:[XBindSplitChannelError,"Shares have mismatched group IDs or lengths. Actions: (1) Verify all from same split, (2) Check group IDs match, (3) Discard mismatched shares."],HMAC_VERIFICATION_FAILED:[XBindSplitChannelError,"Share HMAC check failed. Actions: (1) Check share integrity in transit, (2) Verify not tampered with, (3) Request fresh share."],UNPAD_FAILED:[XBindSplitChannelError,"Padding removal failed after reconstruction. Actions: (1) Verify reconstruction succeeded, (2) Check data is valid UTF-8, (3) Inspect raw bytes."],INVALID_SHARE_DATA:[XBindSplitChannelError,"Share data is malformed. Actions: (1) Verify share is valid base64, (2) Check TLV structure, (3) Log raw bytes to inspect."],XCHANGE_KEYGEN_FAILED:[XBindKeyAgreementError,"Xchange key generation failed. Actions: (1) Verify Web Crypto available (HTTPS/localhost), (2) Check runtime support, (3) Ensure entropy."],XCHANGE_ENCRYPT_FAILED:[XBindEnvelopeError,"Xchange bundle encryption failed. Actions: (1) Check payload < 64KB, (2) Verify key is 32 bytes, (3) Validate bundle structure."],XCHANGE_DECRYPT_FAILED:[XBindEnvelopeError,"Xchange bundle decryption failed. Actions: (1) Verify reconstruction succeeded, (2) Check key matches encryption key, (3) Confirm bundle integrity."],INVALID_BUNDLE:[XBindSplitChannelError,"Xchange bundle is malformed. Actions: (1) Verify size >= 60 bytes (32B + 12B + 16B), (2) Check structure, (3) Decode to inspect."],IDENTITY_FAILED:[XBindAgentError,"Agent identity creation failed. Actions: (1) Verify Web Crypto available, (2) Check HTTPS/localhost, (3) Ensure Node.js 15+ or modern browser."],REGISTRATION_FAILED:[XBindAgentError,"Agent registration with trust registry failed. Actions: (1) Verify registry URL is correct, (2) Check auth token valid/not expired, (3) Confirm registry online."],RECIPIENT_NOT_FOUND:[XBindAgentError,"Recipient agent not found in registry. Actions: (1) Verify recipient email/DID, (2) Ask recipient to register first, (3) Wait for propagation."],RECIPIENT_REVOKED:[XBindAgentError,"Recipient agent has been revoked. Actions: (1) Inform recipient to contact admin, (2) Verify revocation reason, (3) Request re-registration."],KEY_AGREEMENT_FAILED:[XBindAgentError,"ECDH key agreement with recipient failed. Actions: (1) Verify recipient key valid, (2) Check key format (X25519, 32B), (3) Request fresh key."],ENVELOPE_FAILED:[XBindAgentError,"Envelope creation failed. Actions: (1) Check payload < 10MB, (2) Verify recipient DID valid, (3) Confirm sender identity set."],VERIFICATION_FAILED:[XBindAgentError,"Incoming envelope verification failed. Actions: (1) Check sender in registry, (2) Verify signature valid, (3) Confirm sender not revoked."],REPLAY_DETECTED:[XBindAgentError,"Duplicate nonce detected — possible replay attack. Actions: (1) DISCARD message, (2) Log nonce/sender, (3) Alert user to potential attack."],SCOPE_DENIED:[XBindAgentError,"Sender does not have permission for the requested scope. Actions: (1) Check sender scope in registry, (2) Contact admin to grant, (3) Verify scope value."],RECEIVER_SCOPE_DENIED:[XBindAgentError,"Recipient does not accept messages with this scope. Actions: (1) Check recipient receive scope settings, (2) Ask to enable scope, (3) Verify registry entry."],TIMESTAMP_EXPIRED:[XBindAgentError,"Envelope timestamp is outside the allowed window. Actions: (1) Synchronize system clocks (NTP), (2) Check time difference, (3) Verify no time drift."],INCOMPATIBLE_VERSION:[XBindAgentError,"Client version is incompatible with server. Actions: (1) Update xBind SDK to latest version, (2) Check minimum supported version, (3) Contact support if upgrade not possible."],FEATURE_NOT_SUPPORTED:[XBindAgentError,"Requested feature is not supported. Actions: (1) Check feature availability in plan, (2) Verify SDK version, (3) Consider upgrading plan."],QUOTA_EXCEEDED:[XBindAgentError,"Operation quota exceeded. Actions: (1) Check usage against plan limits, (2) Implement rate limiting, (3) Upgrade plan, (4) Wait for quota reset."],ACCOUNT_SUSPENDED:[XBindAgentError,"Account has been suspended. Actions: (1) Contact support for suspension reason, (2) Review terms compliance, (3) Resolve payment/policy issues."],ACCOUNT_NOT_FOUND:[XBindAgentError,"Account does not exist. Actions: (1) Verify account identifier, (2) Check if account was deleted, (3) Create new account if needed."],BILLING_FAILURE:[XBindBillingError,"Billing operation failed. Actions: (1) Verify payment method is valid and not expired, (2) Check Stripe account status, (3) Review billing logs, (4) Contact support if issue persists."],PAYMENT_REQUIRED:[XBindBillingError,"Payment required to access this resource. Actions: (1) Add payment method in account settings, (2) Subscribe to appropriate tier, (3) Verify billing information is current."],SUBSCRIPTION_REQUIRED:[XBindBillingError,"Valid subscription required. Actions: (1) Subscribe to a paid tier in account settings, (2) Verify subscription is active and not expired, (3) Check billing status."],TIER_LIMIT_EXCEEDED:[XBindBillingError,"Current tier usage limit exceeded. Actions: (1) Upgrade to higher tier for increased limits, (2) Check current usage vs tier limits, (3) Wait for limit reset (typically monthly)."],VERIFICATION_REQUIRED:[XBindBillingError,"Account verification required. Actions: (1) Complete email verification, (2) Verify payment method, (3) Complete identity verification if required, (4) Check account verification status in settings."],VAULT_FETCH_FAILED:[VaultStoreError,"Failed to fetch crypto package from Vault Store. Actions: (1) Check network connectivity to private.me, (2) Verify Vault Store endpoint is reachable, (3) Retry with exponential backoff, (4) Check server status page."],VAULT_AUTH_FAILED:[VaultStoreError,"Vault Store authentication failed. Actions: (1) Verify agent identity is valid, (2) Check DID signature is correct, (3) Synchronize system clock (NTP), (4) Regenerate identity if corrupted."],VAULT_QUOTA_EXCEEDED:[QuotaExceededError,"Monthly usage quota exceeded. Free tier: 100K operations/month (120K with grace). Actions: (1) Upgrade to Pro tier for unlimited access ($5/100K ops), (2) Visit https://private.me/subscribe?product=xbind&tier=pro, (3) Wait for monthly reset (1st of month, 00:00 UTC)."],VAULT_PAYMENT_REQUIRED:[VaultStoreError,"Payment required to access Vault Store. Actions: (1) Update payment method in account settings, (2) Verify subscription is active, (3) Check billing status, (4) Contact support if payment issue persists."],VAULT_LOAD_FAILED:[VaultStoreError,"Failed to load crypto package. Actions: (1) Clear crypto cache and retry, (2) Verify SDK version is compatible, (3) Check bundle integrity, (4) Contact support if issue persists."],VAULT_INVALID_RESPONSE:[VaultStoreError,"Invalid response from Vault Store. Actions: (1) Update xBind SDK to latest version, (2) Check API compatibility, (3) Retry request, (4) Contact support if issue persists."]};export function toXBindError(e){const t=e.split(":")[0]??e,i=ERROR_MESSAGES[t];if(i){const[t,r]=i;return new t(e,r)}return new XBindError(e,`XBind error: ${e}`)}export function isXBindError(e){return e instanceof XBindError}
|
|
1
|
+
import{createDetailedError}from"./_deps/ux-helpers/index.js";const DOC_BASE="https://private.me/docs/xbind";export class XBindError extends Error{code;subCode;docUrl;constructor(e,t,i){super(t),this.name="XBindError";const r=e.split(":");this.code=r[0]??e,this.subCode=r.length>1?r.slice(1).join(":"):void 0,this.docUrl=i}}export class XBindIdentityError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#identity`),this.name="XBindIdentityError"}}export class XBindEnvelopeError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#envelope`),this.name="XBindEnvelopeError"}}export class XBindTransportError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#transport`),this.name="XBindTransportError"}}export class XBindRegistryError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#registry`),this.name="XBindRegistryError"}}export class XBindKeyAgreementError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#key-agreement`),this.name="XBindKeyAgreementError"}}export class XBindSplitChannelError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#split-channel`),this.name="XBindSplitChannelError"}}export class XBindAgentError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#agent`),this.name="XBindAgentError"}}export class XBindBillingError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#billing`),this.name="XBindBillingError"}}export class VaultStoreError extends XBindError{constructor(e,t){super(e,t,`${DOC_BASE}#vault-store`),this.name="VaultStoreError"}}export class QuotaExceededError extends XBindBillingError{upgradeUrl;constructor(e,t,i){super(e,t),this.name="QuotaExceededError",this.upgradeUrl=i||"https://private.me/subscribe?product=xbind&tier=pro"}}export function createXBindErrorDetail(e,t){const i=e.split(":")[0]??e,r=ERROR_DETAILS[i];return r?createDetailedError(e,r.message,{hint:t?.hint??r.hint,field:t?.field??r.field,docs:r.docs}):createDetailedError(e,`XBind error: ${e}`,{docs:DOC_BASE})}const ERROR_DETAILS={KEYGEN_FAILED:{message:"Key generation failed",hint:"Verify Web Crypto API available: Run in HTTPS/localhost (browser) or Node.js 15+ (server). Check browser console for WebCryptoAPI warnings.",suggested_action:"Verify runtime environment supports Web Crypto API and retry key generation",severity:"critical",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},SIGN_FAILED:{message:"Signing failed",hint:"Verify private key format is PKCS8 and was imported with extractable:true flag. Check key is not corrupted.",suggested_action:"Verify private key is valid and properly imported with extractable flag",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},VERIFY_FAILED:{message:"Signature verification failed",hint:"Confirm sender public key matches signer identity. Verify message and signature were not truncated or modified in transit.",suggested_action:"Verify sender public key and message integrity before retrying",severity:"critical",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},INVALID_DID:{message:"DID format is invalid",hint:'DID must start with "did:" followed by method name (e.g., did:key:z6Mk...). Use validateDID() helper to check format.',field:"did",suggested_action:"Use validateDID() helper to verify format before processing",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},INVALID_KEY_LENGTH:{message:"Key material has incorrect length",hint:"X25519 keys must be exactly 32 bytes. Log key.length to verify. Check base64 decoding is correct.",suggested_action:"Verify key is exactly 32 bytes and properly base64-decoded",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InvalidParameterValue",grpc:3,http:400},EXPORT_FAILED:{message:"PKCS8 export failed",hint:"Key must be created with extractable:true flag. See https://mdn.io/SubtleCrypto.exportKey for details.",suggested_action:"Create key with extractable:true flag and verify Web Crypto API support",severity:"medium",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},IMPORT_FAILED:{message:"PKCS8 import failed",hint:"Verify PKCS8 format (PEM or raw bytes), algorithm matches (Ed25519/X25519), and key data is not corrupted.",suggested_action:"Validate PKCS8 format and verify key data is not corrupted",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},INVALID_VERSION:{message:"Unsupported envelope version",hint:"This SDK supports versions v1-v4. Check envelope.version field and update SDK or request sender upgrade.",field:"version",suggested_action:"Update SDK or request sender to use compatible version (v1-v4)",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},INVALID_ALG:{message:"Unknown encryption algorithm",hint:"Only AES-256-GCM is supported. Verify envelope.alg value and check sender SDK version.",field:"alg",suggested_action:"Verify sender uses AES-256-GCM algorithm",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},INVALID_NONCE:{message:"Nonce is missing or invalid",hint:"Nonce must be exactly 12 bytes and properly base64-encoded. Ensure nonce is unique per envelope.",field:"nonce",suggested_action:"Verify nonce is 12 bytes and properly base64-encoded",severity:"critical",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},INVALID_FIELDS:{message:"Required envelope fields are missing",hint:"Envelope must have: version, alg, nonce, ciphertext, tag, sender, recipient. Check none are null/undefined.",suggested_action:"Validate all required envelope fields are present",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},ENCRYPT_FAILED:{message:"AES-256-GCM encryption failed",hint:"Verify shared key is exactly 32 bytes, nonce is 12 bytes, and plaintext is valid UTF-8.",suggested_action:"Verify key is 32 bytes and nonce is 12 bytes before encryption",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"InternalFailure",grpc:13,http:500},DECRYPT_FAILED:{message:"Decryption failed",hint:"Verify you are using the correct decryption key. Check ciphertext and authentication tag are not corrupted in transit.",suggested_action:"Verify correct key and check ciphertext integrity",severity:"critical",docs:`${DOC_BASE}#envelope`,aws:"InternalFailure",grpc:13,http:500},PARSE_FAILED:{message:"Envelope deserialization failed",hint:"Validate JSON structure for syntax errors. Check for truncation or corruption. Verify base64 fields are properly encoded.",suggested_action:"Validate JSON structure and check for data corruption",severity:"high",docs:`${DOC_BASE}#envelope`,aws:"ValidationException",grpc:3,http:400},SEND_FAILED:{message:"Message send failed",hint:"Check network connectivity and recipient registration. Use exponential backoff retry (2s, 4s, 8s).",suggested_action:"Check network connectivity and retry with exponential backoff",severity:"high",docs:`${DOC_BASE}#transport`,aws:"ServiceUnavailable",grpc:14,http:503},NETWORK_ERROR:{message:"Network request failed",hint:"Verify internet connection and DNS resolution. Ping registry endpoint to check availability.",suggested_action:"Verify internet connection and implement exponential backoff retry",severity:"high",docs:`${DOC_BASE}#transport`,aws:"ServiceUnavailable",grpc:14,http:503},RECIPIENT_UNREACHABLE:{message:"Recipient is unreachable",hint:"Verify recipient email address is correct and recipient is registered with xBind. Ask recipient to verify registration.",field:"to",suggested_action:"Verify recipient is registered with xBind and online",severity:"medium",docs:`${DOC_BASE}#transport`,aws:"ServiceUnavailable",grpc:14,http:503},TIMEOUT:{message:"Transport operation timed out",hint:"Check network latency and registry responsiveness. Increase timeout threshold if needed (default: 30s).",suggested_action:"Increase timeout threshold and check network latency",severity:"medium",docs:`${DOC_BASE}#transport`,aws:"RequestTimeout",grpc:4,http:408},NOT_FOUND:{message:"Agent not found in trust registry",hint:"Recipient may not be registered with xBind yet. Ask recipient to register or verify email address is correct.",field:"to",suggested_action:"Ask recipient to register with xBind",severity:"medium",docs:`${DOC_BASE}#registry`,aws:"ResourceNotFoundException",grpc:5,http:404},ALREADY_REGISTERED:{message:"Agent is already registered",hint:"Use updateAgent() instead of registerAgent() to update existing registration with new keys or metadata.",suggested_action:"Use updateAgent() instead of registerAgent()",severity:"low",docs:`${DOC_BASE}#registry`,aws:"ResourceAlreadyExists",grpc:6,http:409},REVOKED:{message:"Agent has been revoked from the registry",hint:"Contact registry administrator to determine revocation reason and request re-registration if accidental.",suggested_action:"Contact registry administrator to resolve revocation",severity:"high",docs:`${DOC_BASE}#registry`,aws:"AccessDenied",grpc:7,http:403},DERIVE_FAILED:{message:"ECDH key derivation failed",hint:"Verify peer public key is valid X25519 (32 bytes) and not corrupted. Check algorithm is X25519 ECDH.",suggested_action:"Verify peer public key is valid X25519 and not corrupted",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},KEM_ENCAPSULATE_FAILED:{message:"ML-KEM-768 encapsulation failed",hint:"Verify recipient ML-KEM-768 public key is valid and properly formatted. Confirm post-quantum support is enabled.",suggested_action:"Verify recipient ML-KEM-768 public key and post-quantum support",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},KEM_DECAPSULATE_FAILED:{message:"ML-KEM-768 decapsulation failed",hint:"Verify ciphertext is not truncated and matches this secret key. Confirm ML-KEM library is initialized.",suggested_action:"Verify ciphertext integrity and ML-KEM secret key",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},HKDF_FAILED:{message:"HKDF key derivation failed",hint:"Verify ECDH and KEM shared secrets are valid. Ensure SHA-256 is available and HKDF input size is correct.",suggested_action:"Verify shared secrets are valid and SHA-256 is available",severity:"high",docs:`${DOC_BASE}#key-agreement`,aws:"InternalFailure",grpc:13,http:500},MLKEM_NOT_AVAILABLE:{message:"ML-KEM-768 key not available",hint:"Enable post-quantum support: Agent.create({postQuantum: true}). Regenerate identity with PQ keys enabled.",suggested_action:"Create agent with postQuantum: true",severity:"medium",docs:`${DOC_BASE}#key-agreement`},PQ_SIGN_FAILED:{message:"ML-DSA-65 signing failed",hint:"Actions: (1) Verify ML-DSA-65 secret key is valid and not corrupted, (2) Check post-quantum support is enabled, (3) Ensure message to sign is not empty, (4) Review ML-DSA library logs",suggested_action:"Verify ML-DSA-65 secret key and post-quantum support",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InternalFailure",grpc:13,http:500},PQ_VERIFY_FAILED:{message:"ML-DSA-65 verification failed",hint:"Actions: (1) Verify public key matches signer, (2) Check signature format and encoding, (3) Confirm message matches what was signed, (4) Ensure post-quantum keys are synchronized",suggested_action:"Verify signer public key and signature format",severity:"high",docs:`${DOC_BASE}#identity`,aws:"InvalidParameterValue",grpc:3,http:400},SPLIT_FAILED:{message:"XorIDA split failed",hint:"Verify threshold >= 2 and <= shareCount. Ensure payload < 1MB. Check system has sufficient memory.",suggested_action:"Verify threshold parameters and payload size",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"InternalFailure",grpc:13,http:500},INSUFFICIENT_SHARES:{message:"Not enough shares to reconstruct",hint:"Log current share count and compare to threshold requirement. Collect more shares from recipients matching the split group ID.",suggested_action:"Collect more shares to meet threshold requirement",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"ValidationException",grpc:3,http:400},INCONSISTENT_SHARES:{message:"Shares have mismatched group IDs or lengths",hint:"Verify all shares have matching group IDs and identical lengths. Discard mismatched shares and request correct ones.",suggested_action:"Verify all shares are from the same split operation",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"ValidationException",grpc:3,http:400},HMAC_VERIFICATION_FAILED:{message:"Share HMAC check failed",hint:"Share may be corrupted in transit or tampered with. Request fresh share from sender using same HMAC key.",suggested_action:"Request fresh share from sender",severity:"critical",docs:`${DOC_BASE}#split-channel`,aws:"UnauthorizedOperation",grpc:16,http:401},UNPAD_FAILED:{message:"Padding removal failed after reconstruction",hint:"Verify reconstruction succeeded and data is valid UTF-8. Check padding algorithm is PKCS7.",suggested_action:"Verify reconstruction succeeded and data is valid UTF-8",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"InternalFailure",grpc:13,http:500},INVALID_SHARE_DATA:{message:"Share data is malformed",hint:"Verify share is valid base64 and has correct structure. Log raw bytes to inspect. Request correctly-formatted share.",suggested_action:"Verify share is valid base64 and request correctly-formatted share",severity:"high",docs:`${DOC_BASE}#split-channel`,aws:"ValidationException",grpc:3,http:400},XCHANGE_KEYGEN_FAILED:{message:"Xchange key generation failed",hint:"Verify Web Crypto API available (HTTPS/localhost). Check runtime supports key generation with sufficient entropy.",suggested_action:"Verify Web Crypto API available and retry",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"InternalFailure",grpc:13,http:500},XCHANGE_ENCRYPT_FAILED:{message:"Xchange bundle encryption failed",hint:"Verify payload < 64KB, encryption key is 32 bytes, and bundle structure is valid.",suggested_action:"Verify payload size and encryption key length",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"InternalFailure",grpc:13,http:500},XCHANGE_DECRYPT_FAILED:{message:"Xchange bundle decryption failed",hint:"Verify decryption key matches encryption key and bundle integrity is valid (auth tag correct).",suggested_action:"Verify reconstruction completed and decryption key is correct",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"InternalFailure",grpc:13,http:500},INVALID_BUNDLE:{message:"Xchange bundle is malformed",hint:"Verify bundle size >= 60 bytes (32B key + 12B IV + 16B tag). Check structure and request correctly-formed bundle.",suggested_action:"Verify bundle size and request correctly-formed bundle",severity:"high",docs:`${DOC_BASE}#xchange`,aws:"ValidationException",grpc:3,http:400},IDENTITY_FAILED:{message:"Agent identity creation failed",hint:"Verify Web Crypto API is available (HTTPS/localhost context, Node.js 15+, or modern browser).",suggested_action:"Verify Web Crypto API available and retry agent initialization",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"InternalFailure",grpc:13,http:500},REGISTRATION_FAILED:{message:"Agent registration with trust registry failed",hint:"Verify registry URL is reachable and auth token is valid and not expired. Check registry status page.",suggested_action:"Verify registry URL and auth token, then retry with exponential backoff",severity:"high",docs:`${DOC_BASE}#agent`,aws:"ServiceUnavailable",grpc:14,http:503},RECIPIENT_NOT_FOUND:{message:"Recipient agent not found in registry",hint:"Verify recipient email/DID is correct. Ask recipient to register with xBind first. Allow time for registration to propagate.",field:"to",suggested_action:"Ask recipient to register with xBind",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"ResourceNotFoundException",grpc:5,http:404},RECIPIENT_REVOKED:{message:"Recipient agent has been revoked",hint:"Inform recipient to contact registry administrator to determine revocation reason and request re-registration if accidental.",field:"to",suggested_action:"Inform recipient to contact registry administrator",severity:"high",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},KEY_AGREEMENT_FAILED:{message:"ECDH key agreement with recipient failed",hint:"Verify recipient public key is valid X25519 (32 bytes). Request fresh key from recipient.",suggested_action:"Request fresh key from recipient",severity:"high",docs:`${DOC_BASE}#agent`,aws:"InternalFailure",grpc:13,http:500},ENVELOPE_FAILED:{message:"Envelope creation failed",hint:"Verify payload < 10MB, recipient DID is valid, sender identity is set, and all required fields present.",suggested_action:"Verify payload size and recipient DID",severity:"high",docs:`${DOC_BASE}#agent`,aws:"InternalFailure",grpc:13,http:500},VERIFICATION_FAILED:{message:"Incoming envelope verification failed",hint:"Verify sender DID is in trust registry, sender signature is valid, and sender is not revoked. Review trust policy settings.",suggested_action:"Verify sender is in trust registry and not revoked",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"UnauthorizedOperation",grpc:16,http:401},REPLAY_DETECTED:{message:"Duplicate nonce detected — possible replay attack",hint:"DISCARD MESSAGE immediately for security. Log nonce and sender DID. Alert user to potential attack.",suggested_action:"DISCARD MESSAGE and alert user to potential replay attack",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},SCOPE_DENIED:{message:"Sender does not have permission for the requested scope",hint:"Verify scope value is correct. Contact registry admin to grant sender permission for requested scope.",field:"scope",suggested_action:"Contact registry admin to grant permission",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},RECEIVER_SCOPE_DENIED:{message:"Recipient does not accept messages with this scope",hint:"Ask recipient to enable this scope in their settings. Verify scope matches recipient policy.",field:"scope",suggested_action:"Ask recipient to enable scope in settings",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"AccessDenied",grpc:7,http:403},TIMESTAMP_EXPIRED:{message:"Envelope timestamp is outside the allowed window",hint:"Synchronize system clocks using NTP. Check time difference between sender and receiver.",suggested_action:"Synchronize system clocks using NTP",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"RequestExpired",grpc:9,http:412},INCOMPATIBLE_VERSION:{message:"Client version is incompatible with server",hint:"Update xBind SDK to latest version. Check minimum supported version in documentation.",suggested_action:"Update xBind SDK to latest version",severity:"high",docs:`${DOC_BASE}#agent`,aws:"ValidationException",grpc:3,http:400},FEATURE_NOT_SUPPORTED:{message:"Requested feature is not supported",hint:"Verify SDK version supports this feature and it is available in current plan. Consider upgrading.",suggested_action:"Check feature availability in current plan or SDK version",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"ValidationException",grpc:12,http:501},QUOTA_EXCEEDED:{message:"Operation quota exceeded",hint:"Check usage against plan limits. Implement rate limiting or upgrade to higher tier plan.",suggested_action:"Implement rate limiting or upgrade plan",severity:"medium",docs:`${DOC_BASE}#agent`,aws:"ThrottlingException",grpc:8,http:429},ACCOUNT_SUSPENDED:{message:"Account has been suspended",hint:"Contact support to determine suspension reason. Review terms of service and resolve any payment or policy issues.",suggested_action:"Contact support to resolve suspension",severity:"critical",docs:`${DOC_BASE}#agent`,aws:"AccessDeniedException",grpc:7,http:403},ACCOUNT_NOT_FOUND:{message:"Account does not exist",hint:"Verify account identifier is correct. Check if account was deleted. Create new account if needed.",suggested_action:"Verify account identifier or create new account",severity:"high",docs:`${DOC_BASE}#agent`,aws:"ResourceNotFoundException",grpc:5,http:404},BILLING_FAILURE:{message:"Billing operation failed",hint:"Verify payment method is valid and not expired. Check Stripe account status. Review billing logs.",suggested_action:"Verify payment method and check billing logs",severity:"high",docs:`${DOC_BASE}#billing`,aws:"RequestLimitExceeded",grpc:8,http:402},PAYMENT_REQUIRED:{message:"Payment required to access this resource",hint:"Add payment method in account settings and subscribe to appropriate tier.",suggested_action:"Add payment method and subscribe to access this resource",severity:"medium",docs:`${DOC_BASE}#billing`,aws:"AccessDenied",grpc:7,http:402},SUBSCRIPTION_REQUIRED:{message:"Valid subscription required",hint:"Subscribe to a paid tier in account settings. Verify subscription is active and not expired.",suggested_action:"Subscribe to a paid tier to access this feature",severity:"medium",docs:`${DOC_BASE}#billing`,aws:"AccessDenied",grpc:7,http:403},TIER_LIMIT_EXCEEDED:{message:"Current tier usage limit exceeded",hint:"Check current usage vs tier limits. Upgrade to higher tier for increased limits or wait for monthly reset.",suggested_action:"Upgrade to higher tier or wait for limit reset",severity:"medium",docs:`${DOC_BASE}#billing`,aws:"RequestLimitExceeded",grpc:8,http:403},VERIFICATION_REQUIRED:{message:"Account verification required",hint:"Complete email and payment method verification. Check account verification status in settings.",suggested_action:"Complete account verification steps in settings",severity:"high",docs:`${DOC_BASE}#billing`,aws:"AccessDenied",grpc:7,http:403},VAULT_FETCH_FAILED:{message:"Failed to fetch crypto package from Vault Store",hint:"Check network connectivity to private.me. Verify Vault Store endpoint is reachable. Try again in a few moments.",suggested_action:"Verify network connectivity and retry with exponential backoff",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"ServiceUnavailable",grpc:14,http:503},VAULT_AUTH_FAILED:{message:"Vault Store authentication failed",hint:"DID signature verification failed. Verify agent identity is valid and properly initialized. Check system clock is synchronized.",suggested_action:"Verify agent identity and synchronize system clock (NTP)",severity:"critical",docs:`${DOC_BASE}#vault-store`,aws:"UnauthorizedOperation",grpc:16,http:401},VAULT_QUOTA_EXCEEDED:{message:"Monthly usage quota exceeded",hint:"Free tier allows 100,000 operations per month (120,000 with grace buffer). Upgrade to Pro tier for unlimited access at $5 per 100K operations.",suggested_action:"Upgrade to Pro tier: https://private.me/subscribe?product=xbind&tier=pro",severity:"medium",docs:`${DOC_BASE}#vault-store`,aws:"RequestLimitExceeded",grpc:8,http:402},VAULT_PAYMENT_REQUIRED:{message:"Payment required to access Vault Store",hint:"Subscription expired or payment method failed. Update payment method and verify subscription is active.",suggested_action:"Update payment method and verify subscription status",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"AccessDenied",grpc:7,http:451},VAULT_LOAD_FAILED:{message:"Failed to load crypto package",hint:"Crypto bundle evaluation failed. This may indicate corrupted bundle or incompatible version. Contact support if issue persists.",suggested_action:"Clear cache and retry. Contact support if issue persists.",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"InternalFailure",grpc:13,http:500},VAULT_INVALID_RESPONSE:{message:"Invalid response from Vault Store",hint:"Server returned malformed data. This may indicate version mismatch or server issue. Try updating SDK or contact support.",suggested_action:"Update xBind SDK to latest version or contact support",severity:"high",docs:`${DOC_BASE}#vault-store`,aws:"InternalFailure",grpc:13,http:500}},ERROR_MESSAGES={KEYGEN_FAILED:[XBindIdentityError,"Key generation failed. Actions: (1) Verify Web Crypto API is available in HTTPS or localhost, (2) Check runtime is Node.js 15+ or modern browser, (3) Retry initialization."],SIGN_FAILED:[XBindIdentityError,"Signing failed. Actions: (1) Verify private key is valid and not corrupted, (2) Check key was properly imported, (3) Ensure key is extractable."],VERIFY_FAILED:[XBindIdentityError,"Signature verification failed. Actions: (1) Confirm public key matches signer, (2) Check message integrity, (3) Verify signature format is valid base64."],INVALID_DID:[XBindIdentityError,"The DID string is malformed. Actions: (1) Verify format: did:key:z6Mk..., (2) Check no extra whitespace, (3) Use validateDID() helper."],INVALID_KEY_LENGTH:[XBindKeyAgreementError,"Key material is the wrong length. Actions: (1) Verify X25519 key is exactly 32 bytes, (2) Check base64 decoding, (3) Log key.length to confirm."],EXPORT_FAILED:[XBindIdentityError,"PKCS8 export failed. Actions: (1) Create key with extractable:true, (2) Check Web Crypto support, (3) See: https://mdn.io/SubtleCrypto.exportKey."],IMPORT_FAILED:[XBindIdentityError,"PKCS8 import failed. Actions: (1) Validate PKCS8 format (PEM or bytes), (2) Decode base64 if needed, (3) Check algorithm (Ed25519/X25519)."],INVALID_VERSION:[XBindEnvelopeError,"Unsupported envelope version. Actions: (1) Check envelope.version field, (2) Verify sender uses v1-v4, (3) Request sender SDK update."],INVALID_ALG:[XBindEnvelopeError,'Unknown encryption algorithm. Actions: (1) Verify envelope.alg === "AES-256-GCM", (2) Log alg value to debug, (3) Check sender SDK version.'],INVALID_NONCE:[XBindEnvelopeError,"Nonce is missing or invalid. Actions: (1) Verify nonce exists and is 12 bytes, (2) Check base64 decoding, (3) Inspect replay buffer."],INVALID_FIELDS:[XBindEnvelopeError,"Required envelope fields are missing. Actions: (1) Verify sender/recipient DIDs, (2) Check payload exists, (3) Validate: version, alg, nonce, ciphertext, tag."],ENCRYPT_FAILED:[XBindEnvelopeError,"AES-256-GCM encryption failed. Actions: (1) Verify key is exactly 32 bytes, (2) Check plaintext is valid, (3) Ensure nonce is 12 bytes."],DECRYPT_FAILED:[XBindEnvelopeError,"Decryption failed. Actions: (1) Verify correct key is being used, (2) Check ciphertext integrity, (3) Confirm auth tag is valid."],PARSE_FAILED:[XBindEnvelopeError,"Envelope deserialization failed. Actions: (1) Validate JSON structure, (2) Check for truncation, (3) Verify base64 encoding of fields."],SEND_FAILED:[XBindTransportError,"Message send failed. Actions: (1) Check network connectivity (ping registry), (2) Verify recipient address, (3) Confirm recipient registered, (4) Retry with backoff."],NETWORK_ERROR:[XBindTransportError,"Network request failed. Actions: (1) Verify internet connection, (2) Check DNS resolution, (3) Ping registry endpoint, (4) Implement exponential backoff (2s, 4s, 8s)."],RECIPIENT_UNREACHABLE:[XBindTransportError,"Recipient is unreachable. Actions: (1) Verify recipient email is correct, (2) Check if recipient is registered, (3) Confirm recipient is online, (4) Provide human follow-up."],TIMEOUT:[XBindTransportError,"Transport operation timed out. Actions: (1) Increase timeout threshold, (2) Check network latency, (3) Verify registry responsiveness, (4) Retry operation."],NOT_FOUND:[XBindRegistryError,"Agent not found in trust registry. Actions: (1) Ask recipient to register with xBind, (2) Verify recipient email/DID, (3) Check registration status, (4) Retry after propagation."],ALREADY_REGISTERED:[XBindRegistryError,"Agent is already registered. Actions: (1) Use updateAgent() instead, (2) Provide new keys or metadata, (3) Verify DID matches existing entry."],REVOKED:[XBindRegistryError,"Agent has been revoked from the registry. Actions: (1) Contact registry admin, (2) Check revocation reason, (3) Request re-registration if accidental."],DERIVE_FAILED:[XBindKeyAgreementError,"ECDH key derivation failed. Actions: (1) Verify peer public key is valid X25519 (32 bytes), (2) Check key is not corrupted, (3) Confirm X25519 ECDH support."],KEM_ENCAPSULATE_FAILED:[XBindKeyAgreementError,"ML-KEM-768 encapsulation failed. Actions: (1) Verify recipient key is valid ML-KEM-768, (2) Check key format, (3) Confirm post-quantum support enabled."],KEM_DECAPSULATE_FAILED:[XBindKeyAgreementError,"ML-KEM-768 decapsulation failed. Actions: (1) Verify ciphertext integrity, (2) Check secret key is valid, (3) Confirm ciphertext matches key."],HKDF_FAILED:[XBindKeyAgreementError,"HKDF key derivation failed. Actions: (1) Verify both shared secrets are valid, (2) Check HKDF input size, (3) Ensure SHA-256 support."],MLKEM_NOT_AVAILABLE:[XBindKeyAgreementError,"ML-KEM-768 key not available. Actions: (1) Create agent with postQuantum: true, (2) Check runtime supports ML-KEM-768, (3) Regenerate identity with PQ enabled."],PQ_SIGN_FAILED:[XBindIdentityError,"ML-DSA-65 signing failed. Actions: (1) Verify secret key is valid, (2) Check post-quantum support enabled, (3) Ensure message is not empty."],PQ_VERIFY_FAILED:[XBindIdentityError,"ML-DSA-65 verification failed. Actions: (1) Verify public key matches signer, (2) Check signature format, (3) Confirm message integrity."],SPLIT_FAILED:[XBindSplitChannelError,"XorIDA split failed. Actions: (1) Verify threshold <= shareCount, (2) Check threshold >= 2, (3) Validate payload < 1MB."],INSUFFICIENT_SHARES:[XBindSplitChannelError,"Not enough shares to reconstruct. Actions: (1) Log number of shares collected, (2) Check threshold requirement, (3) Collect more shares."],INCONSISTENT_SHARES:[XBindSplitChannelError,"Shares have mismatched group IDs or lengths. Actions: (1) Verify all from same split, (2) Check group IDs match, (3) Discard mismatched shares."],HMAC_VERIFICATION_FAILED:[XBindSplitChannelError,"Share HMAC check failed. Actions: (1) Check share integrity in transit, (2) Verify not tampered with, (3) Request fresh share."],UNPAD_FAILED:[XBindSplitChannelError,"Padding removal failed after reconstruction. Actions: (1) Verify reconstruction succeeded, (2) Check data is valid UTF-8, (3) Inspect raw bytes."],INVALID_SHARE_DATA:[XBindSplitChannelError,"Share data is malformed. Actions: (1) Verify share is valid base64, (2) Check TLV structure, (3) Log raw bytes to inspect."],XCHANGE_KEYGEN_FAILED:[XBindKeyAgreementError,"Xchange key generation failed. Actions: (1) Verify Web Crypto available (HTTPS/localhost), (2) Check runtime support, (3) Ensure entropy."],XCHANGE_ENCRYPT_FAILED:[XBindEnvelopeError,"Xchange bundle encryption failed. Actions: (1) Check payload < 64KB, (2) Verify key is 32 bytes, (3) Validate bundle structure."],XCHANGE_DECRYPT_FAILED:[XBindEnvelopeError,"Xchange bundle decryption failed. Actions: (1) Verify reconstruction succeeded, (2) Check key matches encryption key, (3) Confirm bundle integrity."],INVALID_BUNDLE:[XBindSplitChannelError,"Xchange bundle is malformed. Actions: (1) Verify size >= 60 bytes (32B + 12B + 16B), (2) Check structure, (3) Decode to inspect."],IDENTITY_FAILED:[XBindAgentError,"Agent identity creation failed. Actions: (1) Verify Web Crypto available, (2) Check HTTPS/localhost, (3) Ensure Node.js 15+ or modern browser."],REGISTRATION_FAILED:[XBindAgentError,"Agent registration with trust registry failed. Actions: (1) Verify registry URL is correct, (2) Check auth token valid/not expired, (3) Confirm registry online."],RECIPIENT_NOT_FOUND:[XBindAgentError,"Recipient agent not found in registry. Actions: (1) Verify recipient email/DID, (2) Ask recipient to register first, (3) Wait for propagation."],RECIPIENT_REVOKED:[XBindAgentError,"Recipient agent has been revoked. Actions: (1) Inform recipient to contact admin, (2) Verify revocation reason, (3) Request re-registration."],KEY_AGREEMENT_FAILED:[XBindAgentError,"ECDH key agreement with recipient failed. Actions: (1) Verify recipient key valid, (2) Check key format (X25519, 32B), (3) Request fresh key."],ENVELOPE_FAILED:[XBindAgentError,"Envelope creation failed. Actions: (1) Check payload < 10MB, (2) Verify recipient DID valid, (3) Confirm sender identity set."],VERIFICATION_FAILED:[XBindAgentError,"Incoming envelope verification failed. Actions: (1) Check sender in registry, (2) Verify signature valid, (3) Confirm sender not revoked."],REPLAY_DETECTED:[XBindAgentError,"Duplicate nonce detected — possible replay attack. Actions: (1) DISCARD message, (2) Log nonce/sender, (3) Alert user to potential attack."],SCOPE_DENIED:[XBindAgentError,"Sender does not have permission for the requested scope. Actions: (1) Check sender scope in registry, (2) Contact admin to grant, (3) Verify scope value."],RECEIVER_SCOPE_DENIED:[XBindAgentError,"Recipient does not accept messages with this scope. Actions: (1) Check recipient receive scope settings, (2) Ask to enable scope, (3) Verify registry entry."],TIMESTAMP_EXPIRED:[XBindAgentError,"Envelope timestamp is outside the allowed window. Actions: (1) Synchronize system clocks (NTP), (2) Check time difference, (3) Verify no time drift."],INCOMPATIBLE_VERSION:[XBindAgentError,"Client version is incompatible with server. Actions: (1) Update xBind SDK to latest version, (2) Check minimum supported version, (3) Contact support if upgrade not possible."],FEATURE_NOT_SUPPORTED:[XBindAgentError,"Requested feature is not supported. Actions: (1) Check feature availability in plan, (2) Verify SDK version, (3) Consider upgrading plan."],QUOTA_EXCEEDED:[QuotaExceededError,"Operation quota exceeded. Actions: (1) Check usage against plan limits, (2) Implement rate limiting, (3) Upgrade plan, (4) Wait for quota reset."],ACCOUNT_SUSPENDED:[XBindAgentError,"Account has been suspended. Actions: (1) Contact support for suspension reason, (2) Review terms compliance, (3) Resolve payment/policy issues."],ACCOUNT_NOT_FOUND:[XBindAgentError,"Account does not exist. Actions: (1) Verify account identifier, (2) Check if account was deleted, (3) Create new account if needed."],BILLING_FAILURE:[XBindBillingError,"Billing operation failed. Actions: (1) Verify payment method is valid and not expired, (2) Check Stripe account status, (3) Review billing logs, (4) Contact support if issue persists."],PAYMENT_REQUIRED:[XBindBillingError,"Payment required to access this resource. Actions: (1) Add payment method in account settings, (2) Subscribe to appropriate tier, (3) Verify billing information is current."],SUBSCRIPTION_REQUIRED:[XBindBillingError,"Valid subscription required. Actions: (1) Subscribe to a paid tier in account settings, (2) Verify subscription is active and not expired, (3) Check billing status."],TIER_LIMIT_EXCEEDED:[XBindBillingError,"Current tier usage limit exceeded. Actions: (1) Upgrade to higher tier for increased limits, (2) Check current usage vs tier limits, (3) Wait for limit reset (typically monthly)."],VERIFICATION_REQUIRED:[XBindBillingError,"Account verification required. Actions: (1) Complete email verification, (2) Verify payment method, (3) Complete identity verification if required, (4) Check account verification status in settings."],VAULT_FETCH_FAILED:[VaultStoreError,"Failed to fetch crypto package from Vault Store. Actions: (1) Check network connectivity to private.me, (2) Verify Vault Store endpoint is reachable, (3) Retry with exponential backoff, (4) Check server status page."],VAULT_AUTH_FAILED:[VaultStoreError,"Vault Store authentication failed. Actions: (1) Verify agent identity is valid, (2) Check DID signature is correct, (3) Synchronize system clock (NTP), (4) Regenerate identity if corrupted."],VAULT_QUOTA_EXCEEDED:[QuotaExceededError,"Monthly usage quota exceeded. Free tier: 100K operations/month (120K with grace). Actions: (1) Upgrade to Pro tier for unlimited access ($5/100K ops), (2) Visit https://private.me/subscribe?product=xbind&tier=pro, (3) Wait for monthly reset (1st of month, 00:00 UTC)."],VAULT_PAYMENT_REQUIRED:[VaultStoreError,"Payment required to access Vault Store. Actions: (1) Update payment method in account settings, (2) Verify subscription is active, (3) Check billing status, (4) Contact support if payment issue persists."],VAULT_LOAD_FAILED:[VaultStoreError,"Failed to load crypto package. Actions: (1) Clear crypto cache and retry, (2) Verify SDK version is compatible, (3) Check bundle integrity, (4) Contact support if issue persists."],VAULT_INVALID_RESPONSE:[VaultStoreError,"Invalid response from Vault Store. Actions: (1) Update xBind SDK to latest version, (2) Check API compatibility, (3) Retry request, (4) Contact support if issue persists."]};export function toXBindError(e){const t=e.split(":")[0]??e,i=ERROR_MESSAGES[t];if(i){const[t,r]=i;return new t(e,r)}return new XBindError(e,`XBind error: ${e}`)}export function isXBindError(e){return e instanceof XBindError}
|
|
@@ -147,4 +147,8 @@ export declare function createHealthChecker(options?: HealthCheckerOptions): Hea
|
|
|
147
147
|
* app.get('/health/readiness', healthEndpoint(checker, 'readiness'));
|
|
148
148
|
* ```
|
|
149
149
|
*/
|
|
150
|
-
export declare function healthEndpoint(checker: HealthChecker, probe?: ProbeType): (req:
|
|
150
|
+
export declare function healthEndpoint(checker: HealthChecker, probe?: ProbeType): (req: unknown, res: {
|
|
151
|
+
status: (code: number) => {
|
|
152
|
+
json: (data: unknown) => void;
|
|
153
|
+
};
|
|
154
|
+
}) => Promise<void>;
|
|
@@ -147,4 +147,4 @@ export declare function createGotCompat(): {
|
|
|
147
147
|
* const response = await fetch('https://api.example.com/data');
|
|
148
148
|
* ```
|
|
149
149
|
*/
|
|
150
|
-
export declare function wrapFetch(
|
|
150
|
+
export declare function wrapFetch(_fetchImpl: typeof fetch): typeof xfetch;
|