@zkmedusa/passport-sdk 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,8 +21,8 @@ import {
21
21
  const passport = parsePassportJson(passportJsonFromUser);
22
22
 
23
23
  const result = verifyPassport(passport, {
24
- issuerPublicKey: "749d6135f3d883950ff82f82bc2119e8b6e469ebfc4163dd10e1cc079b723565",
25
- minTier: 2, // require SILVER+
24
+ issuerPublicKey: process.env.MEDUSA_ISSUER_PUBLIC_KEY!,
25
+ minTier: 2,
26
26
  });
27
27
 
28
28
  if (result.valid) {
@@ -38,19 +38,19 @@ Fetch the issuer public key dynamically:
38
38
  import { MedusaPassportClient } from "@zkmedusa/passport-sdk";
39
39
 
40
40
  const client = new MedusaPassportClient({
41
- baseUrl: "https://your-medusa-app.com",
41
+ baseUrl: "https://www.zkmedusa.com",
42
42
  });
43
43
 
44
44
  const result = await client.verify(passport);
45
45
  ```
46
46
 
47
- ## Register for whitelist / presale
47
+ ## Register for whitelist / presale (partner backend)
48
48
 
49
- Users present a passport, then link a **claim wallet** (the address that receives presale access).
49
+ Partners register claim wallets from their backend with a Bearer API key scoped to one `campaignId`.
50
50
 
51
51
  ```typescript
52
52
  const client = new MedusaPassportClient({
53
- baseUrl: "https://your-medusa-app.com",
53
+ baseUrl: "https://www.zkmedusa.com",
54
54
  apiKey: process.env.MEDUSA_PARTNER_API_KEY,
55
55
  });
56
56
 
@@ -67,33 +67,73 @@ Pull the whitelist for your campaign:
67
67
 
68
68
  ```typescript
69
69
  const entries = await client.getWhitelist("my-presale-q3");
70
- // [{ claimWallet, tier, tierLabel, nullifier, registeredAt }, ...]
71
70
  ```
72
71
 
72
+ ## Claim wallet (user flow)
73
+
74
+ Since **v0.2.0**, users can register a **claim wallet** without a partner API key — for apps that let users submit their own claim address after minting a passport.
75
+
76
+ No `apiKey` is required. The campaign must be enabled on the Medusa server (`MEDUSA_CLAIM_CAMPAIGN_IDS`).
77
+
78
+ ```typescript
79
+ const client = new MedusaPassportClient({
80
+ baseUrl: "https://www.zkmedusa.com",
81
+ });
82
+
83
+ await client.registerClaimWallet({
84
+ passport,
85
+ claimWallet: "FreshClaimWalletPublicKey...",
86
+ campaignId: "my-presale-q3",
87
+ });
88
+ ```
89
+
90
+ Rotate to a new claim address for the same campaign (after generating a fresh wallet):
91
+
92
+ ```typescript
93
+ await client.rotateClaimWallet({
94
+ passport,
95
+ claimWallet: "NewClaimWalletPublicKey...",
96
+ campaignId: "my-presale-q3",
97
+ });
98
+ ```
99
+
100
+ Users can also manage claim wallets in the browser at [zkmedusa.com/wallet](https://www.zkmedusa.com/wallet).
101
+
102
+ **Partner vs user registration**
103
+
104
+ | Method | Auth | Endpoint |
105
+ | --- | --- | --- |
106
+ | `client.register()` | Bearer API key | `/api/partner/register` |
107
+ | `client.registerClaimWallet()` | None | `/api/passport/claim/register` |
108
+ | `client.rotateClaimWallet()` | None | `/api/passport/claim/rotate` |
109
+
73
110
  ## Partner API keys
74
111
 
75
112
  Medusa operators create keys in `.env`:
76
113
 
77
114
  ```env
78
115
  MEDUSA_PARTNER_API_KEYS=my-presale-q3:sk_live_partner_key
116
+ MEDUSA_CLAIM_CAMPAIGN_IDS=my-presale-q3,medusa-claim
79
117
  ```
80
118
 
81
- Each key is scoped to one `campaignId`.
119
+ Each partner key is scoped to one `campaignId`. Public claim routes only accept campaign IDs listed in `MEDUSA_CLAIM_CAMPAIGN_IDS`.
82
120
 
83
121
  ## Endpoints used by the SDK
84
122
 
85
123
  | Endpoint | Purpose |
86
- |----------|---------|
124
+ | --- | --- |
87
125
  | `GET /api/passport/issuer` | Issuer public key |
88
126
  | `GET /api/passport/verify` | Policy metadata |
89
127
  | `POST /api/passport/verify` | Remote passport verification |
90
- | `POST /api/partner/register` | Register passport + claim wallet |
128
+ | `POST /api/partner/register` | Partner register (Bearer) |
129
+ | `POST /api/passport/claim/register` | User claim wallet register |
130
+ | `POST /api/passport/claim/rotate` | User claim wallet rotate |
91
131
  | `GET /api/partner/whitelist?campaignId=` | Export campaign whitelist |
92
132
 
93
133
  ## Tier gating example
94
134
 
95
135
  ```typescript
96
- const PRESALE_MIN_TIER = 1; // bronze
136
+ const PRESALE_MIN_TIER = 1;
97
137
  const ALLOCATION_BY_TIER = { 1: 0.1, 2: 0.5, 3: 2 };
98
138
 
99
139
  const result = await client.verify(passport, { minTier: PRESALE_MIN_TIER });
@@ -106,8 +146,37 @@ const maxSol = ALLOCATION_BY_TIER[result.tier!];
106
146
 
107
147
  - The passport proves eligibility **without** revealing the proving wallet.
108
148
  - Registration links the passport to a **claim wallet** for whitelist/presale payout.
149
+ - Claim wallet secret keys stay in the user's browser unless they export a backup JSON.
109
150
  - One passport nullifier can register once per campaign (anti-sybil).
110
151
 
111
152
  ## Browser + Node
112
153
 
113
154
  The SDK works in Node.js, Next.js API routes, and the browser (local verify only).
155
+
156
+ ## Publishing this package (maintainers)
157
+
158
+ From the monorepo root:
159
+
160
+ ```bash
161
+ # 1. Log in to npm (once per machine)
162
+ npm login
163
+
164
+ # 2. Build the SDK (runs automatically before publish via prepublishOnly)
165
+ npm run build:sdk
166
+
167
+ # 3. Publish to npm
168
+ npm run publish:sdk
169
+ ```
170
+
171
+ Or from `packages/medusa-passport-sdk/`:
172
+
173
+ ```bash
174
+ npm run build
175
+ npm publish --access public
176
+ ```
177
+
178
+ Bump `version` in `packages/medusa-passport-sdk/package.json` before each publish (semver). After publishing, integrators update with:
179
+
180
+ ```bash
181
+ npm install @zkmedusa/passport-sdk@latest
182
+ ```
@@ -0,0 +1,46 @@
1
+ import { type PassportTier } from "./types.js";
2
+ export interface PassportBadge {
3
+ /** MPL Core asset address of the soulbound badge. */
4
+ assetId: string;
5
+ owner: string;
6
+ collection: string | null;
7
+ /** True when the asset is permanently frozen (soulbound). */
8
+ frozen: boolean;
9
+ name?: string;
10
+ tier?: PassportTier;
11
+ tierLabel?: string;
12
+ expiresAt?: string;
13
+ nullifier?: string;
14
+ /** Raw DAS asset object for advanced consumers. */
15
+ raw: unknown;
16
+ }
17
+ export interface FetchPassportBadgesOptions {
18
+ /**
19
+ * A Solana RPC endpoint that supports the DAS (Digital Asset Standard) API,
20
+ * e.g. Helius/Triton/QuickNode. Required to read MPL Core assets by owner.
21
+ */
22
+ dasRpcUrl: string;
23
+ /** Only return badges that belong to this collection address. */
24
+ collection?: string;
25
+ /** Only return badges at or above this tier. */
26
+ minTier?: PassportTier;
27
+ /** Only return permanently-frozen (soulbound) badges. Defaults to true. */
28
+ requireFrozen?: boolean;
29
+ fetchImpl?: typeof fetch;
30
+ }
31
+ /**
32
+ * Reads the soulbound Medusa passport badges (MPL Core assets) owned by a
33
+ * wallet using the DAS API. Use this to gate access by on-chain badge instead
34
+ * of (or in addition to) verifying a signed passport credential.
35
+ *
36
+ * Note: the authoritative tier is always the signed passport; on-chain
37
+ * attributes are a convenience mirror that depends on your DAS provider
38
+ * exposing MPL Core attributes.
39
+ */
40
+ export declare function fetchPassportBadges(owner: string, options: FetchPassportBadgesOptions): Promise<PassportBadge[]>;
41
+ /**
42
+ * Convenience predicate: returns true when the wallet holds at least one
43
+ * soulbound Medusa passport badge meeting the supplied options.
44
+ */
45
+ export declare function hasPassportBadge(owner: string, options: FetchPassportBadgesOptions): Promise<boolean>;
46
+ //# sourceMappingURL=badges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badges.d.ts","sourceRoot":"","sources":["../src/badges.ts"],"names":[],"mappings":"AACA,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAmID;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,aAAa,EAAE,CAAC,CA+D1B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,OAAO,CAAC,CAGlB"}
package/dist/badges.js ADDED
@@ -0,0 +1,171 @@
1
+ import { MedusaPassportError } from "./errors.js";
2
+ import { PASSPORT_TIERS, TIER_LABELS } from "./types.js";
3
+ const TIER_FROM_LABEL = {
4
+ [TIER_LABELS[PASSPORT_TIERS.BRONZE]]: PASSPORT_TIERS.BRONZE,
5
+ [TIER_LABELS[PASSPORT_TIERS.SILVER]]: PASSPORT_TIERS.SILVER,
6
+ [TIER_LABELS[PASSPORT_TIERS.GOLD]]: PASSPORT_TIERS.GOLD,
7
+ };
8
+ function asRecord(value) {
9
+ return value && typeof value === "object"
10
+ ? value
11
+ : undefined;
12
+ }
13
+ /**
14
+ * MPL Core attributes can surface in a few shapes across DAS providers, so we
15
+ * read defensively from all of them and normalize to a flat key/value map.
16
+ */
17
+ function readAttributes(item) {
18
+ const out = {};
19
+ const content = asRecord(item.content);
20
+ const metadata = content ? asRecord(content.metadata) : undefined;
21
+ const plugins = asRecord(item.plugins);
22
+ const attributesPlugin = plugins ? asRecord(plugins.attributes) : undefined;
23
+ const attributesPluginData = attributesPlugin
24
+ ? asRecord(attributesPlugin.data)
25
+ : undefined;
26
+ const mplCoreInfo = asRecord(item.mpl_core_info);
27
+ const sources = [
28
+ item.attributes,
29
+ metadata?.attributes,
30
+ attributesPluginData?.attribute_list,
31
+ mplCoreInfo?.attributes,
32
+ ];
33
+ for (const source of sources) {
34
+ if (!Array.isArray(source)) {
35
+ continue;
36
+ }
37
+ for (const entry of source) {
38
+ const record = asRecord(entry);
39
+ if (!record) {
40
+ continue;
41
+ }
42
+ const key = record.key ?? record.trait_type;
43
+ const value = record.value;
44
+ if (typeof key === "string" && value != null) {
45
+ out[key.toLowerCase()] = String(value);
46
+ }
47
+ }
48
+ }
49
+ return out;
50
+ }
51
+ function tierFromAttributes(attrs) {
52
+ const label = attrs.tier?.toUpperCase();
53
+ if (label && label in TIER_FROM_LABEL) {
54
+ return TIER_FROM_LABEL[label];
55
+ }
56
+ const level = Number(attrs.tierlevel);
57
+ if (level === 1 || level === 2 || level === 3) {
58
+ return level;
59
+ }
60
+ return undefined;
61
+ }
62
+ function collectionFromGrouping(item) {
63
+ const grouping = item.grouping;
64
+ if (!Array.isArray(grouping)) {
65
+ return null;
66
+ }
67
+ for (const entry of grouping) {
68
+ const record = asRecord(entry);
69
+ if (record && record.group_key === "collection") {
70
+ return typeof record.group_value === "string"
71
+ ? record.group_value
72
+ : null;
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+ function isFrozen(item) {
78
+ const ownership = asRecord(item.ownership);
79
+ if (ownership && typeof ownership.frozen === "boolean") {
80
+ return ownership.frozen;
81
+ }
82
+ const plugins = asRecord(item.plugins);
83
+ const permanentFreeze = plugins
84
+ ? asRecord(plugins.permanent_freeze_delegate ?? plugins.permanentFreezeDelegate)
85
+ : undefined;
86
+ const data = permanentFreeze ? asRecord(permanentFreeze.data) : undefined;
87
+ return data?.frozen === true;
88
+ }
89
+ function toBadge(item) {
90
+ const attrs = readAttributes(item);
91
+ const content = asRecord(item.content);
92
+ const metadata = content ? asRecord(content.metadata) : undefined;
93
+ const tier = tierFromAttributes(attrs);
94
+ return {
95
+ assetId: typeof item.id === "string" ? item.id : "",
96
+ owner: asRecord(item.ownership)?.owner ?? "",
97
+ collection: collectionFromGrouping(item),
98
+ frozen: isFrozen(item),
99
+ name: metadata?.name ??
100
+ (typeof item.name === "string" ? item.name : undefined),
101
+ tier,
102
+ tierLabel: tier ? TIER_LABELS[tier] : attrs.tier?.toUpperCase(),
103
+ expiresAt: attrs.expiresat,
104
+ nullifier: attrs.nullifier,
105
+ raw: item,
106
+ };
107
+ }
108
+ /**
109
+ * Reads the soulbound Medusa passport badges (MPL Core assets) owned by a
110
+ * wallet using the DAS API. Use this to gate access by on-chain badge instead
111
+ * of (or in addition to) verifying a signed passport credential.
112
+ *
113
+ * Note: the authoritative tier is always the signed passport; on-chain
114
+ * attributes are a convenience mirror that depends on your DAS provider
115
+ * exposing MPL Core attributes.
116
+ */
117
+ export async function fetchPassportBadges(owner, options) {
118
+ const fetchImpl = options.fetchImpl ?? fetch;
119
+ const requireFrozen = options.requireFrozen ?? true;
120
+ const response = await fetchImpl(options.dasRpcUrl, {
121
+ method: "POST",
122
+ headers: { "Content-Type": "application/json" },
123
+ body: JSON.stringify({
124
+ jsonrpc: "2.0",
125
+ id: "medusa-badges",
126
+ method: "getAssetsByOwner",
127
+ params: {
128
+ ownerAddress: owner,
129
+ page: 1,
130
+ limit: 1000,
131
+ },
132
+ }),
133
+ });
134
+ if (!response.ok) {
135
+ throw new MedusaPassportError(`DAS request failed with status ${response.status}.`, "API_ERROR");
136
+ }
137
+ const payload = (await response.json());
138
+ if (payload.error) {
139
+ throw new MedusaPassportError(payload.error.message ?? "DAS request returned an error.", "API_ERROR");
140
+ }
141
+ const items = payload.result?.items ?? [];
142
+ return items
143
+ .map(asRecord)
144
+ .filter((item) => Boolean(item))
145
+ .filter((item) => {
146
+ const iface = item.interface;
147
+ return iface === undefined || iface === "MplCoreAsset";
148
+ })
149
+ .map(toBadge)
150
+ .filter((badge) => {
151
+ if (options.collection && badge.collection !== options.collection) {
152
+ return false;
153
+ }
154
+ if (requireFrozen && !badge.frozen) {
155
+ return false;
156
+ }
157
+ if (options.minTier !== undefined &&
158
+ (badge.tier === undefined || badge.tier < options.minTier)) {
159
+ return false;
160
+ }
161
+ return true;
162
+ });
163
+ }
164
+ /**
165
+ * Convenience predicate: returns true when the wallet holds at least one
166
+ * soulbound Medusa passport badge meeting the supplied options.
167
+ */
168
+ export async function hasPassportBadge(owner, options) {
169
+ const badges = await fetchPassportBadges(owner, options);
170
+ return badges.length > 0;
171
+ }
package/dist/client.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { IssuerInfo, MedusaPassport, PassportPolicy, RegisterPassportInput, RegisterPassportResult, VerifyPassportOptions, VerifyPassportResult, WhitelistEntry } from "./types.js";
1
+ import { type FetchPassportBadgesOptions, type PassportBadge } from "./badges.js";
2
+ import type { IssuerInfo, MedusaPassport, PassportPolicy, RegisterPassportInput, RegisterPassportResult, ClaimRegisterInput, ClaimRegisterResult, ClaimRotateInput, ClaimRotateResult, VerifyPassportOptions, VerifyPassportResult, WhitelistEntry } from "./types.js";
2
3
  export interface MedusaPassportClientOptions {
3
4
  baseUrl: string;
4
5
  apiKey?: string;
@@ -18,7 +19,11 @@ export declare class MedusaPassportClient {
18
19
  verifyLocal(passport: MedusaPassport, options: VerifyPassportOptions): VerifyPassportResult;
19
20
  parseAndVerify(passportJson: string, options?: Omit<VerifyPassportOptions, "issuerPublicKey">): Promise<VerifyPassportResult>;
20
21
  register(input: RegisterPassportInput): Promise<RegisterPassportResult>;
22
+ registerClaimWallet(input: ClaimRegisterInput): Promise<ClaimRegisterResult>;
23
+ rotateClaimWallet(input: ClaimRotateInput): Promise<ClaimRotateResult>;
21
24
  getWhitelist(campaignId: string): Promise<WhitelistEntry[]>;
25
+ getBadges(owner: string, options: FetchPassportBadgesOptions): Promise<PassportBadge[]>;
26
+ hasBadge(owner: string, options: FetchPassportBadgesOptions): Promise<boolean>;
22
27
  hasValidSignature(passport: MedusaPassport, issuerPublicKey?: string): boolean;
23
28
  }
24
29
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,2BAA2B;IAO1C,WAAW,IAAI,OAAO,CAAC,UAAU,CAAC;IAelC,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC;IAUtC,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA+BrE,MAAM,CACV,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAM,GAC3D,OAAO,CAAC,oBAAoB,CAAC;IAehC,WAAW,CACT,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB;IAIjB,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAM,GAC3D,OAAO,CAAC,oBAAoB,CAAC;IAiB1B,QAAQ,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA+BvE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgCjE,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO;CAQ/E"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAMrB,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,2BAA2B;IAO1C,WAAW,IAAI,OAAO,CAAC,UAAU,CAAC;IAelC,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC;IAUtC,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA+BrE,MAAM,CACV,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAM,GAC3D,OAAO,CAAC,oBAAoB,CAAC;IAehC,WAAW,CACT,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB;IAIjB,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAM,GAC3D,OAAO,CAAC,oBAAoB,CAAC;IAiB1B,QAAQ,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA+BvE,mBAAmB,CACvB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC;IAwBzB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwBtE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgC3D,SAAS,CACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,aAAa,EAAE,CAAC;IAOrB,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,OAAO,CAAC;IAOnB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO;CAQ/E"}
package/dist/client.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { MedusaPassportError } from "./errors.js";
2
+ import { fetchPassportBadges, hasPassportBadge, } from "./badges.js";
2
3
  import { parsePassportJson, verifyPassport, verifyPassportSignature, } from "./verify.js";
3
4
  export class MedusaPassportClient {
4
5
  constructor(options) {
@@ -93,6 +94,30 @@ export class MedusaPassportClient {
93
94
  }
94
95
  return payload;
95
96
  }
97
+ async registerClaimWallet(input) {
98
+ const response = await this.fetchImpl(`${this.baseUrl}/api/passport/claim/register`, {
99
+ method: "POST",
100
+ headers: { "Content-Type": "application/json" },
101
+ body: JSON.stringify(input),
102
+ });
103
+ const payload = (await response.json());
104
+ if (!response.ok || !payload.registered) {
105
+ throw new MedusaPassportError(payload.error ?? "Claim wallet registration failed.", "REGISTRATION_FAILED");
106
+ }
107
+ return payload;
108
+ }
109
+ async rotateClaimWallet(input) {
110
+ const response = await this.fetchImpl(`${this.baseUrl}/api/passport/claim/rotate`, {
111
+ method: "POST",
112
+ headers: { "Content-Type": "application/json" },
113
+ body: JSON.stringify(input),
114
+ });
115
+ const payload = (await response.json());
116
+ if (!response.ok || !payload.rotated) {
117
+ throw new MedusaPassportError(payload.error ?? "Claim wallet rotation failed.", "REGISTRATION_FAILED");
118
+ }
119
+ return payload;
120
+ }
96
121
  async getWhitelist(campaignId) {
97
122
  if (!this.apiKey) {
98
123
  throw new MedusaPassportError("apiKey is required to fetch whitelist entries.", "API_ERROR");
@@ -108,6 +133,18 @@ export class MedusaPassportClient {
108
133
  }
109
134
  return payload.entries ?? [];
110
135
  }
136
+ async getBadges(owner, options) {
137
+ return fetchPassportBadges(owner, {
138
+ fetchImpl: this.fetchImpl,
139
+ ...options,
140
+ });
141
+ }
142
+ async hasBadge(owner, options) {
143
+ return hasPassportBadge(owner, {
144
+ fetchImpl: this.fetchImpl,
145
+ ...options,
146
+ });
147
+ }
111
148
  hasValidSignature(passport, issuerPublicKey) {
112
149
  const key = issuerPublicKey ?? this.issuerPublicKey;
113
150
  if (!key) {
package/dist/index.d.ts CHANGED
@@ -2,7 +2,9 @@ export { MedusaPassportClient } from "./client.js";
2
2
  export type { MedusaPassportClientOptions } from "./client.js";
3
3
  export { MedusaPassportError } from "./errors.js";
4
4
  export { PASSPORT_POLICY_VERSION, PASSPORT_TIERS, TIER_LABELS, } from "./types.js";
5
- export type { IssuerInfo, MedusaPassport, PassportPolicy, PassportPublicInputs, PassportStatement, PassportTier, RegisterPassportInput, RegisterPassportResult, VerifyPassportOptions, VerifyPassportResult, WhitelistEntry, ZkProofBundle, } from "./types.js";
5
+ export type { IssuerInfo, MedusaPassport, PassportPolicy, PassportPublicInputs, PassportStatement, PassportTier, RegisterPassportInput, RegisterPassportResult, ClaimRegisterInput, ClaimRegisterResult, ClaimRotateInput, ClaimRotateResult, VerifyPassportOptions, VerifyPassportResult, WhitelistEntry, ZkProofBundle, } from "./types.js";
6
6
  export { hexToBytes, isValidSolanaAddress } from "./utils.js";
7
7
  export { parsePassportJson, verifyPassport, verifyPassportSignature, } from "./verify.js";
8
+ export { fetchPassportBadges, hasPassportBadge } from "./badges.js";
9
+ export type { PassportBadge, FetchPassportBadgesOptions } from "./badges.js";
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -3,3 +3,4 @@ export { MedusaPassportError } from "./errors.js";
3
3
  export { PASSPORT_POLICY_VERSION, PASSPORT_TIERS, TIER_LABELS, } from "./types.js";
4
4
  export { hexToBytes, isValidSolanaAddress } from "./utils.js";
5
5
  export { parsePassportJson, verifyPassport, verifyPassportSignature, } from "./verify.js";
6
+ export { fetchPassportBadges, hasPassportBadge } from "./badges.js";
package/dist/types.d.ts CHANGED
@@ -29,7 +29,7 @@ export interface PassportStatement {
29
29
  }
30
30
  export interface MedusaPassport {
31
31
  type: "medusa_passport_v1";
32
- chain: "solana";
32
+ chain: "solana" | "ethereum" | "base" | "bnb" | "robinhood";
33
33
  statement: PassportStatement;
34
34
  nullifier: string;
35
35
  zkProof: ZkProofBundle;
@@ -66,6 +66,35 @@ export interface RegisterPassportResult {
66
66
  nullifier: string;
67
67
  registeredAt: string;
68
68
  }
69
+ export interface ClaimRegisterInput {
70
+ passport: MedusaPassport;
71
+ claimWallet: string;
72
+ campaignId?: string;
73
+ }
74
+ export interface ClaimRegisterResult {
75
+ registered: boolean;
76
+ campaignId: string;
77
+ claimWallet: string;
78
+ tier: PassportTier;
79
+ tierLabel: string;
80
+ nullifier: string;
81
+ registeredAt: string;
82
+ }
83
+ export interface ClaimRotateInput {
84
+ passport: MedusaPassport;
85
+ claimWallet: string;
86
+ campaignId?: string;
87
+ }
88
+ export interface ClaimRotateResult {
89
+ rotated: boolean;
90
+ previousClaimWallet: string;
91
+ campaignId: string;
92
+ claimWallet: string;
93
+ tier: PassportTier;
94
+ tierLabel: string;
95
+ nullifier: string;
96
+ registeredAt: string;
97
+ }
69
98
  export interface WhitelistEntry {
70
99
  campaignId: string;
71
100
  claimWallet: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAoBpB,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAc/D;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,cAAc,EACxB,eAAe,EAAE,MAAM,GACtB,OAAO,CAST;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CA8CtB"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAqBpB,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAc/D;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,cAAc,EACxB,eAAe,EAAE,MAAM,GACtB,OAAO,CAST;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CA8CtB"}
package/dist/verify.js CHANGED
@@ -6,8 +6,9 @@ function isPassportShape(value) {
6
6
  return false;
7
7
  }
8
8
  const passport = value;
9
+ const validChains = ["solana", "ethereum", "base", "bnb", "robinhood"];
9
10
  return (passport.type === "medusa_passport_v1" &&
10
- passport.chain === "solana" &&
11
+ validChains.includes(passport.chain) &&
11
12
  passport.issuer === "medusa" &&
12
13
  typeof passport.signature === "string" &&
13
14
  typeof passport.nullifier === "string" &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkmedusa/passport-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Verify and register Medusa Passports in third-party apps, presales, and whitelists.",
5
5
  "license": "MIT",
6
6
  "type": "module",