@spatium/sdk
Classes
Interfaces
Type Aliases
Curve
Ƭ Curve: EcdsaCurve
| EddsaCurve
EcdsaCurve
Ƭ EcdsaCurve: "secp256k1"
EcdsaSignature
Ƭ EcdsaSignature: Object
Type Declaration
Name | Type |
---|---|
r |
string |
recovery |
number |
s |
string |
EddsaCurve
Ƭ EddsaCurve: "ed25519"
EddsaSignature
Ƭ EddsaSignature: Object
Type Declaration
Name | Type |
---|---|
R |
string |
s |
string |
StorageData
Ƭ StorageData: unknown
Stored data blob
SDK stores only serializable JSON data
StorageFilter
Ƭ StorageFilter: Partial
<{ room
: string
; topic
: string
}>
StorageMeta
Ƭ StorageMeta: Object
Storage entry identification data
Each unique combination of room and topic should uniquely identify a storage entry
Type Declaration
Name | Type | Description |
---|---|---|
room |
string |
Data scope, e.g.,, single user, single communication session, etc. |
topic |
string |
Data tag within a scope, e.g.,, single user's property, single communication step, etc. |
StoragePayload
Ƭ StoragePayload: StorageMeta
& { data
: StorageData
}
TransportCallback
Ƭ TransportCallback: (meta
: TransportMeta
, data
: TransportData
) => Promise
<void
>
Type Declaration
▸ (meta
, data
): Promise
<void
>
Parameters
Name | Type |
---|---|
meta |
TransportMeta |
data |
TransportData |
Returns
Promise
<void
>
TransportData
Ƭ TransportData: unknown
Message data blob
The SDK sends only serializable JSON data
TransportFilter
Ƭ TransportFilter: Partial
<TransportMeta
>
Message filter
Partial meta is used as a message filter, receiving side may decide to wait for
messages with a specific room, a specific topic, or even any message (with {}
as a filter)
TransportMeta
Ƭ TransportMeta: Object
Message identification data
Each transfered message contains these fields in order to be correctly identified and caught
Type Declaration
Name | Type | Description |
---|---|---|
room |
string |
Message scope, e.g., single user, single communication session, etc. |
topic |
string |
Message tag within a scope, e.g., single user's property, single communication step, etc. |
TransportPayload
Ƭ TransportPayload: TransportMeta
& { data
: TransportData
}
Variables
NIL
• Const
NIL: string
= _NIL
Functions
decrypt
▸ decrypt(data
, key
): string
Parameters
Name | Type |
---|---|
data |
string |
key |
string |
Returns
string
deriveHDKey
▸ deriveHDKey(secret
, coin
, account
): string
Parameters
Name | Type |
---|---|
secret |
string |
coin |
number |
account |
number |
Returns
string
deserialize
▸ deserialize(data
): unknown
Parameters
Name | Type |
---|---|
data |
string |
Returns
unknown
encodeEddsaBN
▸ encodeEddsaBN(curve
, s
): string
Parameters
Name | Type |
---|---|
curve |
"ed25519" |
s |
string |
Returns
string
encodeEddsaPoint
▸ encodeEddsaPoint(curve
, p
): string
Parameters
Name | Type |
---|---|
curve |
"ed25519" |
p |
string |
Returns
string
encrypt
▸ encrypt(data
, key
, randomSource
): string
Parameters
Name | Type |
---|---|
data |
string |
key |
string |
randomSource |
(size : number ) => string |
Returns
string
fromInternal
▸ fromInternal(value
, decimals
): string
Parameters
Name | Type |
---|---|
value |
string |
decimals |
number |
Returns
string
generatePoint
▸ generatePoint(curve
, x
): string
Parameters
Name | Type |
---|---|
curve |
Curve |
x |
string |
Returns
string
getCompoundEcdsaPrivateKey
▸ getCompoundEcdsaPrivateKey(secretLeft
, secretRight
, curve
, derivationCoin
, derivationAccount
): string
Parameters
Name | Type |
---|---|
secretLeft |
string |
secretRight |
string |
curve |
"secp256k1" |
derivationCoin |
number |
derivationAccount |
number |
Returns
string
getCompoundEddsaPrivateKey
▸ getCompoundEddsaPrivateKey(secretLeft
, secretRight
, curve
, derivationCoin
, derivationAccount
): string
Parameters
Name | Type |
---|---|
secretLeft |
string |
secretRight |
string |
curve |
"ed25519" |
derivationCoin |
number |
derivationAccount |
number |
Returns
string
getEcdsaPublicKey
▸ getEcdsaPublicKey(driver
, secretId
, syncSessionId
): Promise
<string
>
Get a compound public key from an already performed synchronization session (standalone helper)
See
Example
// Assume an already performed synchronization procedure
const publicKey = await getEcdsaPublicKey(protocol, secretId, syncSessionId);
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret used for synchronization |
syncSessionId |
string |
ID (UUID) of a synchronization procedure |
Returns
Promise
<string
>
compound public key, synchronized during that session
getEddsaPublicKey
▸ getEddsaPublicKey(driver
, secretId
, syncSessionId
): Promise
<string
>
Get a compound public key from an already performed synchronization session (standalone helper)
See
Example
// Assume an already performed synchronization procedure
const publicKey = await getEddsaPublicKey(protocol, secretId, syncSessionId);
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret used for synchronization |
syncSessionId |
string |
ID (UUID) of a synchronization procedure |
Returns
Promise
<string
>
compound public key, synchronized during that session
matchOptional
▸ matchOptional<T
>(a
, b
): boolean
Type Parameters
Name |
---|
T |
Parameters
Name | Type |
---|---|
a |
T |
b |
undefined | T |
Returns
boolean
matchTransportMeta
▸ matchTransportMeta(meta
, filter
): boolean
Match a filter against a meta
A useful implementation helper for message filtering
Parameters
Name | Type | Description |
---|---|---|
meta |
TransportMeta |
message identifiers |
filter |
Partial <TransportMeta > |
incoming message filter |
Returns
boolean
true if provided meta matches the filter
pack
▸ pack<T
>(_schema
, v
): unknown
Type Parameters
Name | Type |
---|---|
T |
extends ZodType <any , any , any , T > |
Parameters
Name | Type |
---|---|
_schema |
T |
v |
TypeOf <T > |
Returns
unknown
randomBytes
▸ randomBytes(length
): string
Parameters
Name | Type |
---|---|
length |
number |
Returns
string
read
▸ read(driver
, meta
): Promise
<StorageData
| null
>
Read data stored under the provided meta (standalone helper)
This method is typically used in a permanent storage strategy
See
Parameters
Name | Type | Description |
---|---|---|
driver |
StorageDriver |
StorageDriver implementation |
meta |
StorageMeta |
composite identifier |
Returns
Promise
<StorageData
| null
>
stored data, or null if not found
receive
▸ receive(driver
, filter
): Promise
<TransportPayload
>
Receive a specific message
This method awaits until a matching message is received (determined by filter
) and resolves with
message data. If an assert
filter is specified, the message is also checked against it and throws if
that assertion fails. Such behavior comes in handy for sudden unsubscribing, receiving messages out of order,
and other erroneous situations.
Parameters
Name | Type | Description |
---|---|---|
driver |
TransportDriver |
TransportDriver implementation |
filter |
Partial <TransportMeta > |
incoming message filter |
Returns
Promise
<TransportPayload
>
received message payload (both meta and data)
▸ receive(driver
, filter
, timeout?
): Promise
<TransportPayload
>
Parameters
Name | Type |
---|---|
driver |
TransportDriver |
filter |
Partial <TransportMeta > |
timeout? |
number |
Returns
Promise
<TransportPayload
>
▸ receive(driver
, filter
, assert
): Promise
<TransportPayload
>
Parameters
Name | Type |
---|---|
driver |
TransportDriver |
filter |
Partial <TransportMeta > |
assert |
Partial <TransportMeta > |
Returns
Promise
<TransportPayload
>
▸ receive(driver
, filter
, assert
, timeout?
): Promise
<TransportPayload
>
Parameters
Name | Type |
---|---|
driver |
TransportDriver |
filter |
Partial <TransportMeta > |
assert |
Partial <TransportMeta > |
timeout? |
number |
Returns
Promise
<TransportPayload
>
removeDistributedEcdsaKey
▸ removeDistributedEcdsaKey(driver
, secretId
, syncSessionId
): Promise
<void
>
Remove an already performed synchronization session from storage
See
Example
// Assume an already performed synchronization procedure
await removeDistributedEcdsaKey(protocol, secretId, syncSessionId);
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret used for synchronization |
syncSessionId |
string |
ID (UUID) of a synchronization procedure |
Returns
Promise
<void
>
removeDistributedEddsaKey
▸ removeDistributedEddsaKey(driver
, secretId
, syncSessionId
): Promise
<void
>
Remove an already performed synchronization session from the storage
See
Example
// Assume an already performed synchronization procedure
await removeDistributedEddsaKey(protocol, secretId, syncSessionId);
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret used for synchronization |
syncSessionId |
string |
ID (UUID) of a synchronization procedure |
Returns
Promise
<void
>
safeDecrypt
▸ safeDecrypt(data
, key
): null
| string
Parameters
Name | Type |
---|---|
data |
string |
key |
string |
Returns
null
| string
safeDeserialize
▸ safeDeserialize(data
): unknown
Parameters
Name | Type |
---|---|
data |
string |
Returns
unknown
safeSecureUnpack
▸ safeSecureUnpack<T
>(schema
, data
): null
| TypeOf
<T
>
Type Parameters
Name | Type |
---|---|
T |
extends ZodType <any , any , any , T > |
Parameters
Name | Type |
---|---|
schema |
T |
data |
unknown |
Returns
null
| TypeOf
<T
>
safeUnpack
▸ safeUnpack<T
>(_schema
, data
): null
| TypeOf
<T
>
Type Parameters
Name | Type |
---|---|
T |
extends ZodType <any , any , any , T > |
Parameters
Name | Type |
---|---|
_schema |
T |
data |
unknown |
Returns
null
| TypeOf
<T
>
securePack
▸ securePack<T
>(schema
, v
, randomSource
): string
Type Parameters
Name | Type |
---|---|
T |
extends ZodType <any , any , any , T > |
Parameters
Name | Type |
---|---|
schema |
T |
v |
TypeOf <T > |
randomSource |
(size : number ) => string |
Returns
string
secureUnpack
▸ secureUnpack<T
>(schema
, data
): TypeOf
<T
>
Type Parameters
Name | Type |
---|---|
T |
extends ZodType <any , any , any , T > |
Parameters
Name | Type |
---|---|
schema |
T |
data |
unknown |
Returns
TypeOf
<T
>
send
▸ send(driver
, meta
, data
): Promise
<void
>
Send a message via transport (standalone helper)
This method awaits until the message is sent (not until it's delivered) and throws if sending is impossible. A specific destination and delivery are handled by implementation.
See
Parameters
Name | Type | Description |
---|---|---|
driver |
TransportDriver |
TransportDriver implementation |
meta |
TransportMeta |
message identifiers |
data |
unknown |
message data |
Returns
Promise
<void
>
serialize
▸ serialize(data
): string
Parameters
Name | Type |
---|---|
data |
unknown |
Returns
string
signEcdsaMessage
▸ signEcdsaMessage(driver
, secretId
, syncSessionId
, signSessionId
, message
): Promise
<EcdsaSignature
>
Generate a distributed ECDSA signature for a given message (standalone helper)
This method requires an already performed synchronization procedure and does not store anything in permanent storage. Messages of a length different from 32 bytes are padded/truncated according to the ECDSA algorithm.
See
Example
// Assume an already performed synchronization procedure and an established connection
// Generate a random session ID for a new signing session
const signSessionId = uuid(randomBytes);
// Message to be signed
const message = '7hJ9yN2OdIQo2kJu0arZgw2EKnMX5FGtQ6jlCWuLXCM='
// Generate an ECDSA signature
const signature = await signEcdsaMessage(protocol, secretId, syncSessionId, signSessionId, message);
// Verify the resulting signature against a compound public key with an external library (elliptic.js here)
expect(new ec('secp256k1').verify(
Buffer.from(message, 'base64'),
{
s: Buffer.from(signature.s, 'base64'),
r: Buffer.from(signature.r, 'base64'),
recoveryParam: signature.recovery,
},
Buffer.from(publicKey, 'base64'),
)).toBeTruthy();
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret used for synchronization |
syncSessionId |
string |
ID (UUID) of a corresponding synchronization procedure |
signSessionId |
string |
ID (UUID) of this signing procedure |
message |
string |
message (32 bytes, base64 encoded) to be signed |
Returns
Promise
<EcdsaSignature
>
ECDSA signature in standard format
signEddsaMessage
▸ signEddsaMessage(driver
, secretId
, syncSessionId
, signSessionId
, message
): Promise
<EddsaSignature
>
Generate a distributed EDDSA signature for a given message (standalone helper)
This method requires an already performed synchronization procedure and does not store anything in permanent storage. Messages of a length different from 32 bytes are padded/truncated according to the EDDSA algorithm.
See
Example
// Assume an already performed synchronization procedure and an established connection
// Generate a random session ID for a new signing session
const signSessionId = uuid(randomBytes);
// Message to be signed
const message = '7hJ9yN2OdIQo2kJu0arZgw2EKnMX5FGtQ6jlCWuLXCM='
// Generate an EDDSA signature
const signature = await signEddsaMessage(protocol, secretId, syncSessionId, signSessionId, message);
// Verify the resulting signature against a compound public key with an external library (elliptic.js here)
expect(new ed('ed25519').verify(
Buffer.from(message, 'base64').toString('hex'),
Buffer.concat([
Buffer.from(encodeEddsaPoint('ed25519', signature.R), 'base64'),
Buffer.from(encodeEddsaBN('ed25519', signature.s), 'base64'),
]).toString('hex'),
Buffer.from(encodeEddsaPoint('ed25519', publicKey), 'base64').toString('hex'),
)).toBeTruthy();
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret used for synchronization |
syncSessionId |
string |
ID (UUID) of a corresponding synchronization procedure |
signSessionId |
string |
ID (UUID) of this signing procedure |
message |
string |
message (32 bytes, base64 encoded) to be signed |
Returns
Promise
<EddsaSignature
>
EDDSA signature in standard format
syncDistributedEcdsaKey
▸ syncDistributedEcdsaKey(driver
, secretId
, syncSessionId
, curve
, derivationCoin
, derivationAccount
): Promise
<string
>
Perform a distributed key synchronization procedure (standalone helper)
Each secret is independently used to generate distributed key fragments (BIP-44 with path m/44'/(coin)'/(account)'/0'/0'
),
and then MPC key synchronization is performed over these fragments in order to get a compound public key for that pair.
Despite each session bearing a unique set of data, the resulting key is deterministic in regards to further synchronizations, e.g. each set of secrets, coin, and account always result in the same compound public key (and ephemeral private keys).
As a result of this operation, new synchronization session data is saved to permanent storage, accessible by the provided session ID. From this point, one may freely call getEcdsaPublicKey or signEcdsaMessage as long as synchronization data (and secret) is accessible in the storage.
See
Example
// Assume an already generated secret and an established connection
// Generate a random session ID for a new synchronization session
const syncSessionId = uuid(randomBytes);
// Perform an ECDSA-over-secp256k1 synchronization procedure for a key with path ```m/44'/0'/0'/0'/0'```
const publicKey = await syncDistributedEcdsaKey(protocol, secretId, syncSessionId, 'secp256k1', 0, 0);
// At this point, synchronization data is saved to the storage, so one may access it to get a compound public key
const _publicKey = await getEcdsaPublicKey(protocol, secretId, syncSessionId);
// Which is obviously the same key that was returned from the synchronization procedure itself
expect(publicKey).toBe(_publicKey);
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret to be used for synchronization |
syncSessionId |
string |
ID (UUID) of this synchronization procedure |
curve |
"secp256k1" |
elliptic curve to use (only secp256k1 is supported at the moment) |
derivationCoin |
number |
coin property of HD key derivation (BIP-44) |
derivationAccount |
number |
account property of HD key derivation (BIP-44) |
Returns
Promise
<string
>
compound public key (which may also be accessed via getEcdsaPublicKey later)
syncDistributedEddsaKey
▸ syncDistributedEddsaKey(driver
, secretId
, syncSessionId
, curve
, derivationCoin
, derivationAccount
): Promise
<string
>
Perform a distributed key synchronization procedure (standalone helper)
Each secret is independently used to generate distributed key fragments (BIP-44 with path m/44'/(coin)'/(account)'/0'/0'
),
and then MPC key synchronization is performed over these fragments in order to get a compound public key for that pair.
Despite each session bearing a unique set of data, the resulting key is deterministic in regards to further synchronizations, e.g. each set of secrets, coin, and account always result in the same compound public key (and ephemeral private keys).
As a result of this operation, new synchronization session data is saved to persistent storage, accessible by the provided session ID. From this point, one may freely call getEddsaPublicKey or signEddsaMessage as long as synchronization data (and secret) is accessible in the storage.
See
Example
// Assume an already generated secret and an established connection
// Generate a random session ID for a new synchronization session
const syncSessionId = uuid(randomBytes);
// Perform an EDDSA-over-secp256k1 synchronization procedure for a key with path ```m/44'/0'/0'/0'/0'```
const publicKey = await syncDistributedEddsaKey(protocol, secretId, syncSessionId, 'ed25519', 0, 0);
// At this point, synchronization data is saved to the storage, so one may access it to get a compound public key
const _publicKey = await getEddsaPublicKey(protocol, secretId, syncSessionId);
// Which is obviously the same key that was returned from the synchronization procedure itself
expect(publicKey).toBe(_publicKey);
Parameters
Name | Type | Description |
---|---|---|
driver |
Protocol |
Protocol implementation |
secretId |
string |
ID (UUID) of a secret to be used for synchronization |
syncSessionId |
string |
ID (UUID) of this synchronization procedure |
curve |
"ed25519" |
elliptic curve to use (only ed25519 is supported at the moment) |
derivationCoin |
number |
coin property of HD key derivation (BIP-44) |
derivationAccount |
number |
account property of HD key derivation (BIP-44) |
Returns
Promise
<string
>
compound public key (which may also be accessed via getEddsaPublicKey later)
take
▸ take(driver
, meta
): Promise
<StorageData
| null
>
Take the data stored under the provided meta and remove the original (standalone helper)
This method is typically used in a temporary storage strategy and as a mean to delete stored entry
See
Parameters
Name | Type | Description |
---|---|---|
driver |
StorageDriver |
StorageDriver implementation |
meta |
StorageMeta |
composite identifier |
Returns
Promise
<StorageData
| null
>
stored data, or null if not found
toInternal
▸ toInternal(value
, decimals
): string
Parameters
Name | Type |
---|---|
value |
string |
decimals |
number |
Returns
string
unpack
▸ unpack<T
>(_schema
, data
): TypeOf
<T
>
Type Parameters
Name | Type |
---|---|
T |
extends ZodType <any , any , any , T > |
Parameters
Name | Type |
---|---|
_schema |
T |
data |
unknown |
Returns
TypeOf
<T
>
uuid
▸ uuid(randomSource
): string
Parameters
Name | Type |
---|---|
randomSource |
(size : number ) => string |
Returns
string
write
▸ write(driver
, meta
, data
): Promise
<void
>
Write a unit of data into storage, uniquely identified by meta (standalone helper)
If such unit of data already exists, it is silently overwritten
See
Parameters
Name | Type | Description |
---|---|---|
driver |
StorageDriver |
StorageDriver implementation |
meta |
StorageMeta |
composite identifier |
data |
unknown |
unit of data to insert |
Returns
Promise
<void
>