Send publicKey in RPC requests for implicit username claiming

Updated client to send publicKey in all authenticated RPC requests,
enabling server-side implicit username claiming.

Changes:
- Added publicKey field to RpcRequest interface
- Added publicKey to all authenticated RPC method calls
- Removed username claiming requirement from publishService()
- Auto-mark username as claimed after successful publish

Users no longer need to call claimUsername() before publishing
services. The server will automatically claim the username on
the first authenticated request.

🤖 Generated with Claude Code
https://claude.com/claude-code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-12 20:22:28 +01:00
parent f4ae5dee30
commit 238cc08bf5
2 changed files with 18 additions and 8 deletions

View File

@@ -70,6 +70,7 @@ interface RpcRequest {
method: string method: string
message: string message: string
signature: string signature: string
publicKey?: string
params?: any params?: any
} }
@@ -232,6 +233,7 @@ export class RondevuAPI {
method: 'claimUsername', method: 'claimUsername',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { username, publicKey }, params: { username, publicKey },
}) })
} }
@@ -263,6 +265,7 @@ export class RondevuAPI {
method: 'publishService', method: 'publishService',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { params: {
serviceFqn: service.serviceFqn, serviceFqn: service.serviceFqn,
offers: service.offers, offers: service.offers,
@@ -283,6 +286,7 @@ export class RondevuAPI {
method: 'getService', method: 'getService',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { params: {
serviceFqn, serviceFqn,
...options, ...options,
@@ -299,6 +303,7 @@ export class RondevuAPI {
method: 'deleteService', method: 'deleteService',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { serviceFqn }, params: { serviceFqn },
}) })
} }
@@ -316,6 +321,7 @@ export class RondevuAPI {
method: 'answerOffer', method: 'answerOffer',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { serviceFqn, offerId, sdp }, params: { serviceFqn, offerId, sdp },
}) })
} }
@@ -333,6 +339,7 @@ export class RondevuAPI {
method: 'getOfferAnswer', method: 'getOfferAnswer',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { serviceFqn, offerId }, params: { serviceFqn, offerId },
}) })
} catch (err) { } catch (err) {
@@ -369,6 +376,7 @@ export class RondevuAPI {
method: 'poll', method: 'poll',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { since }, params: { since },
}) })
} }
@@ -386,6 +394,7 @@ export class RondevuAPI {
method: 'addIceCandidates', method: 'addIceCandidates',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { serviceFqn, offerId, candidates }, params: { serviceFqn, offerId, candidates },
}) })
} }
@@ -403,6 +412,7 @@ export class RondevuAPI {
method: 'getIceCandidates', method: 'getIceCandidates',
message: auth.message, message: auth.message,
signature: auth.signature, signature: auth.signature,
publicKey: this.keypair.publicKey,
params: { serviceFqn, offerId, since }, params: { serviceFqn, offerId, since },
}) })

View File

@@ -167,18 +167,13 @@ export class Rondevu {
/** /**
* Publish a service with automatic signature generation * Publish a service with automatic signature generation
* Username will be automatically claimed on first publish if not already claimed
*/ */
async publishService(options: PublishServiceOptions): Promise<Service> { async publishService(options: PublishServiceOptions): Promise<Service> {
if (!this.keypair) { if (!this.keypair) {
throw new Error('Not initialized. Call initialize() first.') throw new Error('Not initialized. Call initialize() first.')
} }
if (!this.usernameClaimed) {
throw new Error(
'Username not claimed. Call claimUsername() first or the server will reject the service.'
)
}
const { serviceFqn, offers, ttl } = options const { serviceFqn, offers, ttl } = options
// Generate signature for service publication // Generate signature for service publication
@@ -194,8 +189,13 @@ export class Rondevu {
ttl, ttl,
} }
// Publish to server // Publish to server (server will auto-claim username if needed)
return await this.getAPI().publishService(serviceRequest) const result = await this.getAPI().publishService(serviceRequest)
// Mark username as claimed after successful publish
this.usernameClaimed = true
return result
} }
// ============================================ // ============================================