Перейти к содержанию

CLASS

SignerClient

public class SignerClient : SpatiumProtocol

Предварительно настроенный протокол, направленный на коммуникацию с Spatium Signer Service

  • Для транспортировки он использует HTTP(S) + SSE двунаправленный транспорт.
  • Для кэша использует in-memory хранилище
  • Для крипто-драйвера использует предоставленный Crypto

Так как внутренне он использует SSETransportDriver, нужно помнить что клиент начинает слушать события как только вызван метод connect(timeout:) и не прекращает, пока не вызван метод disconnect().

  • См. также: SpatiumSDKSwift/ProtocolSwift

Свойства

auth

public final let auth: AuthorizationSession

Методы

init(url:auth:crypto:timeout:)

public init(url: String, auth: AuthorizationSession, crypto: Crypto, timeout: UInt?)

Заметьте

запросы относятся к accountId сессии авторизации, тем самым хранят данные независимо для каждого авторизированного пользователя

Пример

 // Считаем, что Crypto уже инициализирован
 let auth = AuthorizationSession(
     url: "https://api-cloud-dev.spatium.io/authorization/v1",
     tokenId: UUID().uuidString,
     permissions: ["read", "secret"]
 )

 let clientProtocol = SignerClient(
     url: "https://api-cloud-dev.spatium.io/signer/v1",
     auth: auth,
     crypto: clientCrypto,
     timeout: 10 * 1000
 )

 // Подключение к SignerService (с 10-секундным таймаутом)
 try await clientProtocol.connect(timeout: 10 * 1000)

 // Генерируем случаный secretId для нового секрета (он должен быть сгенерирован единожды и сохранен)
 let secretId = UUID().uuidString

 // Генерируем оба секрата (первый на подлюченном сервере и второй локально) (производится единожды для каждого secretId) 
 try await clientProtocol.generateDistributedSecret(
     secretId: secretId
 )

 // Генерируем рандомный session ID для новой сессии синхронизации
 let syncSessionId = UUID().uuidString

 // Выполняем ECDSA-over-secp256k1 процедуру синхронизации для ключа с путем ```m/44'/0'/0'/0'/0'```
 let publicKey = try await syncDistributedEcdsaKey(
     driver: clientProtocol,
     secretId: secretId,
     syncSessionId: syncSessionId,
     curve: .secp256k1,
     derivationCoin: 0,
     derivationAccount: 0
 )

 // К этому моменту данные синхронизации уже сохранены в хранилище и составной ключ доступен к получению
 let _publicKey = try await getEcdsaPublicKey(
     driver: clientProtocol,
     secretId: secretId,
     syncSessionId: syncSessionId
 )

 // Этот ключ, очевидно, является тем же ключом, который мы получаем из самой процедуры синхронизации
 XCTAssertEqual(publicKey, _publicKey)

 // Генерируем рандомный session ID для новой сессии подписания
 let signSessionId = UUID().uuidString

 // Сообщение к подписанию
 let message = "7hJ9yN2OdIQo2kJu0arZgw2EKnMX5FGtQ6jlCWuLXCM="

 // Генерируем ECDSA подпись
 let signature = try await signEcdsaMessage(
     driver: clientProtocol,
     secretId: secretId,
     syncSessionId: syncSessionId,
     signSessionId: signSessionId,
     message: message
 )

 // Верифицируем подпись к составному ключу
 print([
     "curve": EcdsaCurve.secp256k1,
     "publicKey": publicKey,
     "message": message,
     "signature": [
         "r": signature.r,
         "s": signature.s,
         "recovery": signature.recovery
     ] as [String : Any]
 ] as [String : Any])

Параметры

url = signer service эндпоинт (HTTP(S))
auth = сессия авторизации AuthorizationSession к использованию
crypto = любой валидный Crypto для обработки данных и вычислений
timeout = (опционально) таймаут запроса на каждое сообщение, по истечению которого выполнение процедуры останавливается

connect(timeout:)

public func connect(timeout: UInt?) async throws

Подключение и прослушивание событий

disconnect()

public func disconnect()

Прекращение прослушивания событий и отключение

generateDistributedSecret(secretId:)

public func generateDistributedSecret(secretId: String) async throws

Одновременная генерация распределенного секрета с тем же secretId

Этот метод не строго обязателен, т.к. возможна генерация секретов с одинаковыми ID независимо с помощью Crypto Driver, однако это может быть полезно в демонстрационных целях.

Результатом этой операции будут являться новые секреты, сохраненные в постоянное хранилище, доступные по предоставленному secretId

С данного момента можно свободно вызывать syncDistributedEcdsaKey и syncDistributedEddsaKey, в том случае если секрет доступен в хранилище.

Пример

// Считаем, что SignerClient уже инициализирован и подключен

// Генерируем случаный secretId для нового секрета
let secretId = UUID().uuidString

// Генерируем оба секрата (первый на подлюченном сервере и второй локально)
try await clientProtocol.generateDistributedSecret(
    secretId: secretId
)

// К этому моменту секрет уже сгенерирован и готов к использованию MPC 

Параметры

Имя Описание
secretId ID (UUID) данного секрета