mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2024-12-04 18:00:18 +00:00
Sig service redesign (#126)
This commit is contained in:
parent
0c5fecac40
commit
976cd0435c
2
.github/workflows/publish_branch.yml
vendored
2
.github/workflows/publish_branch.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
### Publish to NPM registry
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '15'
|
||||
node-version: '16'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- run: cat package.json
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
### Publish to NPM registry
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '16'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- run: npm i
|
||||
|
35
aqua/src/services.aqua
Normal file
35
aqua/src/services.aqua
Normal file
@ -0,0 +1,35 @@
|
||||
-- import SignResult, Sig from "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
-- export SignResult, Sig
|
||||
|
||||
-- TODO:: fix this issue: https://github.com/fluencelabs/aqua-lib/issues/12
|
||||
-- and remove copy-paste
|
||||
|
||||
data SignResult:
|
||||
-- Was call successful or not
|
||||
success: bool
|
||||
-- Error message. Will be null if the call is successful
|
||||
error: ?string
|
||||
-- Signature as byte array. Will be null if the call is not successful
|
||||
signature: ?[]u8
|
||||
|
||||
-- Available only on FluenceJS peers
|
||||
-- The service can also be resolved by it's host peer id
|
||||
service Sig("sig"):
|
||||
-- Signs data with the service's private key.
|
||||
-- Depending on implementation the service might check call params to restrict usage for security reasons.
|
||||
-- By default it is only allowed to be used on the same peer the particle was initiated
|
||||
-- and accepts data only from the following sources:
|
||||
-- trust-graph.get_trust_bytes
|
||||
-- trust-graph.get_revocation_bytes
|
||||
-- registry.get_key_bytes
|
||||
-- registry.get_record_bytes
|
||||
-- registry.get_host_record_bytes
|
||||
-- Argument: data - byte array to sign
|
||||
-- Returns: signature as SignResult structure
|
||||
sign(data: []u8) -> SignResult
|
||||
|
||||
-- Given the data and signature both as byte arrays, returns true if the signature is correct, false otherwise.
|
||||
verify(signature: []u8, data: []u8) -> bool
|
||||
|
||||
-- Gets service's public key.
|
||||
get_pub_key() -> string
|
11
aqua/tests/sig-tests.aqua
Normal file
11
aqua/tests/sig-tests.aqua
Normal file
@ -0,0 +1,11 @@
|
||||
import SignResult, Sig from "../src/services.aqua"
|
||||
export Sig
|
||||
|
||||
service DataProvider("data"):
|
||||
provide_data() -> []u8
|
||||
|
||||
func callSig(sigId: string) -> SignResult:
|
||||
data <- DataProvider.provide_data()
|
||||
Sig sigId
|
||||
signature <- Sig.sign(data)
|
||||
<- signature
|
File diff suppressed because one or more lines are too long
@ -100,6 +100,7 @@
|
||||
<section class="tsd-index-section ">
|
||||
<h3>Methods</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="FluencePeer.html#getServices" class="tsd-kind-icon">get<wbr>Services</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="FluencePeer.html#getStatus" class="tsd-kind-icon">get<wbr>Status</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="FluencePeer.html#start" class="tsd-kind-icon">start</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="FluencePeer.html#stop" class="tsd-kind-icon">stop</a></li>
|
||||
@ -121,7 +122,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L138">internal/FluencePeer.ts:138</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L140">internal/FluencePeer.ts:140</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -146,7 +147,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L243">internal/FluencePeer.ts:243</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L257">internal/FluencePeer.ts:257</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -315,6 +316,28 @@
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group ">
|
||||
<h2>Methods</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class">
|
||||
<a name="getServices" class="tsd-anchor"></a>
|
||||
<h3>get<wbr>Services</h3>
|
||||
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
|
||||
<li class="tsd-signature tsd-kind-icon">get<wbr>Services<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-symbol">{ </span>sig<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Sig</span><span class="tsd-signature-symbol"> }</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-descriptions">
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L229">internal/FluencePeer.ts:229</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-symbol">{ </span>sig<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Sig</span><span class="tsd-signature-symbol"> }</span></h4>
|
||||
<ul class="tsd-parameters">
|
||||
<li class="tsd-parameter">
|
||||
<h5>sig<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Sig</span></h5>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class">
|
||||
<a name="getStatus" class="tsd-anchor"></a>
|
||||
<h3>get<wbr>Status</h3>
|
||||
@ -325,7 +348,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L156">internal/FluencePeer.ts:156</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L158">internal/FluencePeer.ts:158</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -347,7 +370,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L172">internal/FluencePeer.ts:172</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L174">internal/FluencePeer.ts:174</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -379,7 +402,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L225">internal/FluencePeer.ts:225</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L239">internal/FluencePeer.ts:239</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -402,7 +425,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L145">internal/FluencePeer.ts:145</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L147">internal/FluencePeer.ts:147</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -447,6 +470,9 @@
|
||||
<li class=" tsd-kind-get-signature tsd-parent-kind-class">
|
||||
<a href="FluencePeer.html#internals" class="tsd-kind-icon">internals</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class">
|
||||
<a href="FluencePeer.html#getServices" class="tsd-kind-icon">get<wbr>Services</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class">
|
||||
<a href="FluencePeer.html#getStatus" class="tsd-kind-icon">get<wbr>Status</a>
|
||||
</li>
|
||||
|
@ -93,6 +93,7 @@
|
||||
<h3>Methods</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="KeyPair.html#signBytes" class="tsd-kind-icon">sign<wbr>Bytes</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="KeyPair.html#toB58String" class="tsd-kind-icon">to<wbr>B58<wbr>String</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="KeyPair.html#toEd25519PrivateKey" class="tsd-kind-icon">to<wbr>Ed25519<wbr>Private<wbr>Key</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><a href="KeyPair.html#verify" class="tsd-kind-icon">verify</a></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-static"><a href="KeyPair.html#fromEd25519SK" class="tsd-kind-icon">from<wbr>Ed25519SK</a></li>
|
||||
@ -114,7 +115,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L26">internal/KeyPair.ts:26</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L26">internal/KeyPair.ts:26</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-parameters-title">Parameters</h4>
|
||||
@ -136,7 +137,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">Libp2p<wbr>Peer<wbr>Id<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">PeerId</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L24">internal/KeyPair.ts:24</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L24">internal/KeyPair.ts:24</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -158,7 +159,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L58">internal/KeyPair.ts:58</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L62">internal/KeyPair.ts:62</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-parameters-title">Parameters</h4>
|
||||
@ -171,6 +172,23 @@
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class">
|
||||
<a name="toB58String" class="tsd-anchor"></a>
|
||||
<h3>to<wbr>B58<wbr>String</h3>
|
||||
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
|
||||
<li class="tsd-signature tsd-kind-icon">to<wbr>B58<wbr>String<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">string</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-descriptions">
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L51">internal/KeyPair.ts:51</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">string</span></h4>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class">
|
||||
<a name="toEd25519PrivateKey" class="tsd-anchor"></a>
|
||||
<h3>to<wbr>Ed25519<wbr>Private<wbr>Key</h3>
|
||||
@ -181,7 +199,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L54">internal/KeyPair.ts:54</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L58">internal/KeyPair.ts:58</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Uint8Array</span></h4>
|
||||
@ -199,7 +217,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L62">internal/KeyPair.ts:62</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L66">internal/KeyPair.ts:66</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-parameters-title">Parameters</h4>
|
||||
@ -225,7 +243,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L35">internal/KeyPair.ts:35</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L35">internal/KeyPair.ts:35</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -256,7 +274,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/KeyPair.ts#L46">internal/KeyPair.ts:46</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/KeyPair.ts#L46">internal/KeyPair.ts:46</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -300,6 +318,9 @@
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class">
|
||||
<a href="KeyPair.html#signBytes" class="tsd-kind-icon">sign<wbr>Bytes</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class">
|
||||
<a href="KeyPair.html#toB58String" class="tsd-kind-icon">to<wbr>B58<wbr>String</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class">
|
||||
<a href="KeyPair.html#toEd25519PrivateKey" class="tsd-kind-icon">to<wbr>Ed25519<wbr>Private<wbr>Key</a>
|
||||
</li>
|
||||
|
@ -118,7 +118,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">init<wbr>Peer<wbr>Id<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L37">internal/commonTypes.ts:37</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L37">internal/commonTypes.ts:37</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -133,7 +133,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">particle<wbr>Id<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L32">internal/commonTypes.ts:32</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L32">internal/commonTypes.ts:32</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -148,7 +148,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">signature<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L52">internal/commonTypes.ts:52</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L52">internal/commonTypes.ts:52</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -163,7 +163,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">tetraplets<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{</span><span class="tsd-signature-symbol">[ </span><span class="tsd-signature-type">key</span><span class="tsd-signature-symbol"> in </span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">]</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">SecurityTetraplet</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol"> }</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L57">internal/commonTypes.ts:57</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L57">internal/commonTypes.ts:57</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -178,7 +178,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">timestamp<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L42">internal/commonTypes.ts:42</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L42">internal/commonTypes.ts:42</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -193,7 +193,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">ttl<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L47">internal/commonTypes.ts:47</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L47">internal/commonTypes.ts:47</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
|
@ -108,7 +108,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">Key<wbr>Pair<span class="tsd-signature-symbol">:</span> <a href="../classes/KeyPair.html" class="tsd-signature-type" data-tsd-kind="Class">KeyPair</a></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L71">internal/FluencePeer.ts:71</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L73">internal/FluencePeer.ts:73</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -124,7 +124,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">avm<wbr>Log<wbr>Level<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">LogLevel</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L65">internal/FluencePeer.ts:65</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L67">internal/FluencePeer.ts:67</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -139,7 +139,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">avm<wbr>Runner<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">AvmRunner</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L102">internal/FluencePeer.ts:102</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L104">internal/FluencePeer.ts:104</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -154,7 +154,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">check<wbr>Connection<wbr>Timeout<wbr>Ms<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L78">internal/FluencePeer.ts:78</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L80">internal/FluencePeer.ts:80</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -171,7 +171,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">connect<wbr>To<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Multiaddr</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">Node</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L60">internal/FluencePeer.ts:60</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L62">internal/FluencePeer.ts:62</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -193,7 +193,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">default<wbr>Ttl<wbr>Ms<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L97">internal/FluencePeer.ts:97</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L99">internal/FluencePeer.ts:99</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -210,7 +210,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">dial<wbr>Timeout<wbr>Ms<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L90">internal/FluencePeer.ts:90</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L92">internal/FluencePeer.ts:92</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -225,7 +225,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">skip<wbr>Check<wbr>Connection<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L85">internal/FluencePeer.ts:85</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L87">internal/FluencePeer.ts:87</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
|
@ -104,7 +104,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">is<wbr>Connected<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L117">internal/FluencePeer.ts:117</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L119">internal/FluencePeer.ts:119</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -119,7 +119,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">is<wbr>Initialized<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Boolean</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L112">internal/FluencePeer.ts:112</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L114">internal/FluencePeer.ts:114</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -134,7 +134,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">peer<wbr>Id<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L122">internal/FluencePeer.ts:122</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L124">internal/FluencePeer.ts:124</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -149,7 +149,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">relay<wbr>Peer<wbr>Id<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L127">internal/FluencePeer.ts:127</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L129">internal/FluencePeer.ts:129</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
|
@ -106,7 +106,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">Avm<wbr>Loglevel<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">LogLevel</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/FluencePeer.ts#L44">internal/FluencePeer.ts:44</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/FluencePeer.ts#L46">internal/FluencePeer.ts:46</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -122,7 +122,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">Peer<wbr>IdB58<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/internal/commonTypes.ts#L22">internal/commonTypes.ts:22</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/internal/commonTypes.ts#L22">internal/commonTypes.ts:22</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -140,7 +140,7 @@
|
||||
<div class="tsd-signature tsd-kind-icon">Fluence<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">{ </span>getPeer<span class="tsd-signature-symbol">: </span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol"> => </span><a href="classes/FluencePeer.html" class="tsd-signature-type" data-tsd-kind="Class">FluencePeer</a><span class="tsd-signature-symbol">; </span>getStatus<span class="tsd-signature-symbol">: </span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol"> => </span><a href="interfaces/PeerStatus.html" class="tsd-signature-type" data-tsd-kind="Interface">PeerStatus</a><span class="tsd-signature-symbol">; </span>start<span class="tsd-signature-symbol">: </span><span class="tsd-signature-symbol">(</span>config<span class="tsd-signature-symbol">?: </span><a href="interfaces/PeerConfig.html" class="tsd-signature-type" data-tsd-kind="Interface">PeerConfig</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol"> => </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span><span class="tsd-signature-symbol">; </span>stop<span class="tsd-signature-symbol">: </span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol"> => </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span><span class="tsd-signature-symbol"> }</span><span class="tsd-signature-symbol"> = ...</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/index.ts#L36">index.ts:36</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/index.ts#L36">index.ts:36</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
@ -260,7 +260,7 @@
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/c3512fd/src/index.ts#L25">index.ts:25</a></li>
|
||||
<li>Defined in <a href="https://github.com/fluencelabs/fluence-js/blob/1508a12/src/index.ts#L25">index.ts:25</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<h4 class="tsd-parameters-title">Parameters</h4>
|
||||
|
3465
package-lock.json
generated
3465
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,9 @@
|
||||
"main": "./dist/index.js",
|
||||
"typings": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"compile-aqua": "npm run compile-aqua:src && npm run compile-aqua:test",
|
||||
"compile-aqua:src": "aqua -i ./aqua/src/ -o ./src/internal/_aqua",
|
||||
"compile-aqua:test": "aqua -i ./aqua/tests/ -o ./src/__test__/_aqua",
|
||||
"test": "jest --watch",
|
||||
"test:all": "jest",
|
||||
"test:unit": "jest --testPathPattern=src/__test__/unit",
|
||||
@ -40,6 +43,8 @@
|
||||
"uuid": "8.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.5.3-258",
|
||||
"@fluencelabs/aqua-lib": "^0.3.4",
|
||||
"@types/jest": "^26.0.22",
|
||||
"jest": "^26.6.3",
|
||||
"js-base64": "^3.7.2",
|
||||
|
161
src/__test__/_aqua/sig-tests.ts
Normal file
161
src/__test__/_aqua/sig-tests.ts
Normal file
@ -0,0 +1,161 @@
|
||||
/**
|
||||
*
|
||||
* This file is auto-generated. Do not edit manually: changes may be erased.
|
||||
* Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
|
||||
* If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||
* Aqua version: 0.5.3-258
|
||||
*
|
||||
*/
|
||||
import { Fluence, FluencePeer } from '../../';
|
||||
import { CallParams, callFunction, registerService } from '../../internal/compilerSupport/v2';
|
||||
|
||||
// Services
|
||||
|
||||
export interface DataProviderDef {
|
||||
provide_data: (callParams: CallParams<null>) => number[] | Promise<number[]>;
|
||||
}
|
||||
export function registerDataProvider(service: DataProviderDef): void;
|
||||
export function registerDataProvider(serviceId: string, service: DataProviderDef): void;
|
||||
export function registerDataProvider(peer: FluencePeer, service: DataProviderDef): void;
|
||||
export function registerDataProvider(peer: FluencePeer, serviceId: string, service: DataProviderDef): void;
|
||||
|
||||
export function registerDataProvider(...args: any) {
|
||||
registerService(args, {
|
||||
defaultServiceId: 'data',
|
||||
functions: [
|
||||
{
|
||||
functionName: 'provide_data',
|
||||
argDefs: [],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
export interface SigDef {
|
||||
get_pub_key: (callParams: CallParams<null>) => string | Promise<string>;
|
||||
sign: (
|
||||
data: number[],
|
||||
callParams: CallParams<'data'>,
|
||||
) =>
|
||||
| { error: string | null; signature: number[] | null; success: boolean }
|
||||
| Promise<{ error: string | null; signature: number[] | null; success: boolean }>;
|
||||
verify: (
|
||||
signature: number[],
|
||||
data: number[],
|
||||
callParams: CallParams<'signature' | 'data'>,
|
||||
) => boolean | Promise<boolean>;
|
||||
}
|
||||
export function registerSig(service: SigDef): void;
|
||||
export function registerSig(serviceId: string, service: SigDef): void;
|
||||
export function registerSig(peer: FluencePeer, service: SigDef): void;
|
||||
export function registerSig(peer: FluencePeer, serviceId: string, service: SigDef): void;
|
||||
|
||||
export function registerSig(...args: any) {
|
||||
registerService(args, {
|
||||
defaultServiceId: 'sig',
|
||||
functions: [
|
||||
{
|
||||
functionName: 'get_pub_key',
|
||||
argDefs: [],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
{
|
||||
functionName: 'sign',
|
||||
argDefs: [
|
||||
{
|
||||
name: 'data',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
{
|
||||
functionName: 'verify',
|
||||
argDefs: [
|
||||
{
|
||||
name: 'signature',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'data',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
||||
export type CallSigResult = { error: string | null; signature: number[] | null; success: boolean };
|
||||
export function callSig(sigId: string, config?: { ttl?: number }): Promise<CallSigResult>;
|
||||
|
||||
export function callSig(peer: FluencePeer, sigId: string, config?: { ttl?: number }): Promise<CallSigResult>;
|
||||
|
||||
export function callSig(...args: any) {
|
||||
let script = `
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||
(call %init_peer_id% ("getDataSrv" "sigId") [] sigId)
|
||||
)
|
||||
(call %init_peer_id% ("data" "provide_data") [] data)
|
||||
)
|
||||
(call %init_peer_id% (sigId "sign") [data] signature)
|
||||
)
|
||||
(xor
|
||||
(call %init_peer_id% ("callbackSrv" "response") [signature])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||
)
|
||||
)
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||
)
|
||||
`;
|
||||
return callFunction(
|
||||
args,
|
||||
{
|
||||
functionName: 'callSig',
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
argDefs: [
|
||||
{
|
||||
name: 'sigId',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
names: {
|
||||
relay: '-relay-',
|
||||
getDataSrv: 'getDataSrv',
|
||||
callbackSrv: 'callbackSrv',
|
||||
responseSrv: 'callbackSrv',
|
||||
responseFnName: 'response',
|
||||
errorHandlingSrv: 'errorHandlingSrv',
|
||||
errorFnName: 'error',
|
||||
},
|
||||
},
|
||||
script,
|
||||
);
|
||||
}
|
87
src/__test__/integration/sigService.spec.ts
Normal file
87
src/__test__/integration/sigService.spec.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import { Fluence, FluencePeer, KeyPair, setLogLevel } from '../../index';
|
||||
import { allowServiceFn, Sig } from '../../services';
|
||||
import { registerSig, registerDataProvider, callSig } from '../_aqua/sig-tests';
|
||||
|
||||
let peer: FluencePeer;
|
||||
|
||||
describe('Sig service test suite', () => {
|
||||
afterEach(async () => {
|
||||
if (peer) {
|
||||
await peer.stop();
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
peer = new FluencePeer();
|
||||
await peer.start();
|
||||
});
|
||||
|
||||
it('Use custom sig service, success path', async () => {
|
||||
const customKeyPair = await KeyPair.randomEd25519();
|
||||
const customSig = new Sig(customKeyPair);
|
||||
const data = [1, 2, 3, 4, 5];
|
||||
|
||||
registerSig(peer, 'CustomSig', customSig);
|
||||
|
||||
registerDataProvider(peer, {
|
||||
provide_data: () => {
|
||||
return data;
|
||||
},
|
||||
});
|
||||
|
||||
customSig.securityGuard = allowServiceFn('data', 'provide_data');
|
||||
|
||||
const result = await callSig(peer, 'CustomSig');
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
const isSigCorrect = await customSig.verify(result.signature, data);
|
||||
expect(isSigCorrect).toBe(true);
|
||||
});
|
||||
|
||||
it('Use custom sig service, fail path', async () => {
|
||||
const customKeyPair = await KeyPair.randomEd25519();
|
||||
const customSig = new Sig(customKeyPair);
|
||||
const data = [1, 2, 3, 4, 5];
|
||||
|
||||
registerSig(peer, 'CustomSig', customSig);
|
||||
|
||||
registerDataProvider(peer, {
|
||||
provide_data: () => {
|
||||
return data;
|
||||
},
|
||||
});
|
||||
|
||||
customSig.securityGuard = allowServiceFn('wrong', 'wrong');
|
||||
|
||||
const result = await callSig(peer, 'CustomSig');
|
||||
});
|
||||
|
||||
it('Default sig service should be resolvable by peer id', async () => {
|
||||
const sig = peer.getServices().sig;
|
||||
|
||||
const data = [1, 2, 3, 4, 5];
|
||||
registerDataProvider(peer, {
|
||||
provide_data: () => {
|
||||
return data;
|
||||
},
|
||||
});
|
||||
|
||||
const callAsSigRes = await callSig(peer, 'sig');
|
||||
const callAsPeerIdRes = await callSig(peer, peer.getStatus().peerId);
|
||||
|
||||
expect(callAsSigRes.success).toBe(false);
|
||||
expect(callAsPeerIdRes.success).toBe(false);
|
||||
|
||||
sig.securityGuard = () => true;
|
||||
|
||||
const callAsSigResAfterGuardChange = await callSig(peer, 'sig');
|
||||
const callAsPeerIdResAfterGuardChange = await callSig(peer, peer.getStatus().peerId);
|
||||
|
||||
expect(callAsSigResAfterGuardChange.success).toBe(true);
|
||||
expect(callAsPeerIdResAfterGuardChange.success).toBe(true);
|
||||
|
||||
const isValid = await sig.verify(callAsSigResAfterGuardChange.signature, data);
|
||||
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
});
|
@ -1,37 +1,10 @@
|
||||
import { CallServiceData } from '../../internal/commonTypes';
|
||||
import { CallParams, CallServiceData } from '../../internal/commonTypes';
|
||||
import each from 'jest-each';
|
||||
import { BuiltInServiceContext, builtInServices } from '../../internal/builtInServices';
|
||||
import { builtInServices } from '../../internal/builtins/common';
|
||||
import { KeyPair } from '../../internal/KeyPair';
|
||||
import { Sig, defaultSigGuard, allowServiceFn } from '../../internal/builtins/Sig';
|
||||
import { toUint8Array } from 'js-base64';
|
||||
|
||||
const key = '+cmeYlZKj+MfSa9dpHV+BmLPm6wq4inGlsPlQ1GvtPk=';
|
||||
|
||||
const context = (async () => {
|
||||
const keyBytes = toUint8Array(key);
|
||||
const kp = await KeyPair.fromEd25519SK(keyBytes);
|
||||
const res: BuiltInServiceContext = {
|
||||
peerKeyPair: kp,
|
||||
peerId: kp.Libp2pPeerId.toB58String(),
|
||||
};
|
||||
return res;
|
||||
})();
|
||||
|
||||
const testData = [1, 2, 3, 4, 5, 6, 7, 9, 10];
|
||||
|
||||
// signature produced by KeyPair created from key above (`key` variable)
|
||||
const testDataSig = [
|
||||
224, 104, 245, 206, 140, 248, 27, 72, 68, 133, 111, 10, 164, 197, 242, 132, 107, 77, 224, 67, 99, 106, 76, 29, 144,
|
||||
121, 122, 169, 36, 173, 58, 80, 170, 102, 137, 253, 157, 247, 168, 87, 162, 223, 188, 214, 203, 220, 52, 246, 29,
|
||||
86, 77, 71, 224, 248, 16, 213, 254, 75, 78, 239, 243, 222, 241, 15,
|
||||
];
|
||||
|
||||
// signature produced by KeyPair created from some random KeyPair
|
||||
const testDataWrongSig = [
|
||||
116, 247, 189, 118, 236, 53, 147, 123, 219, 75, 176, 105, 101, 108, 233, 137, 97, 14, 146, 132, 252, 70, 51, 153,
|
||||
237, 167, 156, 150, 36, 90, 229, 108, 166, 231, 255, 137, 8, 246, 125, 0, 213, 150, 83, 196, 237, 221, 131, 159,
|
||||
157, 159, 25, 109, 95, 160, 181, 65, 254, 238, 47, 156, 240, 151, 58, 14,
|
||||
];
|
||||
|
||||
describe('Tests for default handler', () => {
|
||||
// prettier-ignore
|
||||
each`
|
||||
@ -65,11 +38,7 @@ describe('Tests for default handler', () => {
|
||||
${'peer'} | ${'timeout'} | ${[200, ['test']]} | ${0} | ${['test']}}
|
||||
${'peer'} | ${'timeout'} | ${[]} | ${1} | ${'timeout accepts exactly two arguments: timeout duration in ms and a message string'}}
|
||||
${'peer'} | ${'timeout'} | ${[200, 'test', 1]} | ${1} | ${'timeout accepts exactly two arguments: timeout duration in ms and a message string'}}
|
||||
|
||||
${'sig'} | ${'verify'} | ${[testData, testDataSig]} | ${0} | ${true}}
|
||||
${'sig'} | ${'verify'} | ${[testData, testDataWrongSig]} | ${0} | ${false}}
|
||||
${'sig'} | ${'sign'} | ${[]} | ${1} | ${'sign accepts exactly one argument: data be signed in format of u8 array of bytes'}}
|
||||
${'sig'} | ${'verify'} | ${[testData]} | ${1} | ${'verify accepts exactly two arguments: data and signature, both in format of u8 array of bytes'}}
|
||||
|
||||
`.test(
|
||||
//
|
||||
'$fnName with $args expected retcode: $retCode and result: $result',
|
||||
@ -90,7 +59,7 @@ describe('Tests for default handler', () => {
|
||||
};
|
||||
|
||||
// act
|
||||
const fn = builtInServices(await context)[req.serviceId][req.fnName];
|
||||
const fn = builtInServices[req.serviceId][req.fnName];
|
||||
const res = await fn(req);
|
||||
|
||||
// assert
|
||||
@ -118,7 +87,7 @@ describe('Tests for default handler', () => {
|
||||
};
|
||||
|
||||
// act
|
||||
const fn = builtInServices(await context)[req.serviceId][req.fnName];
|
||||
const fn = builtInServices[req.serviceId][req.fnName];
|
||||
const res = await fn(req);
|
||||
|
||||
// assert
|
||||
@ -127,166 +96,140 @@ describe('Tests for default handler', () => {
|
||||
result: 'The JS implementation of Peer does not support identify',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sig.sign should create the correct signature', async () => {
|
||||
// arrange
|
||||
const ctx = await context;
|
||||
const req: CallServiceData = {
|
||||
serviceId: 'sig',
|
||||
fnName: 'sign',
|
||||
args: [testData],
|
||||
tetraplets: [
|
||||
[
|
||||
{
|
||||
function_name: 'get_trust_bytes',
|
||||
json_path: '',
|
||||
peer_pk: '',
|
||||
service_id: 'trust-graph',
|
||||
},
|
||||
],
|
||||
const key = '+cmeYlZKj+MfSa9dpHV+BmLPm6wq4inGlsPlQ1GvtPk=';
|
||||
|
||||
const context = (async () => {
|
||||
const keyBytes = toUint8Array(key);
|
||||
const kp = await KeyPair.fromEd25519SK(keyBytes);
|
||||
const res = {
|
||||
peerKeyPair: kp,
|
||||
peerId: kp.Libp2pPeerId.toB58String(),
|
||||
};
|
||||
return res;
|
||||
})();
|
||||
|
||||
const testData = [1, 2, 3, 4, 5, 6, 7, 9, 10];
|
||||
|
||||
// signature produced by KeyPair created from key above (`key` variable)
|
||||
const testDataSig = [
|
||||
224, 104, 245, 206, 140, 248, 27, 72, 68, 133, 111, 10, 164, 197, 242, 132, 107, 77, 224, 67, 99, 106, 76, 29, 144,
|
||||
121, 122, 169, 36, 173, 58, 80, 170, 102, 137, 253, 157, 247, 168, 87, 162, 223, 188, 214, 203, 220, 52, 246, 29,
|
||||
86, 77, 71, 224, 248, 16, 213, 254, 75, 78, 239, 243, 222, 241, 15,
|
||||
];
|
||||
|
||||
// signature produced by KeyPair created from some random KeyPair
|
||||
const testDataWrongSig = [
|
||||
116, 247, 189, 118, 236, 53, 147, 123, 219, 75, 176, 105, 101, 108, 233, 137, 97, 14, 146, 132, 252, 70, 51, 153,
|
||||
237, 167, 156, 150, 36, 90, 229, 108, 166, 231, 255, 137, 8, 246, 125, 0, 213, 150, 83, 196, 237, 221, 131, 159,
|
||||
157, 159, 25, 109, 95, 160, 181, 65, 254, 238, 47, 156, 240, 151, 58, 14,
|
||||
];
|
||||
|
||||
const makeTetraplet = (initPeerId: string, serviceId?: string, fnName?: string): CallParams<'data'> => {
|
||||
return {
|
||||
initPeerId: initPeerId,
|
||||
tetraplets: {
|
||||
data: [
|
||||
{
|
||||
function_name: fnName,
|
||||
service_id: serviceId,
|
||||
},
|
||||
],
|
||||
particleContext: {
|
||||
particleId: 'some',
|
||||
initPeerId: ctx.peerId,
|
||||
timestamp: 595951200,
|
||||
ttl: 595961200,
|
||||
signature: 'sig',
|
||||
},
|
||||
};
|
||||
},
|
||||
} as any;
|
||||
};
|
||||
|
||||
// act
|
||||
const fn = builtInServices(ctx)[req.serviceId][req.fnName];
|
||||
const res = await fn(req);
|
||||
describe('Sig service tests', () => {
|
||||
it('sig.sign should create the correct signature', async () => {
|
||||
const ctx = await context;
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
|
||||
// assert
|
||||
expect(res).toMatchObject({
|
||||
retCode: 0,
|
||||
result: testDataSig,
|
||||
});
|
||||
const res = await sig.sign(testData, makeTetraplet(ctx.peerId));
|
||||
|
||||
expect(res.success).toBe(true);
|
||||
expect(res.signature).toStrictEqual(testDataSig);
|
||||
});
|
||||
|
||||
it('sig.verify should return true for the correct signature', async () => {
|
||||
const ctx = await context;
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
|
||||
const res = await sig.verify(testDataSig, testData);
|
||||
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('sig.verify should return false for the incorrect signature', async () => {
|
||||
const ctx = await context;
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
|
||||
const res = await sig.verify(testDataWrongSig, testData);
|
||||
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
|
||||
it('sign-verify call chain should work', async () => {
|
||||
const ctx = await context;
|
||||
const signReq: CallServiceData = {
|
||||
serviceId: 'sig',
|
||||
fnName: 'sign',
|
||||
args: [testData],
|
||||
tetraplets: [
|
||||
[
|
||||
{
|
||||
function_name: 'get_trust_bytes',
|
||||
json_path: '',
|
||||
peer_pk: '',
|
||||
service_id: 'trust-graph',
|
||||
},
|
||||
],
|
||||
],
|
||||
particleContext: {
|
||||
particleId: 'some',
|
||||
initPeerId: ctx.peerId,
|
||||
timestamp: 595951200,
|
||||
ttl: 595961200,
|
||||
signature: 'sig',
|
||||
},
|
||||
};
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
|
||||
const signFn = builtInServices(ctx)[signReq.serviceId][signReq.fnName];
|
||||
const signRes = await signFn(signReq);
|
||||
const signature = await sig.sign(testData, makeTetraplet(ctx.peerId));
|
||||
const res = await sig.verify(signature.signature, testData);
|
||||
|
||||
const verifyReq: CallServiceData = {
|
||||
serviceId: 'sig',
|
||||
fnName: 'verify',
|
||||
args: [testData, signRes.result],
|
||||
tetraplets: [],
|
||||
particleContext: {
|
||||
particleId: 'some',
|
||||
initPeerId: ctx.peerId,
|
||||
timestamp: 595951200,
|
||||
ttl: 595961200,
|
||||
signature: 'sig',
|
||||
},
|
||||
};
|
||||
|
||||
const verifyFn = builtInServices(ctx)[verifyReq.serviceId][verifyReq.fnName];
|
||||
const verifyRes = await verifyFn(verifyReq);
|
||||
|
||||
expect(verifyRes).toMatchObject({
|
||||
retCode: 0,
|
||||
result: true,
|
||||
});
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
|
||||
it('sig.sign should not allow data from incorrect services', async () => {
|
||||
// arrange
|
||||
it('sig.sign with defaultSigGuard should work for correct callParams', async () => {
|
||||
const ctx = await context;
|
||||
const req: CallServiceData = {
|
||||
serviceId: 'sig',
|
||||
fnName: 'sign',
|
||||
args: [testData],
|
||||
tetraplets: [
|
||||
[
|
||||
{
|
||||
function_name: 'some-other-fn',
|
||||
json_path: '',
|
||||
peer_pk: '',
|
||||
service_id: 'cool-service',
|
||||
},
|
||||
],
|
||||
],
|
||||
particleContext: {
|
||||
particleId: 'some',
|
||||
initPeerId: ctx.peerId,
|
||||
timestamp: 595951200,
|
||||
ttl: 595961200,
|
||||
signature: 'sig',
|
||||
},
|
||||
};
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
sig.securityGuard = defaultSigGuard(ctx.peerId);
|
||||
|
||||
// act
|
||||
const fn = builtInServices(ctx)[req.serviceId][req.fnName];
|
||||
const res = await fn(req);
|
||||
const signature = await sig.sign(testData, makeTetraplet(ctx.peerId, 'registry', 'get_key_bytes'));
|
||||
|
||||
// assert
|
||||
expect(res).toMatchObject({
|
||||
retCode: 1,
|
||||
result: expect.stringContaining("Only data from the following services is allowed to be signed:"),
|
||||
});
|
||||
await expect(signature).toBeDefined();
|
||||
});
|
||||
|
||||
it('sig.sign should not allow particles initiated from other peers', async () => {
|
||||
// arrange
|
||||
it('sig.sign with defaultSigGuard should not allow particles initiated from incorrect service', async () => {
|
||||
const ctx = await context;
|
||||
const req: CallServiceData = {
|
||||
serviceId: 'sig',
|
||||
fnName: 'sign',
|
||||
args: [testData],
|
||||
tetraplets: [
|
||||
[
|
||||
{
|
||||
function_name: 'some-other-fn',
|
||||
json_path: '',
|
||||
peer_pk: '',
|
||||
service_id: 'cool-service',
|
||||
},
|
||||
],
|
||||
],
|
||||
particleContext: {
|
||||
particleId: 'some',
|
||||
initPeerId: (await KeyPair.randomEd25519()).Libp2pPeerId.toB58String(),
|
||||
timestamp: 595951200,
|
||||
ttl: 595961200,
|
||||
signature: 'sig',
|
||||
},
|
||||
};
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
sig.securityGuard = defaultSigGuard(ctx.peerId);
|
||||
|
||||
// act
|
||||
const fn = builtInServices(ctx)[req.serviceId][req.fnName];
|
||||
const res = await fn(req);
|
||||
const res = await sig.sign(testData, makeTetraplet(ctx.peerId, 'other_service', 'other_fn'));
|
||||
|
||||
// assert
|
||||
expect(res).toMatchObject({
|
||||
retCode: 1,
|
||||
result: 'sign is only allowed to be called on the same peer the particle was initiated from',
|
||||
});
|
||||
await expect(res.success).toBe(false);
|
||||
await expect(res.error).toBe('Security guard validation failed');
|
||||
});
|
||||
|
||||
it('sig.sign with defaultSigGuard should not allow particles initiated from other peers', async () => {
|
||||
const ctx = await context;
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
sig.securityGuard = defaultSigGuard(ctx.peerId);
|
||||
|
||||
const res = await sig.sign(
|
||||
testData,
|
||||
makeTetraplet((await KeyPair.randomEd25519()).toB58String(), 'registry', 'get_key_bytes'),
|
||||
);
|
||||
|
||||
await expect(res.success).toBe(false);
|
||||
await expect(res.error).toBe('Security guard validation failed');
|
||||
});
|
||||
|
||||
it('changing securityGuard should work', async () => {
|
||||
const ctx = await context;
|
||||
const sig = new Sig(ctx.peerKeyPair);
|
||||
sig.securityGuard = allowServiceFn('test', 'test');
|
||||
|
||||
const successful1 = await sig.sign(testData, makeTetraplet(ctx.peerId, 'test', 'test'));
|
||||
const unSuccessful1 = await sig.sign(testData, makeTetraplet(ctx.peerId, 'wrong', 'wrong'));
|
||||
|
||||
sig.securityGuard = allowServiceFn('wrong', 'wrong');
|
||||
|
||||
const successful2 = await sig.sign(testData, makeTetraplet(ctx.peerId, 'wrong', 'wrong'));
|
||||
const unSuccessful2 = await sig.sign(testData, makeTetraplet(ctx.peerId, 'test', 'test'));
|
||||
|
||||
expect(successful1.success).toBe(true);
|
||||
expect(successful2.success).toBe(true);
|
||||
expect(unSuccessful1.success).toBe(false);
|
||||
expect(unSuccessful2.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -25,9 +25,11 @@ import { dataToString, jsonify } from './utils';
|
||||
import { concatMap, filter, pipe, Subject, tap } from 'rxjs';
|
||||
import { RequestFlow } from './compilerSupport/v1';
|
||||
import log from 'loglevel';
|
||||
import { BuiltInServiceContext, builtInServices } from './builtInServices';
|
||||
import { builtInServices } from './builtins/common';
|
||||
import { AvmRunner, InterpreterResult, LogLevel } from '@fluencelabs/avm-runner-interface';
|
||||
import { AvmRunnerBackground } from '@fluencelabs/avm-runner-background';
|
||||
import { defaultSigGuard, Sig } from './builtins/Sig';
|
||||
import { registerSig } from './_aqua/services';
|
||||
|
||||
/**
|
||||
* Node of the Fluence network specified as a pair of node's multiaddr and it's peer id
|
||||
@ -210,14 +212,24 @@ export class FluencePeer {
|
||||
}
|
||||
|
||||
this._legacyCallServiceHandler = new LegacyCallServiceHandler();
|
||||
registerDefaultServices(this, {
|
||||
peerKeyPair: this._keyPair,
|
||||
peerId: this.getStatus().peerId,
|
||||
});
|
||||
registerDefaultServices(this);
|
||||
|
||||
this._classServices = {
|
||||
sig: new Sig(this._keyPair),
|
||||
};
|
||||
this._classServices.sig.securityGuard = defaultSigGuard(this.getStatus().peerId);
|
||||
registerSig(this, this._classServices.sig);
|
||||
registerSig(this, this.getStatus().peerId, this._classServices.sig);
|
||||
|
||||
this._startParticleProcessing();
|
||||
}
|
||||
|
||||
getServices() {
|
||||
return {
|
||||
...this._classServices,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-initializes the peer: stops all the underlying workflows, stops the Aqua VM
|
||||
* and disconnects from the Fluence network
|
||||
@ -358,6 +370,10 @@ export class FluencePeer {
|
||||
private _particleSpecificHandlers = new Map<string, Map<string, GenericCallServiceHandler>>();
|
||||
private _commonHandlers = new Map<string, GenericCallServiceHandler>();
|
||||
|
||||
private _classServices: {
|
||||
sig: Sig;
|
||||
};
|
||||
|
||||
// Internal peer state
|
||||
|
||||
private _defaultTTL: number;
|
||||
@ -615,11 +631,10 @@ function serviceFnKey(serviceId: string, fnName: string) {
|
||||
return `${serviceId}/${fnName}`;
|
||||
}
|
||||
|
||||
function registerDefaultServices(peer: FluencePeer, context: BuiltInServiceContext) {
|
||||
const ctx = builtInServices(context);
|
||||
for (let serviceId in ctx) {
|
||||
for (let fnName in ctx[serviceId]) {
|
||||
const h = ctx[serviceId][fnName];
|
||||
function registerDefaultServices(peer: FluencePeer) {
|
||||
for (let serviceId in builtInServices) {
|
||||
for (let fnName in builtInServices[serviceId]) {
|
||||
const h = builtInServices[serviceId][fnName];
|
||||
peer.internals.regHandler.common(serviceId, fnName, h);
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ export class KeyPair {
|
||||
return new KeyPair(lib2p2Pid);
|
||||
}
|
||||
|
||||
toB58String(): string {
|
||||
return this.Libp2pPeerId.toB58String();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns 32 byte private key
|
||||
*/
|
||||
|
82
src/internal/_aqua/services.ts
Normal file
82
src/internal/_aqua/services.ts
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
*
|
||||
* This file is auto-generated. Do not edit manually: changes may be erased.
|
||||
* Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
|
||||
* If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||
* Aqua version: 0.5.3-258
|
||||
*
|
||||
*/
|
||||
import { Fluence, FluencePeer } from '../../';
|
||||
import { CallParams, callFunction, registerService } from '../../internal/compilerSupport/v2';
|
||||
|
||||
// Services
|
||||
|
||||
export interface SigDef {
|
||||
get_pub_key: (callParams: CallParams<null>) => string | Promise<string>;
|
||||
sign: (
|
||||
data: number[],
|
||||
callParams: CallParams<'data'>,
|
||||
) =>
|
||||
| { error: string | null; signature: number[] | null; success: boolean }
|
||||
| Promise<{ error: string | null; signature: number[] | null; success: boolean }>;
|
||||
verify: (
|
||||
signature: number[],
|
||||
data: number[],
|
||||
callParams: CallParams<'signature' | 'data'>,
|
||||
) => boolean | Promise<boolean>;
|
||||
}
|
||||
export function registerSig(service: SigDef): void;
|
||||
export function registerSig(serviceId: string, service: SigDef): void;
|
||||
export function registerSig(peer: FluencePeer, service: SigDef): void;
|
||||
export function registerSig(peer: FluencePeer, serviceId: string, service: SigDef): void;
|
||||
|
||||
export function registerSig(...args: any) {
|
||||
registerService(args, {
|
||||
defaultServiceId: 'sig',
|
||||
functions: [
|
||||
{
|
||||
functionName: 'get_pub_key',
|
||||
argDefs: [],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
{
|
||||
functionName: 'sign',
|
||||
argDefs: [
|
||||
{
|
||||
name: 'data',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
{
|
||||
functionName: 'verify',
|
||||
argDefs: [
|
||||
{
|
||||
name: 'signature',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'data',
|
||||
argType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
returnType: {
|
||||
tag: 'primitive',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// Functions
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CallServiceResult } from '@fluencelabs/avm-runner-interface';
|
||||
import { encode, decode } from 'bs58';
|
||||
import { PeerIdB58 } from 'src';
|
||||
import { GenericCallServiceHandler, ResultCodes } from './commonTypes';
|
||||
import { KeyPair } from './KeyPair';
|
||||
|
||||
const success = (result: any): CallServiceResult => {
|
||||
return {
|
||||
result: result,
|
||||
retCode: ResultCodes.success,
|
||||
};
|
||||
};
|
||||
|
||||
const error = (error: string): CallServiceResult => {
|
||||
return {
|
||||
result: error,
|
||||
retCode: ResultCodes.error,
|
||||
};
|
||||
};
|
||||
|
||||
export interface BuiltInServiceContext {
|
||||
peerKeyPair: KeyPair;
|
||||
peerId: PeerIdB58;
|
||||
}
|
||||
|
||||
export function builtInServices(context: BuiltInServiceContext): {
|
||||
[serviceId in string]: { [fnName in string]: GenericCallServiceHandler };
|
||||
} {
|
||||
return {
|
||||
op: {
|
||||
noop: (req) => {
|
||||
return success({});
|
||||
},
|
||||
|
||||
array: (req) => {
|
||||
return success(req.args);
|
||||
},
|
||||
|
||||
identity: (req) => {
|
||||
if (req.args.length > 1) {
|
||||
return error(`identity accepts up to 1 arguments, received ${req.args.length} arguments`);
|
||||
} else {
|
||||
return success(req.args.length === 0 ? {} : req.args[0]);
|
||||
}
|
||||
},
|
||||
|
||||
concat: (req) => {
|
||||
const incorrectArgIndices = req.args //
|
||||
.map((x, i) => [Array.isArray(x), i])
|
||||
.filter(([isArray, _]) => !isArray)
|
||||
.map(([_, index]) => index);
|
||||
|
||||
if (incorrectArgIndices.length > 0) {
|
||||
const str = incorrectArgIndices.join(', ');
|
||||
return error(`All arguments of 'concat' must be arrays: arguments ${str} are not`);
|
||||
} else {
|
||||
return success([].concat.apply([], req.args));
|
||||
}
|
||||
},
|
||||
|
||||
string_to_b58: (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('string_to_b58 accepts only one string argument');
|
||||
} else {
|
||||
return success(encode(new TextEncoder().encode(req.args[0])));
|
||||
}
|
||||
},
|
||||
|
||||
string_from_b58: (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('string_from_b58 accepts only one string argument');
|
||||
} else {
|
||||
return success(new TextDecoder().decode(decode(req.args[0])));
|
||||
}
|
||||
},
|
||||
|
||||
bytes_to_b58: (req) => {
|
||||
if (req.args.length !== 1 || !Array.isArray(req.args[0])) {
|
||||
return error('bytes_to_b58 accepts only single argument: array of numbers');
|
||||
} else {
|
||||
const argumentArray = req.args[0] as number[];
|
||||
return success(encode(new Uint8Array(argumentArray)));
|
||||
}
|
||||
},
|
||||
|
||||
bytes_from_b58: (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('bytes_from_b58 accepts only one string argument');
|
||||
} else {
|
||||
return success(Array.from(decode(req.args[0])));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
peer: {
|
||||
timeout: (req) => {
|
||||
if (req.args.length !== 2) {
|
||||
return error('timeout accepts exactly two arguments: timeout duration in ms and a message string');
|
||||
}
|
||||
const durationMs = req.args[0];
|
||||
const message = req.args[1];
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const res = success(message);
|
||||
resolve(res);
|
||||
}, durationMs);
|
||||
});
|
||||
},
|
||||
|
||||
identify: (req) => {
|
||||
return error('The JS implementation of Peer does not support identify');
|
||||
},
|
||||
},
|
||||
|
||||
sig: {
|
||||
sign: async (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('sign accepts exactly one argument: data be signed in format of u8 array of bytes');
|
||||
}
|
||||
|
||||
if (req.particleContext.initPeerId !== context.peerId) {
|
||||
return error('sign is only allowed to be called on the same peer the particle was initiated from');
|
||||
}
|
||||
|
||||
const t = req.tetraplets[0][0];
|
||||
const serviceFnPair = `${t.service_id}.${t.function_name}`;
|
||||
|
||||
const allowedServices = [
|
||||
'trust-graph.get_trust_bytes',
|
||||
'trust-graph.get_revocation_bytes',
|
||||
'registry.get_key_bytes',
|
||||
'registry.get_record_bytes',
|
||||
];
|
||||
|
||||
if (allowedServices.indexOf(serviceFnPair) === -1) {
|
||||
return error(
|
||||
'Only data from the following services is allowed to be signed: ' + allowedServices.join(', '),
|
||||
);
|
||||
}
|
||||
|
||||
const [data] = req.args;
|
||||
const signedData = await context.peerKeyPair.signBytes(Uint8Array.from(data));
|
||||
return success(Array.from(signedData));
|
||||
},
|
||||
|
||||
verify: async (req) => {
|
||||
if (req.args.length !== 2) {
|
||||
return error(
|
||||
'verify accepts exactly two arguments: data and signature, both in format of u8 array of bytes',
|
||||
);
|
||||
}
|
||||
const [data, signature] = req.args;
|
||||
const result = await context.peerKeyPair.verify(Uint8Array.from(data), Uint8Array.from(signature));
|
||||
return success(result);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
128
src/internal/builtins/Sig.ts
Normal file
128
src/internal/builtins/Sig.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { SecurityTetraplet } from '@fluencelabs/avm-runner-interface';
|
||||
import { CallParams, PeerIdB58 } from '../commonTypes';
|
||||
import { KeyPair } from '../KeyPair';
|
||||
import { SigDef } from '../_aqua/services';
|
||||
|
||||
/**
|
||||
* A predicate of call params for sig service's sign method which determines whether signing operation is allowed or not
|
||||
*/
|
||||
export type SigSecurityGuard = (params: CallParams<'data'>) => boolean;
|
||||
|
||||
/**
|
||||
* Only allow calls when tetraplet for 'data' argument satisfies the predicate
|
||||
*/
|
||||
export const allowTetraplet = (pred: (tetraplet: SecurityTetraplet) => boolean): SigSecurityGuard => {
|
||||
return (params) => {
|
||||
const t = params.tetraplets.data[0];
|
||||
return pred(t);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow data which comes from the specified serviceId and fnName
|
||||
*/
|
||||
export const allowServiceFn = (serviceId: string, fnName: string): SigSecurityGuard => {
|
||||
return allowTetraplet((t) => {
|
||||
return t.service_id === serviceId && t.function_name === fnName;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow data originated from the specified json_path
|
||||
*/
|
||||
export const allowExactJsonPath = (jsonPath: string): SigSecurityGuard => {
|
||||
return allowTetraplet((t) => {
|
||||
return t.json_path === jsonPath;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow signing when particle is initiated at the specified peer
|
||||
*/
|
||||
export const allowOnlyParticleOriginatedAt = (peerId: PeerIdB58): SigSecurityGuard => {
|
||||
return (params) => {
|
||||
return params.initPeerId === peerId;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow signing when all of the predicates are satisfied.
|
||||
* Useful for predicates reuse
|
||||
*/
|
||||
export const and = (...predicates: SigSecurityGuard[]): SigSecurityGuard => {
|
||||
return (params) => predicates.every((x) => x(params));
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow signing when any of the predicates are satisfied.
|
||||
* Useful for predicates reuse
|
||||
*/
|
||||
export const or = (...predicates: SigSecurityGuard[]): SigSecurityGuard => {
|
||||
return (params) => predicates.some((x) => x(params));
|
||||
};
|
||||
|
||||
export const defaultSigGuard = (peerId: PeerIdB58) => {
|
||||
return and(
|
||||
allowOnlyParticleOriginatedAt(peerId),
|
||||
or(
|
||||
allowServiceFn('trust-graph', 'get_trust_bytes'),
|
||||
allowServiceFn('trust-graph', 'get_revocation_bytes'),
|
||||
allowServiceFn('registry', 'get_key_bytes'),
|
||||
allowServiceFn('registry', 'get_record_bytes'),
|
||||
allowServiceFn('registry', 'get_host_record_bytes'),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
export class Sig implements SigDef {
|
||||
private _keyPair: KeyPair;
|
||||
|
||||
constructor(keyPair: KeyPair) {
|
||||
this._keyPair = keyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
securityGuard: SigSecurityGuard = (params) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the public key of KeyPair. Required by aqua
|
||||
*/
|
||||
get_pub_key() {
|
||||
return this._keyPair.toB58String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs the data using key pair's private key. Required by aqua
|
||||
*/
|
||||
async sign(
|
||||
data: number[],
|
||||
callParams: CallParams<'data'>,
|
||||
): Promise<{ error: string | null; signature: number[] | null; success: boolean }> {
|
||||
if (!this.securityGuard(callParams)) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Security guard validation failed',
|
||||
signature: null,
|
||||
};
|
||||
}
|
||||
|
||||
const signedData = await this._keyPair.signBytes(Uint8Array.from(data));
|
||||
|
||||
return {
|
||||
success: true,
|
||||
error: null,
|
||||
signature: Array.from(signedData),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the signature. Required by aqua
|
||||
*/
|
||||
verify(signature: number[], data: number[]): Promise<boolean> {
|
||||
return this._keyPair.verify(Uint8Array.from(data), Uint8Array.from(signature));
|
||||
}
|
||||
}
|
123
src/internal/builtins/common.ts
Normal file
123
src/internal/builtins/common.ts
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CallServiceResult } from '@fluencelabs/avm-runner-interface';
|
||||
import { encode, decode } from 'bs58';
|
||||
import { PeerIdB58 } from 'src';
|
||||
import { GenericCallServiceHandler, ResultCodes } from '../commonTypes';
|
||||
import { KeyPair } from '../KeyPair';
|
||||
|
||||
const success = (result: any): CallServiceResult => {
|
||||
return {
|
||||
result: result,
|
||||
retCode: ResultCodes.success,
|
||||
};
|
||||
};
|
||||
|
||||
const error = (error: string): CallServiceResult => {
|
||||
return {
|
||||
result: error,
|
||||
retCode: ResultCodes.error,
|
||||
};
|
||||
};
|
||||
|
||||
export const builtInServices = {
|
||||
op: {
|
||||
noop: (req) => {
|
||||
return success({});
|
||||
},
|
||||
|
||||
array: (req) => {
|
||||
return success(req.args);
|
||||
},
|
||||
|
||||
identity: (req) => {
|
||||
if (req.args.length > 1) {
|
||||
return error(`identity accepts up to 1 arguments, received ${req.args.length} arguments`);
|
||||
} else {
|
||||
return success(req.args.length === 0 ? {} : req.args[0]);
|
||||
}
|
||||
},
|
||||
|
||||
concat: (req) => {
|
||||
const incorrectArgIndices = req.args //
|
||||
.map((x, i) => [Array.isArray(x), i])
|
||||
.filter(([isArray, _]) => !isArray)
|
||||
.map(([_, index]) => index);
|
||||
|
||||
if (incorrectArgIndices.length > 0) {
|
||||
const str = incorrectArgIndices.join(', ');
|
||||
return error(`All arguments of 'concat' must be arrays: arguments ${str} are not`);
|
||||
} else {
|
||||
return success([].concat.apply([], req.args));
|
||||
}
|
||||
},
|
||||
|
||||
string_to_b58: (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('string_to_b58 accepts only one string argument');
|
||||
} else {
|
||||
return success(encode(new TextEncoder().encode(req.args[0])));
|
||||
}
|
||||
},
|
||||
|
||||
string_from_b58: (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('string_from_b58 accepts only one string argument');
|
||||
} else {
|
||||
return success(new TextDecoder().decode(decode(req.args[0])));
|
||||
}
|
||||
},
|
||||
|
||||
bytes_to_b58: (req) => {
|
||||
if (req.args.length !== 1 || !Array.isArray(req.args[0])) {
|
||||
return error('bytes_to_b58 accepts only single argument: array of numbers');
|
||||
} else {
|
||||
const argumentArray = req.args[0] as number[];
|
||||
return success(encode(new Uint8Array(argumentArray)));
|
||||
}
|
||||
},
|
||||
|
||||
bytes_from_b58: (req) => {
|
||||
if (req.args.length !== 1) {
|
||||
return error('bytes_from_b58 accepts only one string argument');
|
||||
} else {
|
||||
return success(Array.from(decode(req.args[0])));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
peer: {
|
||||
timeout: (req) => {
|
||||
if (req.args.length !== 2) {
|
||||
return error('timeout accepts exactly two arguments: timeout duration in ms and a message string');
|
||||
}
|
||||
const durationMs = req.args[0];
|
||||
const message = req.args[1];
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const res = success(message);
|
||||
resolve(res);
|
||||
}, durationMs);
|
||||
});
|
||||
},
|
||||
|
||||
identify: (req) => {
|
||||
return error('The JS implementation of Peer does not support identify');
|
||||
},
|
||||
},
|
||||
};
|
2
src/services.ts
Normal file
2
src/services.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './internal/builtins/Sig';
|
||||
export { registerSig } from './internal/_aqua/services';
|
Loading…
Reference in New Issue
Block a user