@provenonce/partner 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -53,9 +53,39 @@ type SigilCheckResult = SigilCheckValid | SigilCheckInvalid;
53
53
  * On rate limit: throws ProvenoncePartnerError with status 429
54
54
  */
55
55
  declare function checkSigil(opts: SigilCheckOptions): Promise<SigilCheckResult>;
56
+ interface PartnerSessionOptions {
57
+ /** Your pvp_ partner master key */
58
+ partnerKey: string;
59
+ /** Base URL override (default: https://provenonce.io) */
60
+ baseUrl?: string;
61
+ /** Request timeout in ms (default: 5000) */
62
+ timeoutMs?: number;
63
+ }
64
+ interface PartnerSession {
65
+ /** Short-lived pvt_ token — use this for all subsequent API calls */
66
+ token: string;
67
+ /** ISO 8601 expiry timestamp */
68
+ expiresAt: string;
69
+ /** Seconds until expiry (nominally 3600) */
70
+ expiresInSeconds: number;
71
+ }
72
+ /**
73
+ * Exchange your long-lived pvp_ partner key for a short-lived pvt_ session token.
74
+ *
75
+ * Per D-84: use the pvp_ key only to mint tokens. Use the returned pvt_ token
76
+ * for all subsequent checkSigil() and other partner API calls.
77
+ *
78
+ * The pvt_ token is valid for 1 hour. Recommended: mint once per deployment
79
+ * (e.g. on server startup or in middleware) and reuse until near expiry.
80
+ *
81
+ * @example
82
+ * const session = await createPartnerSession({ partnerKey: process.env.PROVENONCE_PARTNER_KEY! })
83
+ * const result = await checkSigil({ agentHash, partnerKey: session.token })
84
+ */
85
+ declare function createPartnerSession(opts: PartnerSessionOptions): Promise<PartnerSession>;
56
86
  declare class ProvenoncePartnerError extends Error {
57
87
  readonly status: number;
58
88
  constructor(message: string, status: number);
59
89
  }
60
90
 
61
- export { ProvenoncePartnerError, type SigilCheckInvalid, type SigilCheckOptions, type SigilCheckResult, type SigilCheckValid, checkSigil };
91
+ export { type PartnerSession, type PartnerSessionOptions, ProvenoncePartnerError, type SigilCheckInvalid, type SigilCheckOptions, type SigilCheckResult, type SigilCheckValid, checkSigil, createPartnerSession };
package/dist/index.d.ts CHANGED
@@ -53,9 +53,39 @@ type SigilCheckResult = SigilCheckValid | SigilCheckInvalid;
53
53
  * On rate limit: throws ProvenoncePartnerError with status 429
54
54
  */
55
55
  declare function checkSigil(opts: SigilCheckOptions): Promise<SigilCheckResult>;
56
+ interface PartnerSessionOptions {
57
+ /** Your pvp_ partner master key */
58
+ partnerKey: string;
59
+ /** Base URL override (default: https://provenonce.io) */
60
+ baseUrl?: string;
61
+ /** Request timeout in ms (default: 5000) */
62
+ timeoutMs?: number;
63
+ }
64
+ interface PartnerSession {
65
+ /** Short-lived pvt_ token — use this for all subsequent API calls */
66
+ token: string;
67
+ /** ISO 8601 expiry timestamp */
68
+ expiresAt: string;
69
+ /** Seconds until expiry (nominally 3600) */
70
+ expiresInSeconds: number;
71
+ }
72
+ /**
73
+ * Exchange your long-lived pvp_ partner key for a short-lived pvt_ session token.
74
+ *
75
+ * Per D-84: use the pvp_ key only to mint tokens. Use the returned pvt_ token
76
+ * for all subsequent checkSigil() and other partner API calls.
77
+ *
78
+ * The pvt_ token is valid for 1 hour. Recommended: mint once per deployment
79
+ * (e.g. on server startup or in middleware) and reuse until near expiry.
80
+ *
81
+ * @example
82
+ * const session = await createPartnerSession({ partnerKey: process.env.PROVENONCE_PARTNER_KEY! })
83
+ * const result = await checkSigil({ agentHash, partnerKey: session.token })
84
+ */
85
+ declare function createPartnerSession(opts: PartnerSessionOptions): Promise<PartnerSession>;
56
86
  declare class ProvenoncePartnerError extends Error {
57
87
  readonly status: number;
58
88
  constructor(message: string, status: number);
59
89
  }
60
90
 
61
- export { ProvenoncePartnerError, type SigilCheckInvalid, type SigilCheckOptions, type SigilCheckResult, type SigilCheckValid, checkSigil };
91
+ export { type PartnerSession, type PartnerSessionOptions, ProvenoncePartnerError, type SigilCheckInvalid, type SigilCheckOptions, type SigilCheckResult, type SigilCheckValid, checkSigil, createPartnerSession };
package/dist/index.js CHANGED
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ProvenoncePartnerError: () => ProvenoncePartnerError,
24
- checkSigil: () => checkSigil
24
+ checkSigil: () => checkSigil,
25
+ createPartnerSession: () => createPartnerSession
25
26
  });
26
27
  module.exports = __toCommonJS(index_exports);
27
28
  var DEFAULT_BASE_URL = "https://provenonce.io";
@@ -78,6 +79,47 @@ async function checkSigil(opts) {
78
79
  signupUrl: data.signup_url ?? null
79
80
  };
80
81
  }
82
+ async function createPartnerSession(opts) {
83
+ const { partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;
84
+ if (!partnerKey?.startsWith("pvp_")) {
85
+ throw new ProvenoncePartnerError("partnerKey must start with pvp_", 400);
86
+ }
87
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/partner/token`;
88
+ const controller = new AbortController();
89
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
90
+ let res;
91
+ try {
92
+ res = await fetch(url, {
93
+ method: "POST",
94
+ headers: { Authorization: `Bearer ${partnerKey}` },
95
+ signal: controller.signal
96
+ });
97
+ } catch (err) {
98
+ clearTimeout(timer);
99
+ if (err?.name === "AbortError") {
100
+ throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);
101
+ }
102
+ throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);
103
+ } finally {
104
+ clearTimeout(timer);
105
+ }
106
+ if (res.status === 401 || res.status === 403) {
107
+ const body = await res.json().catch(() => ({}));
108
+ throw new ProvenoncePartnerError(body?.error ?? "Partner key rejected", res.status);
109
+ }
110
+ if (res.status === 429) {
111
+ throw new ProvenoncePartnerError("Rate limit exceeded", 429);
112
+ }
113
+ if (!res.ok) {
114
+ throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);
115
+ }
116
+ const data = await res.json();
117
+ return {
118
+ token: data.token,
119
+ expiresAt: data.expires_at,
120
+ expiresInSeconds: data.expires_in_seconds
121
+ };
122
+ }
81
123
  var ProvenoncePartnerError = class extends Error {
82
124
  constructor(message, status) {
83
125
  super(message);
@@ -89,6 +131,7 @@ var ProvenoncePartnerError = class extends Error {
89
131
  // Annotate the CommonJS export names for ESM import in node:
90
132
  0 && (module.exports = {
91
133
  ProvenoncePartnerError,
92
- checkSigil
134
+ checkSigil,
135
+ createPartnerSession
93
136
  });
94
137
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\r\n * @provenonce/partner — Provenonce Partner SDK\r\n *\r\n * For skill developers. Wraps GET /api/v1/sigil/check so any skill can verify\r\n * an agent's SIGIL and get a signup URL in one call.\r\n *\r\n * Usage (server-side only — partner key must never be in a client bundle):\r\n *\r\n * import { checkSigil } from '@provenonce/partner'\r\n *\r\n * const result = await checkSigil({\r\n * agentHash: '0x1234...',\r\n * partnerKey: process.env.PROVENONCE_PARTNER_KEY!,\r\n * })\r\n *\r\n * if (!result.valid) {\r\n * return redirect(result.signupUrl)\r\n * }\r\n */\r\n\r\nconst DEFAULT_BASE_URL = 'https://provenonce.io';\r\nconst DEFAULT_TIMEOUT_MS = 5_000;\r\n\r\n// ── Types ─────────────────────────────────────────────────────────────────────\r\n\r\nexport interface SigilCheckOptions {\r\n /** Agent hash to check (0x-prefixed 64-char hex) */\r\n agentHash: string;\r\n /** Your pvp_ partner key — server-side only, never expose to clients */\r\n partnerKey: string;\r\n /** Base URL override (default: https://provenonce.io) */\r\n baseUrl?: string;\r\n /** Request timeout in ms (default: 5000) */\r\n timeoutMs?: number;\r\n}\r\n\r\n/** Agent has a valid SIGIL */\r\nexport interface SigilCheckValid {\r\n valid: true;\r\n sigil: string;\r\n identityClass: string;\r\n tier: string;\r\n}\r\n\r\n/** Agent has no SIGIL (or is inactive) — signupUrl is pre-built with your ref token */\r\nexport interface SigilCheckInvalid {\r\n valid: false;\r\n reason: 'no_sigil' | 'inactive' | 'not_registered';\r\n /** Pre-built signup URL with your ref token embedded. Redirect the user here. */\r\n signupUrl: string | null;\r\n}\r\n\r\nexport type SigilCheckResult = SigilCheckValid | SigilCheckInvalid;\r\n\r\n// ── Main function ─────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Check whether an agent has a valid SIGIL.\r\n *\r\n * Server-side only. The `partnerKey` (pvp_...) must never be sent to clients.\r\n *\r\n * On success: returns { valid: true, sigil, identityClass, tier }\r\n * On no SIGIL: returns { valid: false, reason, signupUrl } — redirect to signupUrl\r\n * On auth error: throws ProvenoncePartnerError with status 401/403\r\n * On rate limit: throws ProvenoncePartnerError with status 429\r\n */\r\nexport async function checkSigil(opts: SigilCheckOptions): Promise<SigilCheckResult> {\r\n const { agentHash, partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\r\n\r\n if (!agentHash) throw new ProvenoncePartnerError('agentHash is required', 400);\r\n if (!partnerKey?.startsWith('pvp_')) {\r\n throw new ProvenoncePartnerError('partnerKey must start with pvp_', 400);\r\n }\r\n\r\n const url = `${baseUrl.replace(/\\/$/, '')}/api/v1/sigil/check?hash=${encodeURIComponent(agentHash)}`;\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${partnerKey}` },\r\n signal: controller.signal,\r\n });\r\n } catch (err: any) {\r\n clearTimeout(timer);\r\n if (err?.name === 'AbortError') {\r\n throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);\r\n }\r\n throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (res.status === 401 || res.status === 403) {\r\n const body = await res.json().catch(() => ({}));\r\n throw new ProvenoncePartnerError(\r\n (body as any)?.error ?? 'Partner key rejected',\r\n res.status,\r\n );\r\n }\r\n\r\n if (res.status === 429) {\r\n throw new ProvenoncePartnerError('Rate limit exceeded', 429);\r\n }\r\n\r\n if (!res.ok) {\r\n throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);\r\n }\r\n\r\n const data: any = await res.json();\r\n\r\n if (data.valid === true) {\r\n return {\r\n valid: true,\r\n sigil: data.sigil ?? '',\r\n identityClass: data.identity_class ?? '',\r\n tier: data.tier ?? '',\r\n };\r\n }\r\n\r\n return {\r\n valid: false,\r\n reason: data.reason ?? 'no_sigil',\r\n signupUrl: data.signup_url ?? null,\r\n };\r\n}\r\n\r\n// ── Error class ───────────────────────────────────────────────────────────────\r\n\r\nexport class ProvenoncePartnerError extends Error {\r\n readonly status: number;\r\n\r\n constructor(message: string, status: number) {\r\n super(message);\r\n this.name = 'ProvenoncePartnerError';\r\n this.status = status;\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AA6C3B,eAAsB,WAAW,MAAoD;AACnF,QAAM,EAAE,WAAW,YAAY,UAAU,kBAAkB,YAAY,mBAAmB,IAAI;AAE9F,MAAI,CAAC,UAAW,OAAM,IAAI,uBAAuB,yBAAyB,GAAG;AAC7E,MAAI,CAAC,YAAY,WAAW,MAAM,GAAG;AACnC,UAAM,IAAI,uBAAuB,mCAAmC,GAAG;AAAA,EACzE;AAEA,QAAM,MAAM,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC,4BAA4B,mBAAmB,SAAS,CAAC;AAElG,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAE5D,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,SAAS,EAAE,eAAe,UAAU,UAAU,GAAG;AAAA,MACjD,QAAQ,WAAW;AAAA,IACrB,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,iBAAa,KAAK;AAClB,QAAI,KAAK,SAAS,cAAc;AAC9B,YAAM,IAAI,uBAAuB,2BAA2B,SAAS,MAAM,GAAG;AAAA,IAChF;AACA,UAAM,IAAI,uBAAuB,kBAAkB,KAAK,WAAW,GAAG,IAAI,CAAC;AAAA,EAC7E,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AAEA,MAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,UAAM,IAAI;AAAA,MACP,MAAc,SAAS;AAAA,MACxB,IAAI;AAAA,IACN;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,KAAK;AACtB,UAAM,IAAI,uBAAuB,uBAAuB,GAAG;AAAA,EAC7D;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,uBAAuB,wBAAwB,IAAI,MAAM,IAAI,IAAI,MAAM;AAAA,EACnF;AAEA,QAAM,OAAY,MAAM,IAAI,KAAK;AAEjC,MAAI,KAAK,UAAU,MAAM;AACvB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,KAAK,SAAS;AAAA,MACrB,eAAe,KAAK,kBAAkB;AAAA,MACtC,MAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ,KAAK,UAAU;AAAA,IACvB,WAAW,KAAK,cAAc;AAAA,EAChC;AACF;AAIO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAGhD,YAAY,SAAiB,QAAgB;AAC3C,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\r\n * @provenonce/partner — Provenonce Partner SDK\r\n *\r\n * For skill developers. Wraps GET /api/v1/sigil/check so any skill can verify\r\n * an agent's SIGIL and get a signup URL in one call.\r\n *\r\n * Usage (server-side only — partner key must never be in a client bundle):\r\n *\r\n * import { checkSigil } from '@provenonce/partner'\r\n *\r\n * const result = await checkSigil({\r\n * agentHash: '0x1234...',\r\n * partnerKey: process.env.PROVENONCE_PARTNER_KEY!,\r\n * })\r\n *\r\n * if (!result.valid) {\r\n * return redirect(result.signupUrl)\r\n * }\r\n */\r\n\r\nconst DEFAULT_BASE_URL = 'https://provenonce.io';\r\nconst DEFAULT_TIMEOUT_MS = 5_000;\r\n\r\n// ── Types ─────────────────────────────────────────────────────────────────────\r\n\r\nexport interface SigilCheckOptions {\r\n /** Agent hash to check (0x-prefixed 64-char hex) */\r\n agentHash: string;\r\n /** Your pvp_ partner key — server-side only, never expose to clients */\r\n partnerKey: string;\r\n /** Base URL override (default: https://provenonce.io) */\r\n baseUrl?: string;\r\n /** Request timeout in ms (default: 5000) */\r\n timeoutMs?: number;\r\n}\r\n\r\n/** Agent has a valid SIGIL */\r\nexport interface SigilCheckValid {\r\n valid: true;\r\n sigil: string;\r\n identityClass: string;\r\n tier: string;\r\n}\r\n\r\n/** Agent has no SIGIL (or is inactive) — signupUrl is pre-built with your ref token */\r\nexport interface SigilCheckInvalid {\r\n valid: false;\r\n reason: 'no_sigil' | 'inactive' | 'not_registered';\r\n /** Pre-built signup URL with your ref token embedded. Redirect the user here. */\r\n signupUrl: string | null;\r\n}\r\n\r\nexport type SigilCheckResult = SigilCheckValid | SigilCheckInvalid;\r\n\r\n// ── Main function ─────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Check whether an agent has a valid SIGIL.\r\n *\r\n * Server-side only. The `partnerKey` (pvp_...) must never be sent to clients.\r\n *\r\n * On success: returns { valid: true, sigil, identityClass, tier }\r\n * On no SIGIL: returns { valid: false, reason, signupUrl } — redirect to signupUrl\r\n * On auth error: throws ProvenoncePartnerError with status 401/403\r\n * On rate limit: throws ProvenoncePartnerError with status 429\r\n */\r\nexport async function checkSigil(opts: SigilCheckOptions): Promise<SigilCheckResult> {\r\n const { agentHash, partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\r\n\r\n if (!agentHash) throw new ProvenoncePartnerError('agentHash is required', 400);\r\n if (!partnerKey?.startsWith('pvp_')) {\r\n throw new ProvenoncePartnerError('partnerKey must start with pvp_', 400);\r\n }\r\n\r\n const url = `${baseUrl.replace(/\\/$/, '')}/api/v1/sigil/check?hash=${encodeURIComponent(agentHash)}`;\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${partnerKey}` },\r\n signal: controller.signal,\r\n });\r\n } catch (err: any) {\r\n clearTimeout(timer);\r\n if (err?.name === 'AbortError') {\r\n throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);\r\n }\r\n throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (res.status === 401 || res.status === 403) {\r\n const body = await res.json().catch(() => ({}));\r\n throw new ProvenoncePartnerError(\r\n (body as any)?.error ?? 'Partner key rejected',\r\n res.status,\r\n );\r\n }\r\n\r\n if (res.status === 429) {\r\n throw new ProvenoncePartnerError('Rate limit exceeded', 429);\r\n }\r\n\r\n if (!res.ok) {\r\n throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);\r\n }\r\n\r\n const data: any = await res.json();\r\n\r\n if (data.valid === true) {\r\n return {\r\n valid: true,\r\n sigil: data.sigil ?? '',\r\n identityClass: data.identity_class ?? '',\r\n tier: data.tier ?? '',\r\n };\r\n }\r\n\r\n return {\r\n valid: false,\r\n reason: data.reason ?? 'no_sigil',\r\n signupUrl: data.signup_url ?? null,\r\n };\r\n}\r\n\r\n// ── Partner Session Token (D-84) ──────────────────────────────────────────────\r\n\r\nexport interface PartnerSessionOptions {\r\n /** Your pvp_ partner master key */\r\n partnerKey: string;\r\n /** Base URL override (default: https://provenonce.io) */\r\n baseUrl?: string;\r\n /** Request timeout in ms (default: 5000) */\r\n timeoutMs?: number;\r\n}\r\n\r\nexport interface PartnerSession {\r\n /** Short-lived pvt_ token — use this for all subsequent API calls */\r\n token: string;\r\n /** ISO 8601 expiry timestamp */\r\n expiresAt: string;\r\n /** Seconds until expiry (nominally 3600) */\r\n expiresInSeconds: number;\r\n}\r\n\r\n/**\r\n * Exchange your long-lived pvp_ partner key for a short-lived pvt_ session token.\r\n *\r\n * Per D-84: use the pvp_ key only to mint tokens. Use the returned pvt_ token\r\n * for all subsequent checkSigil() and other partner API calls.\r\n *\r\n * The pvt_ token is valid for 1 hour. Recommended: mint once per deployment\r\n * (e.g. on server startup or in middleware) and reuse until near expiry.\r\n *\r\n * @example\r\n * const session = await createPartnerSession({ partnerKey: process.env.PROVENONCE_PARTNER_KEY! })\r\n * const result = await checkSigil({ agentHash, partnerKey: session.token })\r\n */\r\nexport async function createPartnerSession(opts: PartnerSessionOptions): Promise<PartnerSession> {\r\n const { partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\r\n\r\n if (!partnerKey?.startsWith('pvp_')) {\r\n throw new ProvenoncePartnerError('partnerKey must start with pvp_', 400);\r\n }\r\n\r\n const url = `${baseUrl.replace(/\\/$/, '')}/api/v1/partner/token`;\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n method: 'POST',\r\n headers: { Authorization: `Bearer ${partnerKey}` },\r\n signal: controller.signal,\r\n });\r\n } catch (err: any) {\r\n clearTimeout(timer);\r\n if (err?.name === 'AbortError') {\r\n throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);\r\n }\r\n throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (res.status === 401 || res.status === 403) {\r\n const body = await res.json().catch(() => ({}));\r\n throw new ProvenoncePartnerError((body as any)?.error ?? 'Partner key rejected', res.status);\r\n }\r\n\r\n if (res.status === 429) {\r\n throw new ProvenoncePartnerError('Rate limit exceeded', 429);\r\n }\r\n\r\n if (!res.ok) {\r\n throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);\r\n }\r\n\r\n const data: any = await res.json();\r\n return {\r\n token: data.token,\r\n expiresAt: data.expires_at,\r\n expiresInSeconds: data.expires_in_seconds,\r\n };\r\n}\r\n\r\n// ── Error class ───────────────────────────────────────────────────────────────\r\n\r\nexport class ProvenoncePartnerError extends Error {\r\n readonly status: number;\r\n\r\n constructor(message: string, status: number) {\r\n super(message);\r\n this.name = 'ProvenoncePartnerError';\r\n this.status = status;\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -53,6 +53,47 @@ async function checkSigil(opts) {
53
53
  signupUrl: data.signup_url ?? null
54
54
  };
55
55
  }
56
+ async function createPartnerSession(opts) {
57
+ const { partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;
58
+ if (!partnerKey?.startsWith("pvp_")) {
59
+ throw new ProvenoncePartnerError("partnerKey must start with pvp_", 400);
60
+ }
61
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/partner/token`;
62
+ const controller = new AbortController();
63
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
64
+ let res;
65
+ try {
66
+ res = await fetch(url, {
67
+ method: "POST",
68
+ headers: { Authorization: `Bearer ${partnerKey}` },
69
+ signal: controller.signal
70
+ });
71
+ } catch (err) {
72
+ clearTimeout(timer);
73
+ if (err?.name === "AbortError") {
74
+ throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);
75
+ }
76
+ throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);
77
+ } finally {
78
+ clearTimeout(timer);
79
+ }
80
+ if (res.status === 401 || res.status === 403) {
81
+ const body = await res.json().catch(() => ({}));
82
+ throw new ProvenoncePartnerError(body?.error ?? "Partner key rejected", res.status);
83
+ }
84
+ if (res.status === 429) {
85
+ throw new ProvenoncePartnerError("Rate limit exceeded", 429);
86
+ }
87
+ if (!res.ok) {
88
+ throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);
89
+ }
90
+ const data = await res.json();
91
+ return {
92
+ token: data.token,
93
+ expiresAt: data.expires_at,
94
+ expiresInSeconds: data.expires_in_seconds
95
+ };
96
+ }
56
97
  var ProvenoncePartnerError = class extends Error {
57
98
  constructor(message, status) {
58
99
  super(message);
@@ -63,6 +104,7 @@ var ProvenoncePartnerError = class extends Error {
63
104
  };
64
105
  export {
65
106
  ProvenoncePartnerError,
66
- checkSigil
107
+ checkSigil,
108
+ createPartnerSession
67
109
  };
68
110
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\r\n * @provenonce/partner — Provenonce Partner SDK\r\n *\r\n * For skill developers. Wraps GET /api/v1/sigil/check so any skill can verify\r\n * an agent's SIGIL and get a signup URL in one call.\r\n *\r\n * Usage (server-side only — partner key must never be in a client bundle):\r\n *\r\n * import { checkSigil } from '@provenonce/partner'\r\n *\r\n * const result = await checkSigil({\r\n * agentHash: '0x1234...',\r\n * partnerKey: process.env.PROVENONCE_PARTNER_KEY!,\r\n * })\r\n *\r\n * if (!result.valid) {\r\n * return redirect(result.signupUrl)\r\n * }\r\n */\r\n\r\nconst DEFAULT_BASE_URL = 'https://provenonce.io';\r\nconst DEFAULT_TIMEOUT_MS = 5_000;\r\n\r\n// ── Types ─────────────────────────────────────────────────────────────────────\r\n\r\nexport interface SigilCheckOptions {\r\n /** Agent hash to check (0x-prefixed 64-char hex) */\r\n agentHash: string;\r\n /** Your pvp_ partner key — server-side only, never expose to clients */\r\n partnerKey: string;\r\n /** Base URL override (default: https://provenonce.io) */\r\n baseUrl?: string;\r\n /** Request timeout in ms (default: 5000) */\r\n timeoutMs?: number;\r\n}\r\n\r\n/** Agent has a valid SIGIL */\r\nexport interface SigilCheckValid {\r\n valid: true;\r\n sigil: string;\r\n identityClass: string;\r\n tier: string;\r\n}\r\n\r\n/** Agent has no SIGIL (or is inactive) — signupUrl is pre-built with your ref token */\r\nexport interface SigilCheckInvalid {\r\n valid: false;\r\n reason: 'no_sigil' | 'inactive' | 'not_registered';\r\n /** Pre-built signup URL with your ref token embedded. Redirect the user here. */\r\n signupUrl: string | null;\r\n}\r\n\r\nexport type SigilCheckResult = SigilCheckValid | SigilCheckInvalid;\r\n\r\n// ── Main function ─────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Check whether an agent has a valid SIGIL.\r\n *\r\n * Server-side only. The `partnerKey` (pvp_...) must never be sent to clients.\r\n *\r\n * On success: returns { valid: true, sigil, identityClass, tier }\r\n * On no SIGIL: returns { valid: false, reason, signupUrl } — redirect to signupUrl\r\n * On auth error: throws ProvenoncePartnerError with status 401/403\r\n * On rate limit: throws ProvenoncePartnerError with status 429\r\n */\r\nexport async function checkSigil(opts: SigilCheckOptions): Promise<SigilCheckResult> {\r\n const { agentHash, partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\r\n\r\n if (!agentHash) throw new ProvenoncePartnerError('agentHash is required', 400);\r\n if (!partnerKey?.startsWith('pvp_')) {\r\n throw new ProvenoncePartnerError('partnerKey must start with pvp_', 400);\r\n }\r\n\r\n const url = `${baseUrl.replace(/\\/$/, '')}/api/v1/sigil/check?hash=${encodeURIComponent(agentHash)}`;\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${partnerKey}` },\r\n signal: controller.signal,\r\n });\r\n } catch (err: any) {\r\n clearTimeout(timer);\r\n if (err?.name === 'AbortError') {\r\n throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);\r\n }\r\n throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (res.status === 401 || res.status === 403) {\r\n const body = await res.json().catch(() => ({}));\r\n throw new ProvenoncePartnerError(\r\n (body as any)?.error ?? 'Partner key rejected',\r\n res.status,\r\n );\r\n }\r\n\r\n if (res.status === 429) {\r\n throw new ProvenoncePartnerError('Rate limit exceeded', 429);\r\n }\r\n\r\n if (!res.ok) {\r\n throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);\r\n }\r\n\r\n const data: any = await res.json();\r\n\r\n if (data.valid === true) {\r\n return {\r\n valid: true,\r\n sigil: data.sigil ?? '',\r\n identityClass: data.identity_class ?? '',\r\n tier: data.tier ?? '',\r\n };\r\n }\r\n\r\n return {\r\n valid: false,\r\n reason: data.reason ?? 'no_sigil',\r\n signupUrl: data.signup_url ?? null,\r\n };\r\n}\r\n\r\n// ── Error class ───────────────────────────────────────────────────────────────\r\n\r\nexport class ProvenoncePartnerError extends Error {\r\n readonly status: number;\r\n\r\n constructor(message: string, status: number) {\r\n super(message);\r\n this.name = 'ProvenoncePartnerError';\r\n this.status = status;\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n"],"mappings":";AAoBA,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AA6C3B,eAAsB,WAAW,MAAoD;AACnF,QAAM,EAAE,WAAW,YAAY,UAAU,kBAAkB,YAAY,mBAAmB,IAAI;AAE9F,MAAI,CAAC,UAAW,OAAM,IAAI,uBAAuB,yBAAyB,GAAG;AAC7E,MAAI,CAAC,YAAY,WAAW,MAAM,GAAG;AACnC,UAAM,IAAI,uBAAuB,mCAAmC,GAAG;AAAA,EACzE;AAEA,QAAM,MAAM,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC,4BAA4B,mBAAmB,SAAS,CAAC;AAElG,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAE5D,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,SAAS,EAAE,eAAe,UAAU,UAAU,GAAG;AAAA,MACjD,QAAQ,WAAW;AAAA,IACrB,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,iBAAa,KAAK;AAClB,QAAI,KAAK,SAAS,cAAc;AAC9B,YAAM,IAAI,uBAAuB,2BAA2B,SAAS,MAAM,GAAG;AAAA,IAChF;AACA,UAAM,IAAI,uBAAuB,kBAAkB,KAAK,WAAW,GAAG,IAAI,CAAC;AAAA,EAC7E,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AAEA,MAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,UAAM,IAAI;AAAA,MACP,MAAc,SAAS;AAAA,MACxB,IAAI;AAAA,IACN;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,KAAK;AACtB,UAAM,IAAI,uBAAuB,uBAAuB,GAAG;AAAA,EAC7D;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,uBAAuB,wBAAwB,IAAI,MAAM,IAAI,IAAI,MAAM;AAAA,EACnF;AAEA,QAAM,OAAY,MAAM,IAAI,KAAK;AAEjC,MAAI,KAAK,UAAU,MAAM;AACvB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,KAAK,SAAS;AAAA,MACrB,eAAe,KAAK,kBAAkB;AAAA,MACtC,MAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ,KAAK,UAAU;AAAA,IACvB,WAAW,KAAK,cAAc;AAAA,EAChC;AACF;AAIO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAGhD,YAAY,SAAiB,QAAgB;AAC3C,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\r\n * @provenonce/partner — Provenonce Partner SDK\r\n *\r\n * For skill developers. Wraps GET /api/v1/sigil/check so any skill can verify\r\n * an agent's SIGIL and get a signup URL in one call.\r\n *\r\n * Usage (server-side only — partner key must never be in a client bundle):\r\n *\r\n * import { checkSigil } from '@provenonce/partner'\r\n *\r\n * const result = await checkSigil({\r\n * agentHash: '0x1234...',\r\n * partnerKey: process.env.PROVENONCE_PARTNER_KEY!,\r\n * })\r\n *\r\n * if (!result.valid) {\r\n * return redirect(result.signupUrl)\r\n * }\r\n */\r\n\r\nconst DEFAULT_BASE_URL = 'https://provenonce.io';\r\nconst DEFAULT_TIMEOUT_MS = 5_000;\r\n\r\n// ── Types ─────────────────────────────────────────────────────────────────────\r\n\r\nexport interface SigilCheckOptions {\r\n /** Agent hash to check (0x-prefixed 64-char hex) */\r\n agentHash: string;\r\n /** Your pvp_ partner key — server-side only, never expose to clients */\r\n partnerKey: string;\r\n /** Base URL override (default: https://provenonce.io) */\r\n baseUrl?: string;\r\n /** Request timeout in ms (default: 5000) */\r\n timeoutMs?: number;\r\n}\r\n\r\n/** Agent has a valid SIGIL */\r\nexport interface SigilCheckValid {\r\n valid: true;\r\n sigil: string;\r\n identityClass: string;\r\n tier: string;\r\n}\r\n\r\n/** Agent has no SIGIL (or is inactive) — signupUrl is pre-built with your ref token */\r\nexport interface SigilCheckInvalid {\r\n valid: false;\r\n reason: 'no_sigil' | 'inactive' | 'not_registered';\r\n /** Pre-built signup URL with your ref token embedded. Redirect the user here. */\r\n signupUrl: string | null;\r\n}\r\n\r\nexport type SigilCheckResult = SigilCheckValid | SigilCheckInvalid;\r\n\r\n// ── Main function ─────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Check whether an agent has a valid SIGIL.\r\n *\r\n * Server-side only. The `partnerKey` (pvp_...) must never be sent to clients.\r\n *\r\n * On success: returns { valid: true, sigil, identityClass, tier }\r\n * On no SIGIL: returns { valid: false, reason, signupUrl } — redirect to signupUrl\r\n * On auth error: throws ProvenoncePartnerError with status 401/403\r\n * On rate limit: throws ProvenoncePartnerError with status 429\r\n */\r\nexport async function checkSigil(opts: SigilCheckOptions): Promise<SigilCheckResult> {\r\n const { agentHash, partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\r\n\r\n if (!agentHash) throw new ProvenoncePartnerError('agentHash is required', 400);\r\n if (!partnerKey?.startsWith('pvp_')) {\r\n throw new ProvenoncePartnerError('partnerKey must start with pvp_', 400);\r\n }\r\n\r\n const url = `${baseUrl.replace(/\\/$/, '')}/api/v1/sigil/check?hash=${encodeURIComponent(agentHash)}`;\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n headers: { Authorization: `Bearer ${partnerKey}` },\r\n signal: controller.signal,\r\n });\r\n } catch (err: any) {\r\n clearTimeout(timer);\r\n if (err?.name === 'AbortError') {\r\n throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);\r\n }\r\n throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (res.status === 401 || res.status === 403) {\r\n const body = await res.json().catch(() => ({}));\r\n throw new ProvenoncePartnerError(\r\n (body as any)?.error ?? 'Partner key rejected',\r\n res.status,\r\n );\r\n }\r\n\r\n if (res.status === 429) {\r\n throw new ProvenoncePartnerError('Rate limit exceeded', 429);\r\n }\r\n\r\n if (!res.ok) {\r\n throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);\r\n }\r\n\r\n const data: any = await res.json();\r\n\r\n if (data.valid === true) {\r\n return {\r\n valid: true,\r\n sigil: data.sigil ?? '',\r\n identityClass: data.identity_class ?? '',\r\n tier: data.tier ?? '',\r\n };\r\n }\r\n\r\n return {\r\n valid: false,\r\n reason: data.reason ?? 'no_sigil',\r\n signupUrl: data.signup_url ?? null,\r\n };\r\n}\r\n\r\n// ── Partner Session Token (D-84) ──────────────────────────────────────────────\r\n\r\nexport interface PartnerSessionOptions {\r\n /** Your pvp_ partner master key */\r\n partnerKey: string;\r\n /** Base URL override (default: https://provenonce.io) */\r\n baseUrl?: string;\r\n /** Request timeout in ms (default: 5000) */\r\n timeoutMs?: number;\r\n}\r\n\r\nexport interface PartnerSession {\r\n /** Short-lived pvt_ token — use this for all subsequent API calls */\r\n token: string;\r\n /** ISO 8601 expiry timestamp */\r\n expiresAt: string;\r\n /** Seconds until expiry (nominally 3600) */\r\n expiresInSeconds: number;\r\n}\r\n\r\n/**\r\n * Exchange your long-lived pvp_ partner key for a short-lived pvt_ session token.\r\n *\r\n * Per D-84: use the pvp_ key only to mint tokens. Use the returned pvt_ token\r\n * for all subsequent checkSigil() and other partner API calls.\r\n *\r\n * The pvt_ token is valid for 1 hour. Recommended: mint once per deployment\r\n * (e.g. on server startup or in middleware) and reuse until near expiry.\r\n *\r\n * @example\r\n * const session = await createPartnerSession({ partnerKey: process.env.PROVENONCE_PARTNER_KEY! })\r\n * const result = await checkSigil({ agentHash, partnerKey: session.token })\r\n */\r\nexport async function createPartnerSession(opts: PartnerSessionOptions): Promise<PartnerSession> {\r\n const { partnerKey, baseUrl = DEFAULT_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\r\n\r\n if (!partnerKey?.startsWith('pvp_')) {\r\n throw new ProvenoncePartnerError('partnerKey must start with pvp_', 400);\r\n }\r\n\r\n const url = `${baseUrl.replace(/\\/$/, '')}/api/v1/partner/token`;\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n method: 'POST',\r\n headers: { Authorization: `Bearer ${partnerKey}` },\r\n signal: controller.signal,\r\n });\r\n } catch (err: any) {\r\n clearTimeout(timer);\r\n if (err?.name === 'AbortError') {\r\n throw new ProvenoncePartnerError(`Request timed out after ${timeoutMs}ms`, 408);\r\n }\r\n throw new ProvenoncePartnerError(`Network error: ${err?.message ?? err}`, 0);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (res.status === 401 || res.status === 403) {\r\n const body = await res.json().catch(() => ({}));\r\n throw new ProvenoncePartnerError((body as any)?.error ?? 'Partner key rejected', res.status);\r\n }\r\n\r\n if (res.status === 429) {\r\n throw new ProvenoncePartnerError('Rate limit exceeded', 429);\r\n }\r\n\r\n if (!res.ok) {\r\n throw new ProvenoncePartnerError(`Unexpected response: ${res.status}`, res.status);\r\n }\r\n\r\n const data: any = await res.json();\r\n return {\r\n token: data.token,\r\n expiresAt: data.expires_at,\r\n expiresInSeconds: data.expires_in_seconds,\r\n };\r\n}\r\n\r\n// ── Error class ───────────────────────────────────────────────────────────────\r\n\r\nexport class ProvenoncePartnerError extends Error {\r\n readonly status: number;\r\n\r\n constructor(message: string, status: number) {\r\n super(message);\r\n this.name = 'ProvenoncePartnerError';\r\n this.status = status;\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@provenonce/partner",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Provenonce Partner SDK — SIGIL verification for skill developers",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",