@@ -10,7 +10,7 @@ import {
1010 Synapse ,
1111 type SynapseOptions ,
1212} from '@filoz/synapse-sdk'
13- import { type Provider as EthersProvider , JsonRpcProvider , Wallet , WebSocketProvider } from 'ethers'
13+ import { type Provider as EthersProvider , JsonRpcProvider , type Signer , Wallet , WebSocketProvider } from 'ethers'
1414import type { Logger } from 'pino'
1515import { ADDRESS_ONLY_SIGNER_SYMBOL , AddressOnlySigner } from './address-only-signer.js'
1616
@@ -54,26 +54,50 @@ export interface Config {
5454}
5555
5656/**
57- * Configuration for Synapse initialization
58- *
59- * Supports two authentication modes:
60- * 1. Standard: privateKey only
61- * 2. Session Key: walletAddress + sessionKey
57+ * Common options for all Synapse configurations
6258 */
63- export interface SynapseSetupConfig {
64- /** Private key for standard authentication (mutually exclusive with session key mode) */
65- privateKey ?: string | undefined
66- /** Wallet address for session key mode (requires sessionKey) */
67- walletAddress ?: string | undefined
68- /** Session key private key (requires walletAddress) */
69- sessionKey ?: string | undefined
59+ interface BaseSynapseConfig {
7060 /** RPC endpoint for the target Filecoin network. Defaults to calibration. */
7161 rpcUrl ?: string | undefined
7262 /** Optional override for WarmStorage contract address */
7363 warmStorageAddress ?: string | undefined
7464 withCDN ?: boolean | undefined
7565}
7666
67+ /**
68+ * Standard authentication with private key
69+ */
70+ export interface PrivateKeyConfig extends BaseSynapseConfig {
71+ privateKey : string
72+ }
73+
74+ /**
75+ * Session key authentication with wallet address and session key
76+ */
77+ export interface SessionKeyConfig extends BaseSynapseConfig {
78+ walletAddress : string
79+ sessionKey : string
80+ }
81+
82+ /**
83+ * Signer-based authentication with ethers Signer
84+ */
85+ export interface SignerConfig extends BaseSynapseConfig {
86+ signer : Signer
87+ /** Target Filecoin network (required for signer mode to determine default RPC) */
88+ network : 'mainnet' | 'calibration'
89+ }
90+
91+ /**
92+ * Configuration for Synapse initialization
93+ *
94+ * Supports three authentication modes:
95+ * 1. Standard: privateKey only
96+ * 2. Session Key: walletAddress + sessionKey
97+ * 3. Signer: ethers Signer instance
98+ */
99+ export type SynapseSetupConfig = PrivateKeyConfig | SessionKeyConfig | SignerConfig
100+
77101/**
78102 * Structured service object containing the fully initialized Synapse SDK and
79103 * its storage context
@@ -189,22 +213,44 @@ export function isSessionKeyMode(synapse: Synapse): boolean {
189213 }
190214}
191215
216+ /**
217+ * Type guards for authentication configuration
218+ */
219+ function isPrivateKeyConfig ( config : Partial < SynapseSetupConfig > ) : config is PrivateKeyConfig {
220+ return 'privateKey' in config && config . privateKey != null
221+ }
222+
223+ function isSessionKeyConfig ( config : Partial < SynapseSetupConfig > ) : config is SessionKeyConfig {
224+ return (
225+ 'walletAddress' in config && 'sessionKey' in config && config . walletAddress != null && config . sessionKey != null
226+ )
227+ }
228+
229+ function isSignerConfig ( config : Partial < SynapseSetupConfig > ) : config is SignerConfig {
230+ return 'signer' in config && config . signer != null
231+ }
232+
192233/**
193234 * Validate authentication configuration
194235 */
195- function validateAuthConfig ( config : SynapseSetupConfig ) : 'standard' | 'session-key' {
196- const hasStandardAuth = config . privateKey != null
197- const hasSessionKeyAuth = config . walletAddress != null && config . sessionKey != null
236+ function validateAuthConfig ( config : Partial < SynapseSetupConfig > ) : 'standard' | 'session-key' | 'signer' {
237+ const hasPrivateKey = isPrivateKeyConfig ( config )
238+ const hasSessionKey = isSessionKeyConfig ( config )
239+ const hasSigner = isSignerConfig ( config )
240+
241+ const authCount = [ hasPrivateKey , hasSessionKey , hasSigner ] . filter ( Boolean ) . length
198242
199- if ( ! hasStandardAuth && ! hasSessionKeyAuth ) {
200- throw new Error ( 'Authentication required: provide either a privateKey or walletAddress + sessionKey' )
243+ if ( authCount === 0 ) {
244+ throw new Error ( 'Authentication required: provide either privateKey, walletAddress + sessionKey, or signer ' )
201245 }
202246
203- if ( hasStandardAuth && hasSessionKeyAuth ) {
204- throw new Error ( 'Conflicting authentication: provide either a privateKey or walletAddress + sessionKey, not both ' )
247+ if ( authCount > 1 ) {
248+ throw new Error ( 'Conflicting authentication: provide only one of privateKey, walletAddress + sessionKey, or signer ' )
205249 }
206250
207- return hasStandardAuth ? 'standard' : 'session-key'
251+ if ( hasPrivateKey ) return 'standard'
252+ if ( hasSessionKey ) return 'session-key'
253+ return 'signer'
208254}
209255
210256/**
@@ -246,18 +292,26 @@ async function setupSessionKey(synapse: Synapse, sessionWallet: Wallet, logger:
246292/**
247293 * Initialize the Synapse SDK without creating storage context
248294 *
249- * Supports two authentication modes:
295+ * Supports three authentication modes:
250296 * - Standard: privateKey only
251297 * - Session Key: walletAddress + sessionKey
298+ * - Signer: ethers Signer instance
252299 *
253300 * @param config - Application configuration with authentication credentials
254301 * @param logger - Logger instance for detailed operation tracking
255302 * @returns Initialized Synapse instance
256303 */
257- export async function initializeSynapse ( config : SynapseSetupConfig , logger : Logger ) : Promise < Synapse > {
304+ export async function initializeSynapse ( config : Partial < SynapseSetupConfig > , logger : Logger ) : Promise < Synapse > {
258305 try {
259306 const authMode = validateAuthConfig ( config )
260- const rpcURL = config . rpcUrl ?? RPC_URLS . calibration . websocket
307+
308+ // Determine RPC URL based on auth mode
309+ let rpcURL : string
310+ if ( isSignerConfig ( config ) ) {
311+ rpcURL = config . rpcUrl ?? RPC_URLS [ config . network ] . websocket
312+ } else {
313+ rpcURL = config . rpcUrl ?? RPC_URLS . calibration . websocket
314+ }
261315
262316 logger . info ( { event : 'synapse.init' , authMode, rpcUrl : rpcURL } , 'Initializing Synapse SDK' )
263317
@@ -275,31 +329,36 @@ export async function initializeSynapse(config: SynapseSetupConfig, logger: Logg
275329 let synapse : Synapse
276330
277331 if ( authMode === 'session-key' ) {
278- // Session key mode - validation guarantees these are defined
279- const walletAddress = config . walletAddress
280- const sessionKey = config . sessionKey
281- if ( ! walletAddress || ! sessionKey ) {
282- throw new Error ( 'Internal error: session key config validated but values missing' )
332+ // Session key mode - type guard ensures these are defined
333+ if ( ! isSessionKeyConfig ( config ) ) {
334+ throw new Error ( 'Internal error: session key mode but config type mismatch' )
283335 }
284336
285337 // Create provider and signers for session key mode
286338 const provider = createProvider ( rpcURL )
287339 activeProvider = provider
288340
289- const ownerSigner = new AddressOnlySigner ( walletAddress , provider )
290- const sessionWallet = new Wallet ( sessionKey , provider )
341+ const ownerSigner = new AddressOnlySigner ( config . walletAddress , provider )
342+ const sessionWallet = new Wallet ( config . sessionKey , provider )
291343
292344 // Initialize with owner signer, then activate session key
293345 synapse = await Synapse . create ( { ...synapseOptions , signer : ownerSigner } )
294346 await setupSessionKey ( synapse , sessionWallet , logger )
347+ } else if ( authMode === 'signer' ) {
348+ // Signer mode - type guard ensures signer is defined
349+ if ( ! isSignerConfig ( config ) ) {
350+ throw new Error ( 'Internal error: signer mode but config type mismatch' )
351+ }
352+
353+ synapse = await Synapse . create ( { ...synapseOptions , signer : config . signer } )
354+ activeProvider = synapse . getProvider ( )
295355 } else {
296- // Standard mode - validation guarantees privateKey is defined
297- const privateKey = config . privateKey
298- if ( ! privateKey ) {
299- throw new Error ( 'Internal error: standard auth validated but privateKey missing' )
356+ // Private key mode - type guard ensures privateKey is defined
357+ if ( ! isPrivateKeyConfig ( config ) ) {
358+ throw new Error ( 'Internal error: private key mode but config type mismatch' )
300359 }
301360
302- synapse = await Synapse . create ( { ...synapseOptions , privateKey } )
361+ synapse = await Synapse . create ( { ...synapseOptions , privateKey : config . privateKey } )
303362 activeProvider = synapse . getProvider ( )
304363 }
305364
0 commit comments