@zkproofport-app/sdk 0.1.2-beta.1 → 0.1.3-beta.1

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Proofport SDK - Main class
3
3
  */
4
- import type { ProofRequest, ProofResponse, CircuitType, CircuitInputs, ProofportConfig, QRCodeOptions, AuthCredentials, AuthToken, RelayProofRequest, RelayProofResult } from './types';
4
+ import type { ProofRequest, ProofResponse, CircuitType, CircuitInputs, ProofportConfig, QRCodeOptions, ChallengeResponse, WalletSigner, RelayProofRequest, RelayProofResult } from './types';
5
5
  import type { SDKEnvironment } from './types';
6
6
  /**
7
7
  * Main SDK class for interacting with the ZKProofport mobile app.
@@ -12,12 +12,15 @@ import type { SDKEnvironment } from './types';
12
12
  * @example
13
13
  * ```typescript
14
14
  * import { ProofportSDK } from '@zkproofport-app/sdk';
15
+ * import { BrowserProvider } from 'ethers';
15
16
  *
16
17
  * // Initialize SDK (uses production relay by default)
17
18
  * const sdk = ProofportSDK.create();
18
19
  *
19
- * // Authenticate
20
- * await sdk.login({ clientId: 'your-id', apiKey: 'your-key' });
20
+ * // Set wallet signer for challenge-signature auth
21
+ * const provider = new BrowserProvider(window.ethereum);
22
+ * const signer = await provider.getSigner();
23
+ * sdk.setSigner(signer);
21
24
  *
22
25
  * // Create proof request via relay
23
26
  * const relay = await sdk.createRelayRequest('coinbase_attestation', {
@@ -37,7 +40,7 @@ import type { SDKEnvironment } from './types';
37
40
  export declare class ProofportSDK {
38
41
  private config;
39
42
  private pendingRequests;
40
- private authToken;
43
+ private signer;
41
44
  private relayUrl;
42
45
  private nullifierRegistry?;
43
46
  private socket;
@@ -707,91 +710,48 @@ export declare class ProofportSDK {
707
710
  */
708
711
  static isMobile(): boolean;
709
712
  /**
710
- * Authenticates with ZKProofport using client credentials via the relay server.
713
+ * Sets the wallet signer for challenge-signature authentication.
714
+ * The signer will be used to sign challenges from the relay server.
711
715
  *
712
- * Exchanges a client_id and api_key pair for a short-lived JWT token
713
- * that can be used to authenticate relay requests.
714
- *
715
- * @param credentials - Client ID and API key
716
- * @param relayUrl - Relay server URL (e.g., 'https://relay.zkproofport.app')
717
- * @returns Promise resolving to AuthToken with JWT token and metadata
718
- * @throws Error if authentication fails
716
+ * @param signer - Wallet signer (ethers v6 Signer or compatible object with signMessage/getAddress)
719
717
  *
720
718
  * @example
721
719
  * ```typescript
722
- * const auth = await ProofportSDK.authenticate(
723
- * { clientId: 'your-client-id', apiKey: 'your-api-key' },
724
- * 'https://relay.zkproofport.app'
725
- * );
726
- * console.log('Token:', auth.token);
727
- * console.log('Expires in:', auth.expiresIn, 'seconds');
728
- * ```
729
- */
730
- static authenticate(credentials: AuthCredentials, relayUrl: string): Promise<AuthToken>;
731
- /**
732
- * Checks if an auth token is still valid (not expired).
733
- *
734
- * @param auth - AuthToken to check
735
- * @returns True if the token has not expired
720
+ * import { BrowserProvider } from 'ethers';
736
721
  *
737
- * @example
738
- * ```typescript
739
- * if (!ProofportSDK.isTokenValid(auth)) {
740
- * auth = await ProofportSDK.authenticate(credentials, relayUrl);
741
- * }
722
+ * const provider = new BrowserProvider(window.ethereum);
723
+ * const signer = await provider.getSigner();
724
+ * sdk.setSigner(signer);
742
725
  * ```
743
726
  */
744
- static isTokenValid(auth: AuthToken): boolean;
727
+ setSigner(signer: WalletSigner): void;
745
728
  /**
746
- * Authenticates with ZKProofport and stores the token for relay requests.
747
- *
748
- * Instance method that authenticates via the relay server and stores
749
- * the JWT token internally, so subsequent relay requests are automatically authenticated.
750
- *
751
- * @param credentials - Client ID and API key
752
- * @returns Promise resolving to AuthToken
753
- * @throws Error if authentication fails or relayUrl is not configured
729
+ * Fetches a random challenge from the relay server.
730
+ * The challenge must be signed and included in proof requests.
754
731
  *
755
- * @example
756
- * ```typescript
757
- * const sdk = ProofportSDK.create('production');
758
- *
759
- * await sdk.login({ clientId: 'your-id', apiKey: 'your-key' });
760
- * // SDK is now authenticated for relay requests
761
- * ```
762
- */
763
- login(credentials: AuthCredentials): Promise<AuthToken>;
764
- /**
765
- * Logs out by clearing the stored authentication token.
766
- */
767
- logout(): void;
768
- /**
769
- * Returns whether the SDK instance is currently authenticated with a valid token.
770
- */
771
- isAuthenticated(): boolean;
772
- /**
773
- * Returns the current auth token, or null if not authenticated.
732
+ * @returns Promise resolving to ChallengeResponse with challenge hex and expiry
733
+ * @throws Error if relayUrl is not configured
774
734
  */
775
- getAuthToken(): AuthToken | null;
735
+ getChallenge(): Promise<ChallengeResponse>;
776
736
  /**
777
737
  * Creates a proof request through the relay server.
778
738
  *
779
739
  * This is the recommended way to create proof requests. The relay server:
780
740
  * - Issues a server-side requestId (validated by the mobile app)
781
741
  * - Tracks request status in Redis
782
- * - Handles credit deduction and tier enforcement
783
742
  * - Builds the deep link with relay callback URL
743
+ * - Stores inputs hash for deep link integrity verification
784
744
  *
785
745
  * @param circuit - Circuit type identifier
786
746
  * @param inputs - Circuit-specific inputs
787
747
  * @param options - Request options (message, dappName, dappIcon, nonce)
788
748
  * @returns Promise resolving to RelayProofRequest with requestId, deepLink, pollUrl
789
- * @throws Error if not authenticated or relay request fails
749
+ * @throws Error if signer not set or relay request fails
790
750
  *
791
751
  * @example
792
752
  * ```typescript
793
753
  * const sdk = ProofportSDK.create();
794
- * await sdk.login({ clientId: 'id', apiKey: 'key' });
754
+ * sdk.setSigner(signer);
795
755
  *
796
756
  * const relay = await sdk.createRelayRequest('coinbase_attestation', {
797
757
  * scope: 'myapp.com'
@@ -857,7 +817,7 @@ export declare class ProofportSDK {
857
817
  * @param callbacks.onResult - Called when proof is completed or failed
858
818
  * @param callbacks.onError - Called on errors
859
819
  * @returns Unsubscribe function to clean up the connection
860
- * @throws Error if not authenticated, relayUrl not set, or socket.io-client not installed
820
+ * @throws Error if relayUrl not set or socket.io-client not installed
861
821
  *
862
822
  * @example
863
823
  * ```typescript
package/dist/index.d.ts CHANGED
@@ -10,8 +10,8 @@
10
10
  * // Initialize with environment preset
11
11
  * const sdk = ProofportSDK.create('production');
12
12
  *
13
- * // Authenticate
14
- * await sdk.login({ clientId: 'your-id', apiKey: 'your-key' });
13
+ * // Set wallet signer
14
+ * sdk.setSigner(signer);
15
15
  *
16
16
  * // Create proof request via relay
17
17
  * const relay = await sdk.createRelayRequest('coinbase_attestation', {
@@ -26,4 +26,4 @@
26
26
  * ```
27
27
  */
28
28
  export { ProofportSDK, default } from './ProofportSDK';
29
- export type { CircuitType, ProofRequestStatus, CoinbaseKycInputs, CoinbaseCountryInputs, CircuitInputs, ProofRequest, ProofResponse, QRCodeOptions, VerifierContract, ProofportConfig, AuthCredentials, AuthToken, RelayProofRequest, RelayProofResult, SDKEnvironment, } from './types';
29
+ export type { CircuitType, ProofRequestStatus, CoinbaseKycInputs, CoinbaseCountryInputs, CircuitInputs, ProofRequest, ProofResponse, QRCodeOptions, VerifierContract, ProofportConfig, ChallengeResponse, WalletSigner, RelayProofRequest, RelayProofResult, SDKEnvironment, } from './types';
package/dist/index.esm.js CHANGED
@@ -3909,12 +3909,15 @@ async function getNullifierInfo(nullifier, registryAddress, provider) {
3909
3909
  * @example
3910
3910
  * ```typescript
3911
3911
  * import { ProofportSDK } from '@zkproofport-app/sdk';
3912
+ * import { BrowserProvider } from 'ethers';
3912
3913
  *
3913
3914
  * // Initialize SDK (uses production relay by default)
3914
3915
  * const sdk = ProofportSDK.create();
3915
3916
  *
3916
- * // Authenticate
3917
- * await sdk.login({ clientId: 'your-id', apiKey: 'your-key' });
3917
+ * // Set wallet signer for challenge-signature auth
3918
+ * const provider = new BrowserProvider(window.ethereum);
3919
+ * const signer = await provider.getSigner();
3920
+ * sdk.setSigner(signer);
3918
3921
  *
3919
3922
  * // Create proof request via relay
3920
3923
  * const relay = await sdk.createRelayRequest('coinbase_attestation', {
@@ -3960,7 +3963,7 @@ class ProofportSDK {
3960
3963
  */
3961
3964
  constructor(config = {}) {
3962
3965
  this.pendingRequests = new Map();
3963
- this.authToken = null;
3966
+ this.signer = null;
3964
3967
  this.socket = null;
3965
3968
  this.config = {
3966
3969
  scheme: config.scheme || DEFAULT_SCHEME,
@@ -4728,115 +4731,42 @@ class ProofportSDK {
4728
4731
  return false;
4729
4732
  return /Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
4730
4733
  }
4734
+ // ============ Relay Integration ============
4731
4735
  /**
4732
- * Authenticates with ZKProofport using client credentials via the relay server.
4733
- *
4734
- * Exchanges a client_id and api_key pair for a short-lived JWT token
4735
- * that can be used to authenticate relay requests.
4736
+ * Sets the wallet signer for challenge-signature authentication.
4737
+ * The signer will be used to sign challenges from the relay server.
4736
4738
  *
4737
- * @param credentials - Client ID and API key
4738
- * @param relayUrl - Relay server URL (e.g., 'https://relay.zkproofport.app')
4739
- * @returns Promise resolving to AuthToken with JWT token and metadata
4740
- * @throws Error if authentication fails
4739
+ * @param signer - Wallet signer (ethers v6 Signer or compatible object with signMessage/getAddress)
4741
4740
  *
4742
4741
  * @example
4743
4742
  * ```typescript
4744
- * const auth = await ProofportSDK.authenticate(
4745
- * { clientId: 'your-client-id', apiKey: 'your-api-key' },
4746
- * 'https://relay.zkproofport.app'
4747
- * );
4748
- * console.log('Token:', auth.token);
4749
- * console.log('Expires in:', auth.expiresIn, 'seconds');
4750
- * ```
4751
- */
4752
- static async authenticate(credentials, relayUrl) {
4753
- if (!credentials.clientId || !credentials.apiKey) {
4754
- throw new Error('clientId and apiKey are required');
4755
- }
4756
- if (!relayUrl) {
4757
- throw new Error('relayUrl is required');
4758
- }
4759
- const response = await fetch(`${relayUrl}/api/v1/auth/token`, {
4760
- method: 'POST',
4761
- headers: { 'Content-Type': 'application/json' },
4762
- body: JSON.stringify({
4763
- client_id: credentials.clientId,
4764
- api_key: credentials.apiKey,
4765
- }),
4766
- });
4767
- if (!response.ok) {
4768
- const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
4769
- throw new Error(error.error || `Authentication failed: HTTP ${response.status}`);
4770
- }
4771
- const data = await response.json();
4772
- return {
4773
- token: data.token,
4774
- clientId: data.client_id,
4775
- dappId: data.dapp_id,
4776
- tier: data.tier,
4777
- expiresIn: data.expires_in,
4778
- expiresAt: Date.now() + (data.expires_in * 1000),
4779
- };
4780
- }
4781
- /**
4782
- * Checks if an auth token is still valid (not expired).
4783
- *
4784
- * @param auth - AuthToken to check
4785
- * @returns True if the token has not expired
4743
+ * import { BrowserProvider } from 'ethers';
4786
4744
  *
4787
- * @example
4788
- * ```typescript
4789
- * if (!ProofportSDK.isTokenValid(auth)) {
4790
- * auth = await ProofportSDK.authenticate(credentials, relayUrl);
4791
- * }
4745
+ * const provider = new BrowserProvider(window.ethereum);
4746
+ * const signer = await provider.getSigner();
4747
+ * sdk.setSigner(signer);
4792
4748
  * ```
4793
4749
  */
4794
- static isTokenValid(auth) {
4795
- return Date.now() < auth.expiresAt - 30000; // 30s buffer
4750
+ setSigner(signer) {
4751
+ this.signer = signer;
4796
4752
  }
4797
- // ============ Relay Integration ============
4798
4753
  /**
4799
- * Authenticates with ZKProofport and stores the token for relay requests.
4800
- *
4801
- * Instance method that authenticates via the relay server and stores
4802
- * the JWT token internally, so subsequent relay requests are automatically authenticated.
4754
+ * Fetches a random challenge from the relay server.
4755
+ * The challenge must be signed and included in proof requests.
4803
4756
  *
4804
- * @param credentials - Client ID and API key
4805
- * @returns Promise resolving to AuthToken
4806
- * @throws Error if authentication fails or relayUrl is not configured
4807
- *
4808
- * @example
4809
- * ```typescript
4810
- * const sdk = ProofportSDK.create('production');
4811
- *
4812
- * await sdk.login({ clientId: 'your-id', apiKey: 'your-key' });
4813
- * // SDK is now authenticated for relay requests
4814
- * ```
4757
+ * @returns Promise resolving to ChallengeResponse with challenge hex and expiry
4758
+ * @throws Error if relayUrl is not configured
4815
4759
  */
4816
- async login(credentials) {
4760
+ async getChallenge() {
4817
4761
  if (!this.relayUrl) {
4818
- throw new Error('relayUrl is required for authentication. Use ProofportSDK.create(\'production\') or set relayUrl in config.');
4762
+ throw new Error('relayUrl is required. Set it in ProofportSDK config.');
4819
4763
  }
4820
- this.authToken = await ProofportSDK.authenticate(credentials, this.relayUrl);
4821
- return this.authToken;
4822
- }
4823
- /**
4824
- * Logs out by clearing the stored authentication token.
4825
- */
4826
- logout() {
4827
- this.authToken = null;
4828
- }
4829
- /**
4830
- * Returns whether the SDK instance is currently authenticated with a valid token.
4831
- */
4832
- isAuthenticated() {
4833
- return this.authToken !== null && ProofportSDK.isTokenValid(this.authToken);
4834
- }
4835
- /**
4836
- * Returns the current auth token, or null if not authenticated.
4837
- */
4838
- getAuthToken() {
4839
- return this.authToken;
4764
+ const response = await fetch(`${this.relayUrl}/api/v1/challenge`);
4765
+ if (!response.ok) {
4766
+ const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
4767
+ throw new Error(error.error || `Failed to get challenge: HTTP ${response.status}`);
4768
+ }
4769
+ return await response.json();
4840
4770
  }
4841
4771
  /**
4842
4772
  * Creates a proof request through the relay server.
@@ -4844,19 +4774,19 @@ class ProofportSDK {
4844
4774
  * This is the recommended way to create proof requests. The relay server:
4845
4775
  * - Issues a server-side requestId (validated by the mobile app)
4846
4776
  * - Tracks request status in Redis
4847
- * - Handles credit deduction and tier enforcement
4848
4777
  * - Builds the deep link with relay callback URL
4778
+ * - Stores inputs hash for deep link integrity verification
4849
4779
  *
4850
4780
  * @param circuit - Circuit type identifier
4851
4781
  * @param inputs - Circuit-specific inputs
4852
4782
  * @param options - Request options (message, dappName, dappIcon, nonce)
4853
4783
  * @returns Promise resolving to RelayProofRequest with requestId, deepLink, pollUrl
4854
- * @throws Error if not authenticated or relay request fails
4784
+ * @throws Error if signer not set or relay request fails
4855
4785
  *
4856
4786
  * @example
4857
4787
  * ```typescript
4858
4788
  * const sdk = ProofportSDK.create();
4859
- * await sdk.login({ clientId: 'id', apiKey: 'key' });
4789
+ * sdk.setSigner(signer);
4860
4790
  *
4861
4791
  * const relay = await sdk.createRelayRequest('coinbase_attestation', {
4862
4792
  * scope: 'myapp.com'
@@ -4870,15 +4800,20 @@ class ProofportSDK {
4870
4800
  * ```
4871
4801
  */
4872
4802
  async createRelayRequest(circuit, inputs, options = {}) {
4873
- if (!this.authToken || !ProofportSDK.isTokenValid(this.authToken)) {
4874
- throw new Error('Not authenticated. Call login() first.');
4803
+ if (!this.signer) {
4804
+ throw new Error('Signer not set. Call setSigner() first.');
4875
4805
  }
4876
4806
  if (!this.relayUrl) {
4877
4807
  throw new Error('relayUrl is required. Set it in ProofportSDK config.');
4878
4808
  }
4809
+ // Get challenge from relay and sign it
4810
+ const { challenge } = await this.getChallenge();
4811
+ const signature = await this.signer.signMessage(challenge);
4879
4812
  const body = {
4880
4813
  circuitId: circuit,
4881
4814
  inputs,
4815
+ challenge,
4816
+ signature,
4882
4817
  };
4883
4818
  if (options.message)
4884
4819
  body.message = options.message;
@@ -4892,7 +4827,6 @@ class ProofportSDK {
4892
4827
  method: 'POST',
4893
4828
  headers: {
4894
4829
  'Content-Type': 'application/json',
4895
- 'Authorization': `Bearer ${this.authToken.token}`,
4896
4830
  },
4897
4831
  body: JSON.stringify(body),
4898
4832
  });
@@ -4975,7 +4909,7 @@ class ProofportSDK {
4975
4909
  * @param callbacks.onResult - Called when proof is completed or failed
4976
4910
  * @param callbacks.onError - Called on errors
4977
4911
  * @returns Unsubscribe function to clean up the connection
4978
- * @throws Error if not authenticated, relayUrl not set, or socket.io-client not installed
4912
+ * @throws Error if relayUrl not set or socket.io-client not installed
4979
4913
  *
4980
4914
  * @example
4981
4915
  * ```typescript
@@ -4996,9 +4930,6 @@ class ProofportSDK {
4996
4930
  * ```
4997
4931
  */
4998
4932
  async subscribe(requestId, callbacks) {
4999
- if (!this.authToken || !ProofportSDK.isTokenValid(this.authToken)) {
5000
- throw new Error('Not authenticated. Call login() first.');
5001
- }
5002
4933
  if (!this.relayUrl) {
5003
4934
  throw new Error('relayUrl is required. Set it in ProofportSDK config.');
5004
4935
  }
@@ -5013,10 +4944,9 @@ class ProofportSDK {
5013
4944
  if (typeof ioConnect !== 'function') {
5014
4945
  throw new Error('Failed to load socket.io-client: io function not found');
5015
4946
  }
5016
- // Connect to relay /proof namespace
4947
+ // Connect to relay /proof namespace (no JWT — open connections)
5017
4948
  const socket = ioConnect(`${this.relayUrl}/proof`, {
5018
4949
  path: '/socket.io',
5019
- auth: { token: this.authToken.token },
5020
4950
  transports: ['websocket', 'polling'],
5021
4951
  });
5022
4952
  this.socket = socket;
@@ -5065,7 +4995,7 @@ class ProofportSDK {
5065
4995
  async waitForProof(requestId, options = {}) {
5066
4996
  const timeout = options.timeoutMs || 300000;
5067
4997
  // Try Socket.IO first
5068
- if (this.authToken && ProofportSDK.isTokenValid(this.authToken) && this.relayUrl) {
4998
+ if (this.relayUrl) {
5069
4999
  try {
5070
5000
  return await new Promise((resolve, reject) => {
5071
5001
  const timer = setTimeout(() => {