Skip to content

Commit

Permalink
Load Blockdaemon dependency on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
wcalderipe committed Jun 27, 2024
1 parent b686822 commit a8fd974
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 19 deletions.
44 changes: 26 additions & 18 deletions apps/policy-engine/src/engine/core/service/signing-mpc.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Blockdaemon } from '@narval-xyz/blockdaemon-tsm-kit'
import { Blockdaemon } from '@narval-xyz/blockdaemon-tsm'
import { ConfigService } from '@narval/config-module'
import { Alg, Hex, PublicKey, eip191Hash, hexToBase64Url, publicKeyToJwk } from '@narval/signature'
import { HttpStatus, Inject, Injectable, Logger } from '@nestjs/common'
Expand All @@ -8,16 +8,6 @@ import { ApplicationException } from '../../../shared/exception/application.exce
import { SignerConfig } from '../../../shared/type/domain.type'
import { SigningService } from './signing.service.interface'

const { Configuration, TSMClient, SessionConfig, curves } = Blockdaemon

const createClient = async (url: string, apiKey: string) => {
if (!TSMClient || !Configuration) return null

const config = await new Configuration(url)
await config.withAPIKeyAuthentication(apiKey)
return await TSMClient.withConfiguration(config)
}

// util to wrap TSM SDK exceptions so we throw sanitized messages while capturing the internal error ourselves
const wrapTsmException = (message: string, e: Error) => {
throw new ApplicationException({
Expand All @@ -30,37 +20,48 @@ const wrapTsmException = (message: string, e: Error) => {
@Injectable()
export class MpcSigningService implements SigningService {
private logger = new Logger(MpcSigningService.name)

private url: string

private apiKey: string

private playerCount: number

constructor(@Inject(ConfigService) private configService: ConfigService<Config>) {
private blockdaemon: typeof Blockdaemon

constructor(
@Inject(ConfigService) private configService: ConfigService<Config>,
blockdaemon: typeof Blockdaemon
) {
const tsm = this.configService.get('tsm')
if (!tsm) {
throw new ApplicationException({
message: 'TSM config not found',
suggestedHttpStatusCode: 500
})
}

this.blockdaemon = blockdaemon

this.url = tsm.url
this.apiKey = tsm.apiKey
this.playerCount = tsm.playerCount
}

async generateKey(keyId?: string, sessionId?: string): Promise<{ publicKey: PublicKey }> {
if (!sessionId || !SessionConfig || !TSMClient) {
if (!sessionId) {
throw new ApplicationException({
message: 'sessionId is missing',
suggestedHttpStatusCode: 500
})
}
const sessionConfig = await SessionConfig.newStaticSessionConfig(sessionId, this.playerCount)
const sessionConfig = await this.blockdaemon.SessionConfig.newStaticSessionConfig(sessionId, this.playerCount)

const tsmClient = await createClient(this.url, this.apiKey)
const tsmClient = await this.createClient()

const ecdsaKeyId = await tsmClient
.ECDSA()
.generateKey(sessionConfig, 1, curves.SECP256K1, keyId)
.generateKey(sessionConfig, 1, this.blockdaemon.curves.SECP256K1, keyId)
.catch((e: Error) => wrapTsmException('Failed to generate ECDSA key', e))

if (keyId && ecdsaKeyId !== keyId) {
Expand All @@ -86,6 +87,13 @@ export class MpcSigningService implements SigningService {
}
}

private async createClient() {
const config = await new this.blockdaemon.Configuration(this.url)
await config.withAPIKeyAuthentication(this.apiKey)

return this.blockdaemon.TSMClient.withConfiguration(config)
}

buildSignerEip191(signer: SignerConfig, sessionId?: string) {
return async (messageToSign: string): Promise<string> => {
const hash = eip191Hash(messageToSign)
Expand All @@ -96,9 +104,9 @@ export class MpcSigningService implements SigningService {
})
}

const sessionConfig = await SessionConfig.newStaticSessionConfig(sessionId, this.playerCount)
const sessionConfig = await this.blockdaemon.SessionConfig.newStaticSessionConfig(sessionId, this.playerCount)

const tsmClient = await createClient(this.url, this.apiKey)
const tsmClient = await this.createClient()

const keyId = signer.keyId || signer.publicKey?.kid
if (!keyId) {
Expand Down
8 changes: 7 additions & 1 deletion apps/policy-engine/src/engine/engine.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ import { HttpDataStoreRepository } from './persistence/repository/http-data-stor
if (signingProtocol === 'simple') {
return new SimpleSigningService()
} else if (signingProtocol === 'mpc') {
return new MpcSigningService(configService)
try {
const { Blockdaemon } = await import('@narval-xyz/blockdaemon-tsm')

return new MpcSigningService(configService, Blockdaemon)
} catch {
throw new Error('Unable to load optional dependency on Blockdaemon TSM')
}
}

throw new Error('Invalid signing protocol')
Expand Down

0 comments on commit a8fd974

Please sign in to comment.