From 4ad941f99e85ee73ce043cc9f0db7da015710baf Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Mon, 18 Sep 2023 17:28:57 -0700 Subject: [PATCH 01/17] draft: update terms --- w3-filecoin.md | 248 +++++++++++++++++++++++++++++++------------------ 1 file changed, 158 insertions(+), 90 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index 1f19639..a3d7e5f 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -58,12 +58,12 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S There are several roles in the authorization flow: -| Name | Description | -| ------------- | ----------- | -| Storefront | [Principal] identified by a DID, representing a storage API like web3.storage. | -| Aggregator | [Principal] identified by a DID, representing a storage aggregator like w3filecoin. | -| Dealer | [Principal] identified by a DID, that arranges filecoin deals with storage providers. e.g. Spade. | -| Deal Tracker | [Principal] identified by a DID, that tracks deals made by the Dealer. | +| Name | Description | +| ------------ | ------------------------------------------------------------------------------------------------- | +| Storefront | [Principal] identified by a DID, representing a storage API like web3.storage. | +| Aggregator | [Principal] identified by a DID, representing a storage aggregator like w3filecoin. | +| Dealer | [Principal] identified by a DID, that arranges filecoin deals with storage providers. e.g. Spade. | +| Deal Tracker | [Principal] identified by a DID, that tracks deals made by the Dealer. | ### Storefront @@ -90,7 +90,7 @@ A _Deal Tracker_ is a type of [principal] identified by a DID (typically a `did: ## Overview -A Storefront is a service that ensures content addressed user/application data is stored perpetually on the decentralized web. A Storefront ingests user/application data and replicates it across various storage systems, including Filecoin Storage Providers. Content supplied to a Storefront can be of arbitrary size, while (Filecoin) Storage Providers demand large (>= 16GiB) content pieces. To align supply and demand requirements, the Aggregator accumulates supplied content pieces into a larger verifiable aggregate pieces per [FRC-0058](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md) that can be stored by Storage Providers. +A Storefront is a service that ensures content addressed user/application data is stored perpetually on the decentralized web. A Storefront ingests user/application data and replicates it across various storage systems, including Filecoin Storage Providers. Content supplied to a Storefront can be of arbitrary size, while (Filecoin) Storage Providers demand large (>= 16GiB) content pieces. To align supply and demand requirements, the Aggregator accumulates supplied content pieces into a larger verifiable aggregate pieces per [FRC-0058](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md) that can be stored by Storage Providers. ### Authorization @@ -104,22 +104,40 @@ A Storefront MUST submit content for aggregation by it's piece CID. It MAY be co Once a Storefront receives the offer for a piece, it is pending for verification. A receipt is issued to proof the transition of the added piece state from `uninitialized` into `pending` for verification. +#### `filecoin/accept` + +Receipt MUST have `fx.join` effect that links to the final task of the invoed workflow. Task MUST either succeed with `DealAggregationProof` providing cryptographic proof that offered piece had been included in the filecoin deal, or fail specifying reason of failure. + +#### `filecoin/submit` + +Receipt MUST have `fx.fork` effect that can be used to track progress of the workflow. Linkd task MUST succeed after offered piece has been verified and submitted for aggregation. If aggregation fails + +links to the task that either succeeds after piece had been submitted for aggregation + This receipt MUST have a link to a followup task (using `.fx.join` field) that either succeeds (if the piece was handled) or fails, so that its receipt MAY be looked up using it. If offered piece is already `pending` or `done` state does not change and receipt capturing current state is issued instead. -After a storefront dequeues the piece and verifies it, a receipt is created to proof the transition of the aggregate state from `pending` into `done`. This receipt MUST have link to a followup task (using `.fx.join` field) with `piece/add`. +After a storefront dequeues the piece and verifies it, a receipt is created to proof the transition of the aggregate state from `pending` into `done`. This receipt MUST have link to a followup task (using `.fx.join` field) with `piece/offer`. ```mermaid sequenceDiagram - actor Agent as

did:key:a... - actor Storefront as

did:web:web3.storage + participant Agent as

did:key:aAlice + participant Storefront as

did:web:web3.storage + participant Aggregator as

did:web:aggregator.web3.storage - Agent->>Storefront: invoke `filecoin/queue`
with:`did:key:aSpace` + Agent->>Storefront: invoke filecoin/offer
with:did:key:aSpace Note left of Storefront: Request piece to be added to filecoin deal + + activate Storefront - Storefront-->>Agent: receipt issued as `pending` - Storefront->>Storefront: invoke `filecoin/add`
with:`did:web:web3.storage` + Storefront-->>Agent: receipt issued as pending + Storefront->>Storefront: fx.fork filecoin/submit
with:did:web:web3.storage + + Storefront->>Aggregator: fx.join: piece/offer + + Storefront->>Storefront: fx.join filecoin/accept
with:did:web:web3.storage deactivate Storefront - Storefront-->>Agent: receipt issued
fx: `piece/add` + + ``` ### Storefront offers a piece to aggregate @@ -197,7 +215,7 @@ In this document, we will be exposing capabilities implemented by Storefront `we ### Storefront Capabilities -#### `filecoin/queue` +#### `filecoin/offer` An agent can invoke a capability to queue a piece to be included in a Filecoin deal(s) with a Storage providers. See [schema](#filecoinqueue-schema). @@ -207,20 +225,42 @@ An agent can invoke a capability to queue a piece to be included in a Filecoin d { "iss": "did:key:zAlice", "aud": "did:web:web3.storage", - "att": [{ - "with": "did:key:zAlice", - "can": "filecoin/queue", - "nb": { - "content": { "/": "bag...car" }, /* CID of file previously added to resource space */ - "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + "att": [ + { + "with": "did:key:zAlice", + "can": "filecoin/offer", + "nb": { + "content": { + "/": "bag...car" + } /* CID of file previously added to resource space */, + "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + } } - }], + ], "prf": [], "sig": "..." } ``` -A Storefront MUST issue a signed receipt to acknowledge the received request. The issued receipt MUST contain an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent task (`.fx.join` field) that is run when submitted piece is verified and either succeeds (implying that piece was valid) or fails (with an `error` describing a problem with the piece). +Storefront MAY fail invocation if it linked `content` has not been stored with it. + +```json +{ + "ran": "bafy...filOffer", + "out": { + "error": { + "name": "ContentNotFoundError", + "content": { "/": "bag...car" } + } + } +} +``` + +Alternatively Storefront MAY choose to queue request until it content has been uploaded. If Storefront has linked `content` or decides to queue request, it MUST issue a signed receipts acknowleding to acknowledge received request. The issued receipt MUST contain: + +1. An + +an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent task (`.fx.join` field) that is run when submitted piece is verified and either succeeds (implying that piece was valid) or fails (with an `error` describing a problem with the piece). ```json { @@ -251,14 +291,18 @@ When a piece request to be added is dequeued & verified, a Storefront MUST invok { "iss": "did:web:web3.storage", "aud": "did:web:web3.storage", - "att": [{ - "with": "did:web:web3.storage", - "can": "filecoin/add", - "nb": { - "content": { "/": "bag...car" }, /* CID of file previously added to resource space */ - "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + "att": [ + { + "with": "did:web:web3.storage", + "can": "filecoin/add", + "nb": { + "content": { + "/": "bag...car" + } /* CID of file previously added to resource space */, + "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + } } - }], + ], "prf": [], "sig": "..." } @@ -293,7 +337,7 @@ If the added piece is invalid, details on failing reason is also reported: "error": { "name": "InvalidPieceCID", "message": "...." - }, + } }, "fx": { "fork": [] @@ -316,14 +360,16 @@ A Storefront can invoke a capability to offer a piece to be aggregated for upcom { "iss": "did:web:web3.storage", "aud": "did:key:agg...", - "att": [{ - "with": "did:web:web3.storage", - "can": "aggregate/queue", - "nb": { - "piece": { "/": "bafk...commp" }, /* commitment proof for piece */ - "group": "did:web:free.web3.storage", /* grouping of joining segments into an aggregate */ + "att": [ + { + "with": "did:web:web3.storage", + "can": "aggregate/queue", + "nb": { + "piece": { "/": "bafk...commp" } /* commitment proof for piece */, + "group": "did:web:free.web3.storage" /* grouping of joining segments into an aggregate */ + } } - }], + ], "prf": [], "sig": "..." } @@ -358,15 +404,17 @@ When a piece request to be added is dequeued, an Aggregator MUST invoke `aggrega { "iss": "did:key:agg...", "aud": "did:key:agg...", - "att": [{ - "with": "did:key:agg...", - "can": "aggregate/add", - "nb": { - "piece": { "/": "commitment...car" }, /* commitment proof for piece */ - "storefront": "did:web:web3.storage", /* storefront responsible for invocation (with of aggregate/queue) */ - "group": "did:web:free.web3.storage", /* grouping of joining segments into an aggregate */ + "att": [ + { + "with": "did:key:agg...", + "can": "aggregate/add", + "nb": { + "piece": { "/": "commitment...car" } /* commitment proof for piece */, + "storefront": "did:web:web3.storage" /* storefront responsible for invocation (with of aggregate/queue) */, + "group": "did:web:free.web3.storage" /* grouping of joining segments into an aggregate */ + } } - }], + ], "prf": [], "sig": "..." } @@ -379,9 +427,11 @@ An Aggregator MUST issue a signed receipt with the result of the task. An arrang "ran": "bafy...arrange", "out": { "ok": { - "piece": { "/": "commitment...car" }, /* commitment proof for piece */ - "aggregate": { "/": "commitment...aggregate-proof" }, /* commitment proof */ - "path": "path-between-root-aggregate-and-piece" + "piece": { "/": "commitment...car" } /* commitment proof for piece */, + "aggregate": { + "/": "commitment...aggregate-proof" + } /* commitment proof */, + "path": "path-between-root-aggregate-and-piece" } }, "meta": {}, @@ -399,7 +449,7 @@ If the offered piece is invalid, the reason is also reported: "error": { "name": "InvaildPieceCID", "message": "..." - }, + } }, "meta": {}, "iss": "did:key:agg...", @@ -419,16 +469,22 @@ An Aggregator can invoke a capabilty to queue an aggregate that is ready to be i { "iss": "did:web:filecoin.web3.storage", "aud": "did:web:spade.storage", - "att": [{ - "with": "did:web:filecoin.web3.storage", - "can": "deal/queue", - "nb": { - "pieces": { "/": "bafy...many-cars" }, /* dag-cbor CID with content pieces */ - "aggregate": { "/": "bafk...aggregate-proof" }, /* commitment proof for aggregate */ - "storefront": "did:web:web3.storage", /* storefront responsible for invocation */ - "label": "deal-label" + "att": [ + { + "with": "did:web:filecoin.web3.storage", + "can": "deal/queue", + "nb": { + "pieces": { + "/": "bafy...many-cars" + } /* dag-cbor CID with content pieces */, + "aggregate": { + "/": "bafk...aggregate-proof" + } /* commitment proof for aggregate */, + "storefront": "did:web:web3.storage" /* storefront responsible for invocation */, + "label": "deal-label" + } } - }], + ], "prf": [], "sig": "..." } @@ -443,8 +499,8 @@ Finally, the `nb.offer` field represents a "Ferry" aggregate offer that is ready ```json /* offers block as an array of piece CIDs, encoded as DAG-JSON (for readability) */ [ - { "/": "commitment...car0" }, /* COMMP CID */ - { "/": "commitment...car1" }, /* COMMP CID */ + { "/": "commitment...car0" } /* COMMP CID */, + { "/": "commitment...car1" } /* COMMP CID */ /* ... */ ] ``` @@ -480,16 +536,22 @@ When an aggregate request to be added is dequeued, a dealer MUST invoke `deal/ad { "iss": "did:web:spade.storage", "aud": "did:web:spade.storage", - "att": [{ - "with": "did:web:spade.storage", - "can": "deal/add", - "nb": { - "pieces": { "/": "bafy...many-cars" }, /* dag-cbor CID with content pieces */ - "aggregate": { "/": "bafk...aggregate-proof" }, /* commitment proof for aggregate */ - "storefront": "did:web:web3.storage", /* storefront responsible for invocation */ - "label": "deal-label" + "att": [ + { + "with": "did:web:spade.storage", + "can": "deal/add", + "nb": { + "pieces": { + "/": "bafy...many-cars" + } /* dag-cbor CID with content pieces */, + "aggregate": { + "/": "bafk...aggregate-proof" + } /* commitment proof for aggregate */, + "storefront": "did:web:web3.storage" /* storefront responsible for invocation */, + "label": "deal-label" + } } - }], + ], "prf": [], "sig": "..." } @@ -502,7 +564,9 @@ A Dealer MUST issue a signed receipt with the result of the task. An arranged ag "ran": "bafy...invocation", "out": { "ok": { - "aggregate": { "/": "commitment...aggregate-proof" } /* commitment proof */ + "aggregate": { + "/": "commitment...aggregate-proof" + } /* commitment proof */ } }, "meta": {}, @@ -518,15 +582,17 @@ If offered aggregate is invalid, details on failing pieces are also reported: "ran": "bafy...invocation", "out": { "error": { - "name": "InvalidPiece", - "message": "....", - "aggregate": { "/": "bafk...aggregate-proof" }, /* commitment proof */ - "cause": [{ + "name": "InvalidPiece", + "message": "....", + "aggregate": { "/": "bafk...aggregate-proof" } /* commitment proof */, + "cause": [ + { "name": "InvalidPieceCID", "message": "....", - "piece": { "/": "bafk...car0" }, - }], - }, + "piece": { "/": "bafk...car0" } + } + ] + } }, "meta": {}, "iss": "did:web:spade.storage", @@ -546,13 +612,15 @@ A Storefront can query the state of an aggregate by invoking a `dealtracker/info { "iss": "did:web:web3.storage", "aud": "did:web:dealtracker...", - "att": [{ - "with": "did:web:web3.storage", - "can": "dealtracker/info", - "nb": { - "piece": { "/": "commitment...aggregate-proof" } /* commitment proof */ + "att": [ + { + "with": "did:web:web3.storage", + "can": "dealtracker/info", + "nb": { + "piece": { "/": "commitment...aggregate-proof" } /* commitment proof */ + } } - }], + ], "prf": [], "sig": "..." } @@ -578,7 +646,7 @@ Once this invocation is executed, a receipt is generated with the resulting aggr "updated": "2024-04-12T03:42:26.928993+00:00" } } - }, + } }, "fx": { "fork": [] @@ -751,8 +819,8 @@ type DealAddDetail struct { [`did:web`]: https://w3c-ccg.github.io/did-method-web/ [UCAN]: https://github.com/ucan-wg/spec/ [principal]: https://github.com/ucan-wg/spec/#321-principals - -[Protocol Labs]:https://protocol.ai/ -[Vasco Santos]:https://github.com/vasco-santos -[Irakli Gozalishvili]:https://github.com/Gozala -[Alan Shaw]:https://github.com/alanshaw +[Protocol Labs]: https://protocol.ai/ +[Vasco Santos]: https://github.com/vasco-santos +[Irakli Gozalishvili]: https://github.com/Gozala +[Alan Shaw]: https://github.com/alanshaw +[effect]: https://github.com/ucan-wg/invocation/#7-effect From 72636280e404255ddf7d83454b349f0cff2b86ba Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 00:00:21 -0700 Subject: [PATCH 02/17] feat: update per diagram --- w3-filecoin.md | 674 ++++++++++++++++++++++++++++--------------------- 1 file changed, 380 insertions(+), 294 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index a3d7e5f..f46ac82 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -33,24 +33,27 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S - [Authorization](#authorization) - [Capabilities](#capabilities) - [Storefront Capabilities](#storefront-capabilities) - - [`filecoin/queue`](#filecoinqueue) - - [`filecoin/add`](#filecoinadd) + - [`filecoin/offer`](#filecoinoffer) + - [`filecoin/submit`](#filecoinsubmit) + - [`filecoin/accept`](#filecoinaccept) - [Aggregator Capabilities](#aggregator-capabilities) - - [`aggregate/queue`](#aggregatequeue) - - [`aggregate/add`](#aggregateadd) + - [`piece/offer`](#aggregateoffer) + - [`piece/accept`](#aggregateaccept) - [Dealer Capabilities](#storefront-capabilities) - - [`deal/queue`](#dealqueue) - - [`deal/add`](#dealadd) + - [`aggregate/offer`](#aggregateoffer) + - [`aggregate/accept`](#aggregateaccept) - [Deal Tracker Capabilities](#deal-tracker-capabilities) - - [`dealtracker/info`](#dealtrackerinfo) + - [`deal/info`](#dealinfo) - [Schema](#schema) - [Base types](#base-types) - - [`filecoin/queue` schema](#filecoinqueue-schema) - - [`filecoin/add` schema](#filecoinadd-schema) - - [`aggregate/queue` schema](#aggregatequeue-schema) - - [`aggregate/add` schema](#aggregateadd-schema) - - [`deal/queue` schema](#dealqueue-schema) - - [`deal/add` schema](#dealadd-schema) + - [`filecoin/offer` schema](#filecoinoffer-schema) + - [`filecoin/submit` schema](#filecoinsubmit-schema) + - [`filecoin/accept` schema](#filecoinaccept-schema) + - [`piece/offer` schema](#pieceoffer-schema) + - [`piece/accept` schema](#pieceaccept-schema) + - [`aggregate/offer` schema](#aggregateoffer-schema) + - [`aggregate/accept` schema](#aggregateaccept-schema) + - [`deal/info` schema](#dealinfo-schema) # Terminology @@ -102,138 +105,157 @@ For example, an Aggregator can authorize invocations from `did:web:web3.storage` A Storefront MUST submit content for aggregation by it's piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the Storefront itself. A Storefront MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a Storefront client or delegated to a hired third party, ether way a Storefront MUST acknowledge request by issuing a signed receipt. A Storefront MAY decide to verify submitted piece prior to aggregation. A Storefront MAY also operate trusted actor that computes and submits pieces on content upload. -Once a Storefront receives the offer for a piece, it is pending for verification. A receipt is issued to proof the transition of the added piece state from `uninitialized` into `pending` for verification. +Once a Storefront receives the offer for a piece, it is pending for verification. Storefront MUST issue receipt proofing that request state has transition from `uninitialized` to `pending` if result was `ok` or to `failed` if result was `error`. Storefront MAY fail invocation if piece `content` has not been provided. -#### `filecoin/accept` - -Receipt MUST have `fx.join` effect that links to the final task of the invoed workflow. Task MUST either succeed with `DealAggregationProof` providing cryptographic proof that offered piece had been included in the filecoin deal, or fail specifying reason of failure. +#### `filecoin/accept` effect -#### `filecoin/submit` +Successful invocation receipt MUST have `fx.join` [effect] that links to the terminating task of the workflow. It allowing observer to lookup whether offered piece has landed on filecoin or failed. -Receipt MUST have `fx.fork` effect that can be used to track progress of the workflow. Linkd task MUST succeed after offered piece has been verified and submitted for aggregation. If aggregation fails +#### `filecoin/submit` effect -links to the task that either succeeds after piece had been submitted for aggregation +Successful invocation receipt MUST have `fx.fork` [effect] that links to the next task of the workflow. It allows observer to follow progress of the execution. -This receipt MUST have a link to a followup task (using `.fx.join` field) that either succeeds (if the piece was handled) or fails, so that its receipt MAY be looked up using it. If offered piece is already `pending` or `done` state does not change and receipt capturing current state is issued instead. - -After a storefront dequeues the piece and verifies it, a receipt is created to proof the transition of the aggregate state from `pending` into `done`. This receipt MUST have link to a followup task (using `.fx.join` field) with `piece/offer`. +The storefront MUST issue receipt of the linked `filecoin/submit` task after it verifies offered piece queues it for aggregation. This receipt MUST have `fx.join` [effect] that links to a `piece/offer` task that forwards submitted piece to the _Aggregator_. ```mermaid sequenceDiagram - participant Agent as

did:key:aAlice - participant Storefront as

did:web:web3.storage - participant Aggregator as

did:web:aggregator.web3.storage + participant Agent as
did:key:aAlice
+ participant Storefront as
did:web:web3.storage
+ participant Aggregator as
did:web:aggregator.web3.storage
- Agent->>Storefront: invoke filecoin/offer
with:did:key:aSpace - Note left of Storefront: Request piece to be added to filecoin deal + Agent->>Storefront: run: filecoin/offer
with:did:key:aSpace + Activate Storefront + Note left of Storefront: Request piece to be added to filecoin deal - activate Storefront - Storefront-->>Agent: receipt issued as pending - Storefront->>Storefront: fx.fork filecoin/submit
with:did:web:web3.storage + par + Storefront->>Storefront: fx.fork: filecoin/submit
with:did:web:web3.storage Storefront->>Aggregator: fx.join: piece/offer + Storefront-->>Agent: Receipt accepting offer + end + par + + Storefront->>Storefront: fx.join: filecoin/accept
with:did:web:web3.storage + + Storefront-->>Agent: Receipt with final result + end - Storefront->>Storefront: fx.join filecoin/accept
with:did:web:web3.storage + Storefront-->>Agent: Receipt akwnoledging offer deactivate Storefront + ``` ### Storefront offers a piece to aggregate -Storefront SHOULD propagate submitted pieces into Filecoin Storage Providers by forwarding them to an Aggregator. +Storefront SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an Aggregator. + +The Aggregator MUST queue offered pieces for an aggregation and issue a signed receipt proving that piece is been `pending` to be added. Issued receipt MUST have `fx.join` [effect] that links to a `piece/accept` task, which either succeeds with (aggregate) inclusion proof or fail. -The Aggregator MUST queue offered pieces for an aggregation and issue a signed receipt proving that submitted piece is `pending` to be added. Issued receipt MUST link to a followup task (using `.fx.join` field) that either succeeds with inclusion proof (if the piece was included into an aggregate) or fail, in order to allow state lookup by its receipt. +If Storefront offers a piece multiple times, Aggregator MUST respond with the receipt containing same result and effect(s). -If piece submitted by Storefront has already been queued, receipt with the same result and effect MUST be issued. +> ℹ️ Invocation nonce could be used to force piece to be included into another aggregate. The same Piece submitted by different Storefronts SHOULD NOT be considered a duplicate. -After an Aggregator dequeues the piece and includes it into an aggregate, it MUST issue a receipt with a piece inclusion proof, transition state of the submitted piece from `pending` into `done`. +After an Aggregator includes piece in an aggregate it MUST issue `piece/accept` receipt with an piece inclusion proof in result. Receipt MUST have `fx.join` [effect] that links to an `aggregate/offer` task for the aggregate where piece was included. ```mermaid sequenceDiagram - actor Storefront as

did:web:web3.storage - actor Aggregator as

did:key:agg... + participant Storefront as
did:web:web3.storage
+ participant Aggregator as
did:web:aggregator.web3.storage
+ participant Dealer as
did:web:dealer.web3.storage
- Storefront->>Aggregator: invoke `piece/queue`
with:`did:web:web3.storage` - Note left of Aggregator: Request piece to be included in aggregate + Storefront->>Aggregator: run: piece/offer
with: did:web:web3.storage activate Aggregator - Aggregator-->>Storefront: receipt issued as `pending` - Aggregator->>Aggregator: invoke `piece/add`
with:`did:key:agg...` + Note left of Aggregator: Request piece to be included in aggregate + par + Aggregator->>Aggregator: invoke piece/accept
with: did:key:agg... + Aggregator->>Dealer: fx.join aggregate/offer + Aggregator-->>Storefront: Receipt with inclusion proof + end + Aggregator-->>Storefront: Receipt akwnoledging offer deactivate Aggregator - Aggregator-->>Storefront: receipt issued
with inclusion proof ``` ### Aggregator offers dealer an aggregate -When the Aggregator has enough content pieces to build a qualified aggregate (dealers MAY impose different requirements), it MUST submit a Filecoin deal for the aggregate to a Dealer. Dealer MUST issue signed receipt acknowledging submission, actual deal negotiation with Filecoin Storage Providers MAY carry out of band. +When the Aggregator has enough content pieces to build a qualified aggregate (dealers MAY impose different requirements), it MUST offer an aggregate to the Dealer. Dealer MUST issue signed receipt acknowledging an offer, actual deal negotiation with Filecoin Storage Providers MAY be carried out of band. + +If Dealer receives a request with an aggregate multiple times it MUST (re)issue receipt with the same result and effects. -Once a Dealer receives an aggregate offer it is queued for negotiations with Storage Providers. Issued receipt is a proofs transition of the (offered aggregate) state from `uninitialized` into `pending`. If Dealer receives request with an aggregate already in pipeline it MUST simply reissue receipt with a same result and effects as the original request. +> ℹ️ Invocation nonce could be used to force aggregate to be reprocessed. -Issued receipt MUST link to a followup task (using `.fx.join` field) that either succeeds (if the aggregate deal made it into Filecoin chain) or fails (e.g. if Storage Provider failed to replicate and reported an error) so that its receipt COULD be looked up by it. +Issued receipt MUST have `fx.join` [effect] linking to a `aggregate/accept` task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if Storage Provider failed to replicate and reported an error). -After a Dealer dequeues the aggregate, it will interact with available Filecoin Storage Providers, in order to establish a previously determined (out of band) number of deals. Depending on storage providers availability, as well as the content present in the offer, the aggregate MAY be handled or not. A receipt is created to proof the transition of the aggregate state from `pending` into `done`. +Dealer MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue receipt for `aggregate/accept` task with succeed or failure result depending on the availability of storage providers and their ability to replicate content pieces in the aggregate. Successful task MUST have [`DataAggregationProof`] as result and contain no [effect]s. +Failed task MUST provide an error reason. When pieces of the aggregate can be retried issued receipt MUST contain `fx.fork` [effect]s with `piece/offer` task per piece. -> Note: Dealer MAY have several intermediate steps and states it transitions through, however those intentionally are not captured by this protocol, because storefront will take no action until success / failure condition is met. +> Note: Dealer MAY have several intermediate steps and states it transitions through, however those intentionally are not captured by this protocol, because other actor take no action until success / failure condition is met. ```mermaid sequenceDiagram - actor Aggregator as

did:key:agg... - actor Dealer as

did:key:brk... + participant Aggregator as
did:web:aggregator.web3.storage
+ participant Dealer as
did:web:dealer.web3.storage
- Aggregator->>Dealer: invoke `aggregate/queue`
with:`did:key:agg...` - Note left of Dealer: Request aggregate to be queued for deal proposal + Aggregator->>Dealer: run: aggregate/offer
with: did:key:agg... activate Dealer - Dealer-->>Aggregator: receipt issued as `pending` - Dealer->>Dealer: invoke `aggregate/add`
with:`did:key:brk...` + Note left of Dealer: Request to arrange deal for the aggregate + par + Dealer->>Dealer: run: aggregate/accept
with: did:key:brk... + Dealer-->>Aggregator: Receipt with DataAggregationProof or error + end + Dealer-->>Aggregator: Receipt akwnoledging offer deactivate Dealer - Dealer-->>Aggregator: receipt issued with `done` ``` -The Dealer MAY request an out of bound signature from the Storefront to validate the terms of a deal. +### _Deal Tracker_ can be queried for the aggregate status -### Storefront can query state of the aggregate deals +Storefront users MAY want to check status of the deals of their content. Deals change over time as they get renewed. Therefore, Storefront MAY invoke `deal/info` capability to gather information about an aggregate. Storefront SHOULD be able to look up aggregate from received inclusion proofs and use it to look up deal info by it. -Storefront users MAY want to check details about deals from the content they previously stored. These deals will change over time as they get renewed. Therefore, Storefront should invoke `dealtracker/info` capability to gather information about given aggregate identifier. Storefront should be able to look into previously received inclusion proofs to get the aggregate to look at based on the requested piece. +Dealer MAY also use _Deal Tracker_ to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue `aggregate/accept` receipts when they do. ```mermaid sequenceDiagram - actor Storefront as

did:web:web3.storage - actor DealTracker as

did:key:dealtracker... - - Storefront->>DealTracker: invoke `dealtracker/info` - Note left of DealTracker: Request DealTracker for information from given piece + participant Storefront as
did:web:web3.storage
+ participant DealTracker as
did:web:tracker.web3.storage
+ participant Aggregator as
did:web:aggregator.web3.storage
+ + Storefront->>DealTracker: run: deal/info + Note left of DealTracker: Request information about an aggregate + Aggregator->>DealTracker: run deal/info + Note right of DealTracker: Request information about an aggregate ``` ## Capabilities -This section describes the capabilities that form the w3 aggregation protocol, along with the details relevant for invoking capabilities with a service provider. +This section describes set of capabilities that form the w3 filecoin protocol, along with the details relevant for invoking them with a service provider. -In this document, we will be exposing capabilities implemented by Storefront `web3.storage`, Aggregator `aggregator.web3.storage`, Dealer `dealer.web3.storage` and Deal Tracker `dealtracker.web3.storage`. +In this document, we will be exposing capabilities implemented by Storefront `web3.storage`, Aggregator `aggregator.web3.storage`, Dealer `dealer.web3.storage` and Deal Tracker `tracker.web3.storage`. ### Storefront Capabilities #### `filecoin/offer` -An agent can invoke a capability to queue a piece to be included in a Filecoin deal(s) with a Storage providers. See [schema](#filecoinqueue-schema). +An agent MAY invoke `filecoin/offer` capability to request storing a content piece in Filecoin. See [schema](#filecoinqueue-schema). -> `did:key:zAlice` invokes capability from `did:web:web3.storage` +> `did:key:zAliceAgent` invokes `filecoin/offer` capability provided by `did:web:web3.storage` ```json { - "iss": "did:key:zAlice", + "iss": "did:key:zAliceAgent", "aud": "did:web:web3.storage", "att": [ { "with": "did:key:zAlice", "can": "filecoin/offer", "nb": { - "content": { - "/": "bag...car" - } /* CID of file previously added to resource space */, - "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + /* CID of the uploaded content */ + "content": { "/": "bag...car" }, + /* Commitment proof for piece */ + "piece": { "/": "bafk...commp" } } } ], @@ -242,7 +264,7 @@ An agent can invoke a capability to queue a piece to be included in a Filecoin d } ``` -Storefront MAY fail invocation if it linked `content` has not been stored with it. +Storefront MAY fail invocation if linked `content` has not yet been stored in the given space. ```json { @@ -256,22 +278,30 @@ Storefront MAY fail invocation if it linked `content` has not been stored with i } ``` -Alternatively Storefront MAY choose to queue request until it content has been uploaded. If Storefront has linked `content` or decides to queue request, it MUST issue a signed receipts acknowleding to acknowledge received request. The issued receipt MUST contain: +Alternatively, Storefront MAY choose to queue request until linked `content` has been uploaded. + +Storefront MUST issue a signed receipt for successful invocation akwnoledging request (regardless if it already has a `content` or if it chose to wait for an upload). -1. An +#### Effects -an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent task (`.fx.join` field) that is run when submitted piece is verified and either succeeds (implying that piece was valid) or fails (with an `error` describing a problem with the piece). +Issued receipt MUST have `fx.join` [effect] that links to the `filecoin/accept` task. Storefront MUST issue receipt for this task once content piece is aggregated and deal is published to filecoin chain. + +> This allows agent to get a result without having to follow the progress across invocation chain + +Issued receipt MUST have `fx.fork` [effect] that links to the `filecoin/submit` task. Storefront MUST issue receipt for this task once it processed request and queued it for aggregation or failed with an error (implying problem with piece or a content). + +> This allows agent to follow the progress across invocation chain. ```json { - "ran": "bafy...invocation", + "ran": "bafy...filOffer", "out": { - "ok": { - "piece": { "/": "bafk...commp" } /* commitment proof for piece */ - } + /* commitment proof for piece */ + "ok": { "piece": { "/": "bafk...commp" } } }, "fx": { - "join": { "/": "bafy...dequeue" } + "join": { "/": "bafy...filAccept" }, + "fork": [{ "/": "bafy...filSubmit" }] }, "meta": {}, "iss": "did:web:web3.storage", @@ -279,12 +309,58 @@ an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent t } ``` -See [`filecoin/add`](#filecoinadd) section to see the subsequent task. +#### `filecoin/accept` + +This task is effectively a shortcut allowing observer to find out result of the `filecoin/offer` task chain without having to follow each step. _Storefront_ MUST issue signed receipt with an [`DataAggregationProof`] result or an error. + +##### Filecoin Accept Failure -#### `filecoin/add` +```json +{ + "ran": "bafy...filAccept", + "out": { + "error": { + "name": "InvalidContentPiece", + "content": { "/": "bafk...commp" } + } + } +} +``` + +##### Filecoin Accept Success + +```json +{ + "ran": "bafy...filAccept", + "out": { + "ok": { + "inclusion": { + "tree": { + "path": [ + "bafk...root", + "bafk...parent", + "bafk...child", + "bag...car" + ], + "at": 1 + }, + "index": { + "path": [/** ... */], + "at": 7 + } + }, + "auxDataType": 0, + "auxDataSource": { + "dealID": 1245 + } + } + } +} +``` -When a piece request to be added is dequeued & verified, a Storefront MUST invoke `filecoin/add` with own DID propagating piece through the pipeline and signaling that submitted piece was handled. See [schema](#filecoinadd-schema). +#### `filecoin/submit` +The task MUST be invoked by the Storefront which MAY be used to verify offered content piece before propagating it through the pipeline. > `did:web:web3.storage` invokes capability from `did:web:web3.storage` ```json @@ -294,12 +370,12 @@ When a piece request to be added is dequeued & verified, a Storefront MUST invok "att": [ { "with": "did:web:web3.storage", - "can": "filecoin/add", + "can": "filecoin/submit", "nb": { - "content": { - "/": "bag...car" - } /* CID of file previously added to resource space */, - "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + /* CID of uploaded content */ + "content": { "/": "bag...car" }, + /* commitment proof for piece */ + "piece": { "/": "bafk...commp" } } } ], @@ -308,18 +384,19 @@ When a piece request to be added is dequeued & verified, a Storefront MUST invok } ``` -A Storefront MUST issue a signed receipt to communicate the response for the request. The issued receipt MUST contain an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent task (`.fx.join` field) that submits the piece for aggregation. +Storefront MUST issue signed receipt that either succeeds and links to the `aggregate/offer` task via `fx.join` [effect] or fails with specified reason (e.g. `content` does not corresponds to the provided `piece`). ```json { - "ran": "bafy...invocation", + "ran": "bafy...filSubmit", "out": { "ok": { - "piece": { "/": "bafk...commp" } /* commitment proof for piece */ + /* commitment proof for piece */ + "piece": { "/": "bafk...commp" } } }, "fx": { - "join": { "/": "bafy...aggregate...add" } + "join": { "/": "bafy...aggregateOffer" } }, "meta": {}, "iss": "did:web:web3.storage", @@ -327,12 +404,12 @@ A Storefront MUST issue a signed receipt to communicate the response for the req } ``` -See [`aggregate/add`](#aggregateadd) section to see the subsequent task. +See [`aggregate/offer`](#aggregateoffer) section to see the subsequent task. If the added piece is invalid, details on failing reason is also reported: ```json { - "ran": "bafy...invocation", + "ran": "bafy...filSubmit", "out": { "error": { "name": "InvalidPieceCID", @@ -350,23 +427,25 @@ If the added piece is invalid, details on failing reason is also reported: ### Aggregator Capabilities -#### `aggregate/queue` +#### `aggregate/offer` -A Storefront can invoke a capability to offer a piece to be aggregated for upcoming Filecoin deal(s). See [schema](#aggregateadd-schema). +A Storefront can invoke a capability to offer a piece to be aggregated for upcoming Filecoin deal(s). See [schema](#aggregateoffer-schema). -> `did:web:web3.storage` invokes capability from `did:key:agg...` +> `did:web:web3.storage` invokes capability from `did:web:aggregator.web3.storage` ```json { "iss": "did:web:web3.storage", - "aud": "did:key:agg...", + "aud": "did:web:aggregator.web3.storage", "att": [ { "with": "did:web:web3.storage", - "can": "aggregate/queue", + "can": "aggregate/offer", "nb": { - "piece": { "/": "bafk...commp" } /* commitment proof for piece */, - "group": "did:web:free.web3.storage" /* grouping of joining segments into an aggregate */ + /* commitment proof for piece */ + "piece": { "/": "bafk...commp" }, + /* grouping of joining segments into an aggregate */ + "group": "did:web:free.web3.storage" } } ], @@ -375,113 +454,84 @@ A Storefront can invoke a capability to offer a piece to be aggregated for upcom } ``` -An Aggregator MUST issue a signed receipt to acknowledge the received request. The issued receipt MUST contain an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent task (`.fx.join` field) that is run when piece is added to an aggregate and either succeeds (implying that aggregate was queued for being offered) or fails (with an `error` describing the problem). +An _Aggregator_ MUST issue a signed receipt to acknowledge the received request. Receipt MUST contain `fx.join` [effect] with a `aggregate/accept` task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. ```json { - "ran": "bafy...invocation", + "ran": "bafy...aggregateOffer", "out": { - "ok": {} + "ok": { + /* commitment proof for piece */ + "piece": { "/": "bafk...commp" }, + } }, "fx": { - "join": { "/": "bafy...dequeue" } + "join": { "/": "bafy...aggregateAccept" } }, "meta": {}, - "iss": "did:key:agg...", + "iss": "did:web:aggregator.web3.storage", "prf": [] } ``` -See [`aggregate/add`](#aggregateadd) section to see the subsequent task. +See [`aggregate/accept`](#aggregateaccept) section to see the subsequent task. -#### `aggregate/add` +#### `aggregate/accept` -When a piece request to be added is dequeued, an Aggregator MUST invoke `aggregate/add` to include it in an aggregate. The `storefront` requester identifier should be included in the invocation. See [schema](#aggregateadd-schema). +An _Aggregator_ MUST issue receipt for `aggregate/accept` task for the offered piece that was included into an aggregate. Receipt MUST either contain [`InclusionProof`] in a result and `fx.join` [effect] linking to `deal/offer` task, or an error detailing the reason. -> `did:key:agg...` invokes capability from `did:key:agg...` +> It is RECOMMENDED to not fail `aggregate/accept` as piece inclusion is deterministic computation occurring on validated data ```json { - "iss": "did:key:agg...", - "aud": "did:key:agg...", - "att": [ - { - "with": "did:key:agg...", - "can": "aggregate/add", - "nb": { - "piece": { "/": "commitment...car" } /* commitment proof for piece */, - "storefront": "did:web:web3.storage" /* storefront responsible for invocation (with of aggregate/queue) */, - "group": "did:web:free.web3.storage" /* grouping of joining segments into an aggregate */ - } - } - ], - "prf": [], - "sig": "..." -} -``` - -An Aggregator MUST issue a signed receipt with the result of the task. An arranged aggregate for piece receipt looks like: - -```json -{ - "ran": "bafy...arrange", + "ran": "bafy...aggregateAccept", "out": { "ok": { - "piece": { "/": "commitment...car" } /* commitment proof for piece */, - "aggregate": { - "/": "commitment...aggregate-proof" - } /* commitment proof */, - "path": "path-between-root-aggregate-and-piece" - } - }, - "meta": {}, - "iss": "did:key:agg...", - "prf": [] -} -``` - -If the offered piece is invalid, the reason is also reported: - -```json -{ - "ran": "bafy...invocation", - "out": { - "error": { - "name": "InvaildPieceCID", - "message": "..." + /* commitment proof for piece */ + "piece": { "/": "commitment...car" }, + /* commitment proof for aggregate */ + "aggregate": { "/": "commitment...aggregate" }, + /** inclusion proof */ + "inclusion": { + "tree": { + "path": [/** ... */], + "at": 4 + }, + "index": { + "path": [/** ... */], + "at": 7 + } + } } }, "meta": {}, - "iss": "did:key:agg...", + "iss": "did:web:aggregator.web3.storage", "prf": [] } ``` ### Dealer Capabilities -#### `deal/queue` +#### `deal/offer` -An Aggregator can invoke a capabilty to queue an aggregate that is ready to be included in Filecoin deal(s). See [schema](#dealadd-schema). +An _Aggregator_ can offer an aggregate for Filecoin deal inclusion by invoking a `deal/offer` capability. See [schema](#dealoffer-schema). -> `did:web:filecoin.web3.storage` invokes capability from `did:web:spade.storage` +> `did:web:aggregator.web3.storage` invokes capability from `did:web:dealer.web3.storage` ```json { - "iss": "did:web:filecoin.web3.storage", - "aud": "did:web:spade.storage", + "iss": "did:web:aggregator.web3.storage", + "aud": "did:web:dealer.web3.storage", "att": [ { - "with": "did:web:filecoin.web3.storage", - "can": "deal/queue", + "can": "deal/offer", + /* storefront responsible for invocation */ + "with": "did:web:web3.storage", "nb": { - "pieces": { - "/": "bafy...many-cars" - } /* dag-cbor CID with content pieces */, - "aggregate": { - "/": "bafk...aggregate-proof" - } /* commitment proof for aggregate */, - "storefront": "did:web:web3.storage" /* storefront responsible for invocation */, - "label": "deal-label" + /* commitment proof for aggregate */ + "aggregate": { "/": "bafk...aggregate-proof" }, + /* dag-cbor CID with content pieces */ + "pieces": { "/": "bafy...many-cars" }, } } ], @@ -490,11 +540,11 @@ An Aggregator can invoke a capabilty to queue an aggregate that is ready to be i } ``` -Invoking the `deal/queue` capability submits an aggregate to a dealer service for inclusion in one or more Filecoin deals. +Invoking the `deal/offer` capability is a request to arrange Filecoin deals for the aggregate. -The `nb.piece` field represents the proof of the `piece` to be offered for the deal. It is a CID with its piece size encoded. In addition, a Filecoin `nb.deal` contains the necessary fields for a Filecoin Deal proposal. More specifically, it MUST include `nb.deal.tenantId` that will allow dealer to select from multiple wallets associated with the tenant and MAY include an arbitrary `nb.deal.label` chosen by the client. +The `nb.aggregate` field represents commitment proof for the `aggregate` to arrange a deal(s) for. -Finally, the `nb.offer` field represents a "Ferry" aggregate offer that is ready for a Filecoin deal. Its value is the DAG-CBOR CID that refers to a "Ferry" offer. It encodes a dag-cbor block with an array of entries representing all the pieces to include in the aggregated deal. This array MUST be sorted in the exact same order as they were used to compute the aggregate piece CID. This block MUST be included in the CAR file that transports the invocation. Its format is: +The `nb.pieces` field represents a link to DAG-CBOR encoded list of pieces of an `aggregate`. The elements of the `nb.pieces` MUST be sorted in the exact same order as they were used to compute the aggregate piece CID. This block MUST be included with the invocation. Its format is: ```json /* offers block as an array of piece CIDs, encoded as DAG-JSON (for readability) */ @@ -505,86 +555,80 @@ Finally, the `nb.offer` field represents a "Ferry" aggregate offer that is ready ] ``` -Each entry of the decoded offers block has all the necessary information for a Storage Provider to fetch and store a CAR file. It includes an array of Filecoin `piece` info required by Storage Providers. +Each entry of the decoded offers block has all the necessary information for a Storage Provider to fetch and store a CAR file. -A Dealer MUST issue a signed receipt to acknowledge the received request. Issued receipt MUST contain an [effect](https://github.com/ucan-wg/invocation/#7-effect) with a subsequent task (`.fx.join` field) that is run when submitted aggregate is processed and either succeeds (implying that aggregate was handled and deals will be arranged) or fail (with `error` describing a problem with the aggregate). +The Dealer MUST issue a signed receipt to acknowledge request. Issued receipt MUST have `fx.join` [effect] linking to the `deal/accept` task which MUST succeed with [`DataAggregationProof`] after deals are live on Filecoin chain or fail (with an `error` describing a problem with the `aggregate`). ```json { - "ran": "bafy...invocation", + "ran": "bafy...dealOffer", "out": { - "ok": {} + "ok": { + /* commitment proof for aggregate */ + "aggregate": { "/": "bafk...aggregate-proof" }, + } }, "fx": { - "join": { "/": "bafy...dequeue" } + "join": { "/": "bafy...dealAccept" } }, "meta": {}, - "iss": "did:web:spade.storage", + "iss": "did:web:dealer.web3.storage", "prf": [] } ``` -See [`deal/add`](#dealadd) section to see the subsequent task. - -### `deal/add` +See [`deal/accept`](#dealaccept) section to see the subsequent task. -When an aggregate request to be added is dequeued, a dealer MUST invoke `deal/add` to store it. +### `deal/accept` -> `did:web:spade.storage` invokes capability from `did:web:spade.storage` +The _Dealer_ MUST issue receipt for `deal/accept` task once it arranges deals with Storage Providers and they are live on Filecoin chain. Receipt MUST either succeed with [`DataAggregationProof`] or fail (with an `error` describing a problem with the `aggregate`). ```json { - "iss": "did:web:spade.storage", - "aud": "did:web:spade.storage", - "att": [ - { - "with": "did:web:spade.storage", - "can": "deal/add", - "nb": { - "pieces": { - "/": "bafy...many-cars" - } /* dag-cbor CID with content pieces */, - "aggregate": { - "/": "bafk...aggregate-proof" - } /* commitment proof for aggregate */, - "storefront": "did:web:web3.storage" /* storefront responsible for invocation */, - "label": "deal-label" - } - } - ], - "prf": [], - "sig": "..." -} -``` - -A Dealer MUST issue a signed receipt with the result of the task. An arranged aggregate receipt looks like: - -```json -{ - "ran": "bafy...invocation", + "ran": "bafy...dealAccept", "out": { "ok": { - "aggregate": { - "/": "commitment...aggregate-proof" - } /* commitment proof */ + "inclusion": { + "tree": { + "path": [ + "bafk...root", + "bafk...parent", + "bafk...child", + "bag...car" + ], + "at": 1 + }, + "index": { + "path": [/** ... */], + "at": 7 + } + }, + "auxDataType": 0, + "auxDataSource": { + "dealID": 1245 + } } }, + "fx": {}, + "iss": "did:web:dealer.web3.storage", "meta": {}, - "iss": "did:web:spade.storage", "prf": [] } ``` -If offered aggregate is invalid, details on failing pieces are also reported: +If deal fails due to invalid piece issued receipt MUST have contain `fx.fork` [effect]s that to retry valid pieces. + +> ℹ️ This allows observer to follow new execution chain even if original piece inclusion failed. ```json { - "ran": "bafy...invocation", + "ran": "bafy...dealAccept", "out": { "error": { "name": "InvalidPiece", "message": "....", - "aggregate": { "/": "bafk...aggregate-proof" } /* commitment proof */, + /* commitment proof */ + "aggregate": { "/": "bafk...aggregate-proof" }, "cause": [ { "name": "InvalidPieceCID", @@ -594,43 +638,54 @@ If offered aggregate is invalid, details on failing pieces are also reported: ] } }, + "fx": { + "fork": [ + { "/": "bafy...piece1Offer" }, + { "/": "bafy...piece2Offer" }, + /** ... */ + ] + }, + "iss": "did:web:dealer.web3.storage", "meta": {}, - "iss": "did:web:spade.storage", "prf": [] } ``` ### Deal Tracker Capabilities -#### `dealtracker/info` +#### `deal/info` -A Storefront can query the state of an aggregate by invoking a `dealtracker/info` capability. +A _Storefront_ and _Aggregator_ MAY invoke `deal/info` capability to request a current state of the aggregate. -> `did:web:web3.storage` invokes capability from `did:key:dealtracker...` +> `did:web:web3.storage` invokes capability from `did:web:tracker.web3.storage` ```json { "iss": "did:web:web3.storage", - "aud": "did:web:dealtracker...", + "aud": "did:web:tracker.web3.storage", "att": [ { "with": "did:web:web3.storage", - "can": "dealtracker/info", + "can": "deal/info", "nb": { - "piece": { "/": "commitment...aggregate-proof" } /* commitment proof */ + /* commitment proof */ + "piece": { "/": "commitment...aggregate-proof" } } } ], + "nnc": "lmpxywjr", "prf": [], "sig": "..." } ``` -Once this invocation is executed, a receipt is generated with the resulting aggregate information: +> ⚠️ Invoker SHOULD utilize nonce on subsequent calls to avoid receiving response for the prior invocation. + +_Deal Tracker_ MUST succeed invocation and return deal information for the aggregate if it is on chain. ```json { - "ran": "bafy...get", + "ran": "bafy...dealInfo", "out": { "ok": { "deals": { @@ -657,40 +712,62 @@ Once this invocation is executed, a receipt is generated with the resulting aggr } ``` +_Deal Tracker_ MUST fail invocation if deal information for the aggregate is not on chain. + +```json +{ + "ran": "bafy...dealInfo", + "out": { + "error": { + "name": "DealNotFound" + /* ... */ + } + }, + "fx": { + "fork": [] + }, + "meta": {}, + "iss": "did:web:spade.storage", + "prf": [] +} +``` + ## Schema ### Base types ```ipldsch -type FilecoinCapability enum { - FilecoinQueue "filecoin/queue", - FilecoinAdd "filecoin/add" +type FilecoinCapability union { + | FilecoinOffer "filecoin/offer" + | FilecoinAccept "filecoin/accept" } representation inline { discriminantKey "can" } -type AggregateCapability enum { - AggregateQueue "aggregate/queue", - AggregateAdd "aggregate/add" +type PieceCapability union { + | PieceOffer "piece/offer" + | PieceSubmit "piece/submit" + | PieceAccept "piece/accept" } representation inline { discriminantKey "can" } -type DealCapability enum { - DealQueue "deal/queue", - DealAdd "deal/add" +type AggregateCapability union { + | AggregateOffer "aggregate/offer" + | AggregateAccept "aggregate/accept" } representation inline { discriminantKey "can" } -type DealTrackerCapability enum { - DealTrackerInfo "dealtracker/info" +type DealCapability enum { + DealOffer "deal/info", } representation inline { discriminantKey "can" } + type PieceRef struct { - piece PieceCid + piece PieceLink } type AgentDID string @@ -700,127 +777,136 @@ type DealerDID string type DealTrackerDID string # from a fr32-sha2-256-trunc254-padded-binary-tree multihash -type PieceCid Link -type ContentCid Link +type PieceLink Link +type Content Any type AggregatePieces [PieceCid] ``` -### `filecoin/queue` schema +### `filecoin/offer` schema ```ipldsch -type FilecoinQueue struct { +type FilecoinOffer struct { with AgentDID - nb FilecoinQueueDetail + nb FilecoinOfferDetail } -type FilecoinQueueDetail struct { +type FilecoinOfferDetail struct { # CID of file previously added to resource space - content ContentCid + content &Content # Piece as Filecoin Piece with padding - piece PieceCid + piece PieceLink } ``` -### `filecoin/add` schema +### `filecoin/submit` schema ```ipldsch -type FilecoinAdd struct { +type FilecoinSubmit struct { with AgentDID - nb FilecoinAddDetail + nb FilecoinOfferDetail } -type FilecoinAddDetail struct { - # CID of file previously added to resource space - content ContentCid - # Piece as Filecoin Piece with padding - piece PieceCid +type FilecoinSubmitDetail = FilecoinOfferDetail +``` + +### `filecoin/accept` schema + +```ipldsch +type FilecoinAccept struct { + with AgentDID + nb FilecoinAcceptDetail } + +type FilecoinAcceptDetail = FilecoinOfferDetail ``` -### `aggregate/queue` schema +### `piece/offer` schema ```ipldsch -type AggregateQueue struct { +type PieceOffer struct { with AgentDID - nb AggregateQueueDetail + nb PieceOfferDetail } -type AggregateQueueDetail struct { +type PieceOfferDetail struct { # Piece as Filecoin Piece with padding - piece PieceCid + piece PieceLink # grouping for joining segments into an aggregate (subset of space) group string } ``` -### `aggregate/add` schema +### `piece/accept` schema ```ipldsch -type AggregateAdd struct { +type PieceAccept struct { with AgentDID - nb AggregateAddDetail + nb PieceAcceptDetail } -type AggregateAddDetail struct { +type PieceAcceptDetail struct { # Piece as Filecoin Piece with padding - piece PieceCid - # storefront responsible for invocation - storefront string - # grouping for joining segments into an aggregate (subset of space) + piece PieceLink + # Grouping for joining segments into an aggregate (subset of space) group string } ``` -### `deal/queue` schema +### `aggregate/offer` schema ```ipldsch -type DealQueue struct { +type AggregateOffer struct { with StorefrontDID - nb DealQueueDetail + nb AggregateOfferDetail } -type DealQueueDetail struct { +type AggregateOfferDetail struct { # Contains each individual piece within Aggregate piece pieces &AggregatePieces # Piece as Aggregate of CARs with padding - aggregate PieceCid - # Fields to create a contract with a Storage Provider for aggregate - # storefront responsible for invocation - storefront string - # Label is an arbitrary client chosen label to apply to the deal - # @see https://github.com/filecoin-project/go-state-types/blob/ff2ed169ff566458f2acd8b135d62e8ca27e7d0c/builtin/v9/market/deal.go#L201-L221 - label string + aggregate PieceLink } ``` -### `deal/add` schema +### `aggregate/accept` schema ```ipldsch -type DealAdd struct { +type AggregateAccept struct { with StorefrontDID - nb DealAddDetail + nb AggregateAcceptDetail } -type DealAddDetail struct { +type AggregateAcceptDetail struct { # Contains each individual piece within Aggregate piece pieces &AggregatePieces # Piece as Aggregate of CARs with padding - aggregate PieceCid - # Fields to create a contract with a Storage Provider for aggregate - # storefront responsible for invocation - storefront string - # Label is an arbitrary client chosen label to apply to the deal - # @see https://github.com/filecoin-project/go-state-types/blob/ff2ed169ff566458f2acd8b135d62e8ca27e7d0c/builtin/v9/market/deal.go#L201-L221 - label string + aggregate PieceLink +} +``` + +### `deal/info` schema + +```ipldsch +type DealInfo struct { + with StorefrontDID + nb DealInfoDetail +} + +type DealInfoDetail struct { + # Piece as Aggregate of CARs with padding + aggregate PieceLink } ``` [`did:web`]: https://w3c-ccg.github.io/did-method-web/ +[`did:key`]:https://w3c-ccg.github.io/did-method-key/ [UCAN]: https://github.com/ucan-wg/spec/ [principal]: https://github.com/ucan-wg/spec/#321-principals [Protocol Labs]: https://protocol.ai/ [Vasco Santos]: https://github.com/vasco-santos [Irakli Gozalishvili]: https://github.com/Gozala [Alan Shaw]: https://github.com/alanshaw -[effect]: https://github.com/ucan-wg/invocation/#7-effect +[effect]:https://github.com/ucan-wg/invocation/#7-effect +[`DataAggregationProof`]:https://github.com/filecoin-project/go-data-segment/blob/e3257b64fa2c84e0df95df35de409cfed7a38438/datasegment/verifier.go#L8-L14 +[`InclusionProof`]:https://github.com/filecoin-project/go-data-segment/blob/e3257b64fa2c84e0df95df35de409cfed7a38438/datasegment/inclusion.go#L30-L39 From 9d135c98d51945f79fa57f425f397c36d080f245 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 08:52:00 -0700 Subject: [PATCH 03/17] Apply suggestions from code review Co-authored-by: Alan Shaw Co-authored-by: Vasco Santos --- w3-filecoin.md | 145 +++++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index f46ac82..e29be51 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -105,17 +105,17 @@ For example, an Aggregator can authorize invocations from `did:web:web3.storage` A Storefront MUST submit content for aggregation by it's piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the Storefront itself. A Storefront MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a Storefront client or delegated to a hired third party, ether way a Storefront MUST acknowledge request by issuing a signed receipt. A Storefront MAY decide to verify submitted piece prior to aggregation. A Storefront MAY also operate trusted actor that computes and submits pieces on content upload. -Once a Storefront receives the offer for a piece, it is pending for verification. Storefront MUST issue receipt proofing that request state has transition from `uninitialized` to `pending` if result was `ok` or to `failed` if result was `error`. Storefront MAY fail invocation if piece `content` has not been provided. +Once a Storefront receives the offer for a piece, it is pending for verification. The Storefront MUST issue a receipt proving that request state has transition from `uninitialized` to `pending` if result was `ok`, or to `failed` if result was `error`. The Storefront MAY fail invocation if piece `content` has not been provided. #### `filecoin/accept` effect -Successful invocation receipt MUST have `fx.join` [effect] that links to the terminating task of the workflow. It allowing observer to lookup whether offered piece has landed on filecoin or failed. +A successful invocation receipt MUST have `fx.join` [effect] that links to the terminating task of the workflow. It allows the observer to lookup whether the offered piece has landed on filecoin or failed. #### `filecoin/submit` effect -Successful invocation receipt MUST have `fx.fork` [effect] that links to the next task of the workflow. It allows observer to follow progress of the execution. +Successful invocation receipt MUST have an `fx.fork` [effect] that links to the next task of the workflow. It allows the observer to follow progress of the execution. -The storefront MUST issue receipt of the linked `filecoin/submit` task after it verifies offered piece queues it for aggregation. This receipt MUST have `fx.join` [effect] that links to a `piece/offer` task that forwards submitted piece to the _Aggregator_. +The Storefront MUST issue a receipt for the linked `filecoin/submit` task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a `piece/offer` task that forwards the submitted piece to the _Aggregator_. ```mermaid sequenceDiagram @@ -141,7 +141,7 @@ sequenceDiagram Storefront-->>Agent: Receipt with final result end - Storefront-->>Agent: Receipt akwnoledging offer + Storefront-->>Agent: Receipt acknowledging offer deactivate Storefront @@ -150,17 +150,17 @@ sequenceDiagram ### Storefront offers a piece to aggregate -Storefront SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an Aggregator. +A Storefront SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an Aggregator. -The Aggregator MUST queue offered pieces for an aggregation and issue a signed receipt proving that piece is been `pending` to be added. Issued receipt MUST have `fx.join` [effect] that links to a `piece/accept` task, which either succeeds with (aggregate) inclusion proof or fail. +The Aggregator MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have an `fx.join` [effect] that links to a `piece/accept` task, which either succeeds with an (aggregate) inclusion proof or fails. -If Storefront offers a piece multiple times, Aggregator MUST respond with the receipt containing same result and effect(s). +If the Storefront offers a piece multiple times, the Aggregator MUST respond with a receipt that contains the _same_ result and effect(s). -> ℹ️ Invocation nonce could be used to force piece to be included into another aggregate. +> ℹ️ An invocation nonce MAY be used to force a piece to be included in another aggregate. The same Piece submitted by different Storefronts SHOULD NOT be considered a duplicate. -After an Aggregator includes piece in an aggregate it MUST issue `piece/accept` receipt with an piece inclusion proof in result. Receipt MUST have `fx.join` [effect] that links to an `aggregate/offer` task for the aggregate where piece was included. +After an Aggregator includes a piece in an aggregate it MUST issue a `piece/accept` receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an `aggregate/offer` task for the aggregate where piece was included. ```mermaid sequenceDiagram @@ -176,24 +176,24 @@ sequenceDiagram Aggregator->>Dealer: fx.join aggregate/offer Aggregator-->>Storefront: Receipt with inclusion proof end - Aggregator-->>Storefront: Receipt akwnoledging offer + Aggregator-->>Storefront: Receipt acknowledging offer deactivate Aggregator ``` ### Aggregator offers dealer an aggregate -When the Aggregator has enough content pieces to build a qualified aggregate (dealers MAY impose different requirements), it MUST offer an aggregate to the Dealer. Dealer MUST issue signed receipt acknowledging an offer, actual deal negotiation with Filecoin Storage Providers MAY be carried out of band. +When the Aggregator has enough content pieces to build a qualified aggregate (dealers MAY impose different requirements), it MUST offer an aggregate to the Dealer. The Dealer MUST issue a signed receipt acknowledging an offer, and then deal negotiation with Filecoin Storage Providers MAY be carried out of band. -If Dealer receives a request with an aggregate multiple times it MUST (re)issue receipt with the same result and effects. +If a Dealer receives a request with an aggregate multiple times it MUST (re)issue a receipt with the _same_ result and effects. -> ℹ️ Invocation nonce could be used to force aggregate to be reprocessed. +> ℹ️ An invocation nonce MAY be used to force an aggregate to be reprocessed. -Issued receipt MUST have `fx.join` [effect] linking to a `aggregate/accept` task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if Storage Provider failed to replicate and reported an error). +The issued receipt MUST have an `fx.join` [effect] linking to an `aggregate/accept` task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if a Storage Provider failed to replicate and reported an error). -Dealer MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue receipt for `aggregate/accept` task with succeed or failure result depending on the availability of storage providers and their ability to replicate content pieces in the aggregate. Successful task MUST have [`DataAggregationProof`] as result and contain no [effect]s. -Failed task MUST provide an error reason. When pieces of the aggregate can be retried issued receipt MUST contain `fx.fork` [effect]s with `piece/offer` task per piece. +The Dealer MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the `aggregate/accept` task with a succeed or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. +A failed task MUST provide an error reason. When pieces of the aggregate can be retried, the issued receipt MUST contain `fx.fork` [effect]s with `piece/offer` tasks per piece. -> Note: Dealer MAY have several intermediate steps and states it transitions through, however those intentionally are not captured by this protocol, because other actor take no action until success / failure condition is met. +> Note: The Dealer MAY have several intermediate steps and states it transitions through, however those are _not_ captured by this protocol intentionally, because the other actor take no action until a success / failure condition is met. ```mermaid sequenceDiagram @@ -213,25 +213,25 @@ sequenceDiagram ### _Deal Tracker_ can be queried for the aggregate status -Storefront users MAY want to check status of the deals of their content. Deals change over time as they get renewed. Therefore, Storefront MAY invoke `deal/info` capability to gather information about an aggregate. Storefront SHOULD be able to look up aggregate from received inclusion proofs and use it to look up deal info by it. +Storefront users MAY want to check status of the deals for their content. Deals change over time as they get renewed. Therefore, the Storefront MAY invoke `deal/info` capability to gather information about an aggregate. The Storefront SHOULD be able to look up an aggregate from received inclusion proofs and use them to look up deal status information. -Dealer MAY also use _Deal Tracker_ to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue `aggregate/accept` receipts when they do. +The Dealer MAY also use a _Deal Tracker_ to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue `aggregate/accept` receipts when they do. ```mermaid sequenceDiagram participant Storefront as
did:web:web3.storage
participant DealTracker as
did:web:tracker.web3.storage
- participant Aggregator as
did:web:aggregator.web3.storage
+ participant Dealer as
did:web:dealer.web3.storage
Storefront->>DealTracker: run: deal/info Note left of DealTracker: Request information about an aggregate - Aggregator->>DealTracker: run deal/info + Dealer->>DealTracker: run deal/info Note right of DealTracker: Request information about an aggregate ``` ## Capabilities -This section describes set of capabilities that form the w3 filecoin protocol, along with the details relevant for invoking them with a service provider. +This section describes the set of capabilities that form the w3 filecoin protocol, along with the details relevant for invoking them with a service provider. In this document, we will be exposing capabilities implemented by Storefront `web3.storage`, Aggregator `aggregator.web3.storage`, Dealer `dealer.web3.storage` and Deal Tracker `tracker.web3.storage`. @@ -239,7 +239,7 @@ In this document, we will be exposing capabilities implemented by Storefront `we #### `filecoin/offer` -An agent MAY invoke `filecoin/offer` capability to request storing a content piece in Filecoin. See [schema](#filecoinqueue-schema). +An agent MAY invoke the `filecoin/offer` capability to request storing a content piece in Filecoin. See [schema](#filecoinqueue-schema). > `did:key:zAliceAgent` invokes `filecoin/offer` capability provided by `did:web:web3.storage` @@ -264,7 +264,7 @@ An agent MAY invoke `filecoin/offer` capability to request storing a content pie } ``` -Storefront MAY fail invocation if linked `content` has not yet been stored in the given space. +The Storefront MAY fail the invocation if the linked `content` has not yet been stored in the given space. ```json { @@ -278,19 +278,19 @@ Storefront MAY fail invocation if linked `content` has not yet been stored in th } ``` -Alternatively, Storefront MAY choose to queue request until linked `content` has been uploaded. +Alternatively, the Storefront MAY choose to queue request until linked `content` has been uploaded. -Storefront MUST issue a signed receipt for successful invocation akwnoledging request (regardless if it already has a `content` or if it chose to wait for an upload). +Storefront MUST issue a signed receipt for a successful invocation acknowledging the request (regardless if it already has a `content` or if it chose to wait for an upload). #### Effects -Issued receipt MUST have `fx.join` [effect] that links to the `filecoin/accept` task. Storefront MUST issue receipt for this task once content piece is aggregated and deal is published to filecoin chain. +The issued receipt MUST have an `fx.join` [effect] that links to the `filecoin/accept` task. The Storefront MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. -> This allows agent to get a result without having to follow the progress across invocation chain +> This allows an agent to get a result without having to follow progress across the entire invocation chain. -Issued receipt MUST have `fx.fork` [effect] that links to the `filecoin/submit` task. Storefront MUST issue receipt for this task once it processed request and queued it for aggregation or failed with an error (implying problem with piece or a content). +The issued receipt MUST have an `fx.fork` [effect] that links to the `filecoin/submit` task. The Storefront MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). -> This allows agent to follow the progress across invocation chain. +> This allows an agent to follow progress across the entire invocation chain. ```json { @@ -311,7 +311,7 @@ Issued receipt MUST have `fx.fork` [effect] that links to the `filecoin/submit` #### `filecoin/accept` -This task is effectively a shortcut allowing observer to find out result of the `filecoin/offer` task chain without having to follow each step. _Storefront_ MUST issue signed receipt with an [`DataAggregationProof`] result or an error. +This task is effectively a shortcut allowing an observer to find out the result of the `filecoin/offer` task chain without having to follow each step. The _Storefront_ MUST issue a signed receipt with an [`DataAggregationProof`] result or an error. ##### Filecoin Accept Failure @@ -360,7 +360,7 @@ This task is effectively a shortcut allowing observer to find out result of the #### `filecoin/submit` -The task MUST be invoked by the Storefront which MAY be used to verify offered content piece before propagating it through the pipeline. +The task MUST be invoked by the Storefront which MAY be used to verify the offered content piece before propagating it through the pipeline. > `did:web:web3.storage` invokes capability from `did:web:web3.storage` ```json @@ -384,7 +384,7 @@ The task MUST be invoked by the Storefront which MAY be used to verify offered c } ``` -Storefront MUST issue signed receipt that either succeeds and links to the `aggregate/offer` task via `fx.join` [effect] or fails with specified reason (e.g. `content` does not corresponds to the provided `piece`). +A Storefront MUST issue a signed receipt that either succeeds and links to the `piece/offer` task via an `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). ```json { @@ -396,7 +396,7 @@ Storefront MUST issue signed receipt that either succeeds and links to the `aggr } }, "fx": { - "join": { "/": "bafy...aggregateOffer" } + "join": { "/": "bafy...pieceOffer" } }, "meta": {}, "iss": "did:web:web3.storage", @@ -404,8 +404,8 @@ Storefront MUST issue signed receipt that either succeeds and links to the `aggr } ``` -See [`aggregate/offer`](#aggregateoffer) section to see the subsequent task. -If the added piece is invalid, details on failing reason is also reported: +See the [`piece/offer`](#pieceoffer)section to see the subsequent task. +If the added piece is invalid, the reason for the failure is also reported: ```json { @@ -427,9 +427,9 @@ If the added piece is invalid, details on failing reason is also reported: ### Aggregator Capabilities -#### `aggregate/offer` +#### `piece/offer` -A Storefront can invoke a capability to offer a piece to be aggregated for upcoming Filecoin deal(s). See [schema](#aggregateoffer-schema). +A Storefront can invoke a capability to offer a piece to be aggregated for upcoming Filecoin deal(s). See [schema](#pieceoffer-schema). > `did:web:web3.storage` invokes capability from `did:web:aggregator.web3.storage` @@ -440,7 +440,7 @@ A Storefront can invoke a capability to offer a piece to be aggregated for upcom "att": [ { "with": "did:web:web3.storage", - "can": "aggregate/offer", + "can": "piece/offer", "nb": { /* commitment proof for piece */ "piece": { "/": "bafk...commp" }, @@ -454,11 +454,11 @@ A Storefront can invoke a capability to offer a piece to be aggregated for upcom } ``` -An _Aggregator_ MUST issue a signed receipt to acknowledge the received request. Receipt MUST contain `fx.join` [effect] with a `aggregate/accept` task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. +An _Aggregator_ MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] with an `piece/accept` task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. ```json { - "ran": "bafy...aggregateOffer", + "ran": "bafy...pieceOffer", "out": { "ok": { /* commitment proof for piece */ @@ -466,7 +466,7 @@ An _Aggregator_ MUST issue a signed receipt to acknowledge the received request. } }, "fx": { - "join": { "/": "bafy...aggregateAccept" } + "join": { "/": "bafy...pieceAccept" } }, "meta": {}, "iss": "did:web:aggregator.web3.storage", @@ -474,17 +474,17 @@ An _Aggregator_ MUST issue a signed receipt to acknowledge the received request. } ``` -See [`aggregate/accept`](#aggregateaccept) section to see the subsequent task. +See the [`piece/accept`](#pieceaccept) section for the subsequent task. -#### `aggregate/accept` +#### `piece/accept` -An _Aggregator_ MUST issue receipt for `aggregate/accept` task for the offered piece that was included into an aggregate. Receipt MUST either contain [`InclusionProof`] in a result and `fx.join` [effect] linking to `deal/offer` task, or an error detailing the reason. +An _Aggregator_ MUST issue a receipt for the `piece/accept` task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and `fx.join` [effect] linking to `aggregate/offer` task, or an error detailing the reason. -> It is RECOMMENDED to not fail `aggregate/accept` as piece inclusion is deterministic computation occurring on validated data +> It is RECOMMENDED to never fail `piece/accept` as piece inclusion is a deterministic computation occurring on validated data. ```json { - "ran": "bafy...aggregateAccept", + "ran": "bafy...pieceAccept", "out": { "ok": { /* commitment proof for piece */ @@ -512,9 +512,9 @@ An _Aggregator_ MUST issue receipt for `aggregate/accept` task for the offered p ### Dealer Capabilities -#### `deal/offer` +#### `aggregate/offer` -An _Aggregator_ can offer an aggregate for Filecoin deal inclusion by invoking a `deal/offer` capability. See [schema](#dealoffer-schema). +An _Aggregator_ can offer an aggregate for Filecoin deal inclusion by invoking a `aggregate/offer` capability. See [schema](#aggregateoffer-schema). > `did:web:aggregator.web3.storage` invokes capability from `did:web:dealer.web3.storage` @@ -524,7 +524,7 @@ An _Aggregator_ can offer an aggregate for Filecoin deal inclusion by invoking a "aud": "did:web:dealer.web3.storage", "att": [ { - "can": "deal/offer", + "can": "aggregate/offer", /* storefront responsible for invocation */ "with": "did:web:web3.storage", "nb": { @@ -540,11 +540,11 @@ An _Aggregator_ can offer an aggregate for Filecoin deal inclusion by invoking a } ``` -Invoking the `deal/offer` capability is a request to arrange Filecoin deals for the aggregate. +Invoking the `aggregate/offer` capability is a request to arrange Filecoin deals for the aggregate. -The `nb.aggregate` field represents commitment proof for the `aggregate` to arrange a deal(s) for. +The `nb.aggregate` field represents a commitment proof for the `aggregate` to arrange a deal(s) for. -The `nb.pieces` field represents a link to DAG-CBOR encoded list of pieces of an `aggregate`. The elements of the `nb.pieces` MUST be sorted in the exact same order as they were used to compute the aggregate piece CID. This block MUST be included with the invocation. Its format is: +The `nb.pieces` field represents a link to DAG-CBOR encoded list of pieces of an `aggregate`. The elements of the `nb.pieces` field MUST be sorted in the _same_ order as they were used to compute the aggregate piece CID. This block MUST be included with the invocation. Its format is: ```json /* offers block as an array of piece CIDs, encoded as DAG-JSON (for readability) */ @@ -557,11 +557,11 @@ The `nb.pieces` field represents a link to DAG-CBOR encoded list of pieces of an Each entry of the decoded offers block has all the necessary information for a Storage Provider to fetch and store a CAR file. -The Dealer MUST issue a signed receipt to acknowledge request. Issued receipt MUST have `fx.join` [effect] linking to the `deal/accept` task which MUST succeed with [`DataAggregationProof`] after deals are live on Filecoin chain or fail (with an `error` describing a problem with the `aggregate`). +The Dealer MUST issue a signed receipt to acknowledge the request. The issued receipt MUST have an `fx.join` [effect] linking to the `deal/accept` task which MUST succeed with the [`DataAggregationProof`] after deals are live on the Filecoin chain or fail (with an `error` describing the problem with the `aggregate`). ```json { - "ran": "bafy...dealOffer", + "ran": "bafy...aggregateOffer", "out": { "ok": { /* commitment proof for aggregate */ @@ -569,7 +569,7 @@ The Dealer MUST issue a signed receipt to acknowledge request. Issued receipt MU } }, "fx": { - "join": { "/": "bafy...dealAccept" } + "join": { "/": "bafy...aggregateAccept" } }, "meta": {}, "iss": "did:web:dealer.web3.storage", @@ -577,15 +577,15 @@ The Dealer MUST issue a signed receipt to acknowledge request. Issued receipt MU } ``` -See [`deal/accept`](#dealaccept) section to see the subsequent task. +See the [`aggregate/accept`](#aggregateaccept) section for the subsequent task. -### `deal/accept` +### `aggregate/accept` -The _Dealer_ MUST issue receipt for `deal/accept` task once it arranges deals with Storage Providers and they are live on Filecoin chain. Receipt MUST either succeed with [`DataAggregationProof`] or fail (with an `error` describing a problem with the `aggregate`). +The _Dealer_ MUST issue a receipt for the `aggregate/accept` task once it arranges deals with Storage Providers and they are live on the Filecoin chain. The receipt MUST either succeed with the [`DataAggregationProof`] or fail (with an `error` describing the problem with the `aggregate`). ```json { - "ran": "bafy...dealAccept", + "ran": "bafy...aggregateAccept", "out": { "ok": { "inclusion": { @@ -616,13 +616,13 @@ The _Dealer_ MUST issue receipt for `deal/accept` task once it arranges deals wi } ``` -If deal fails due to invalid piece issued receipt MUST have contain `fx.fork` [effect]s that to retry valid pieces. +If a deal fails due to an invalid piece, the issued receipt MUST contain `fx.fork` [effect]s that retry valid pieces. -> ℹ️ This allows observer to follow new execution chain even if original piece inclusion failed. +> ℹ️ This allows an observer to follow the new execution chain even if the original piece inclusion failed. ```json { - "ran": "bafy...dealAccept", + "ran": "bafy...aggregateAccept", "out": { "error": { "name": "InvalidPiece", @@ -655,7 +655,7 @@ If deal fails due to invalid piece issued receipt MUST have contain `fx.fork` [e #### `deal/info` -A _Storefront_ and _Aggregator_ MAY invoke `deal/info` capability to request a current state of the aggregate. +A _Storefront_ and an _Aggregator_ MAY invoke a `deal/info` capability to request the current state of the aggregate. > `did:web:web3.storage` invokes capability from `did:web:tracker.web3.storage` @@ -679,9 +679,9 @@ A _Storefront_ and _Aggregator_ MAY invoke `deal/info` capability to request a c } ``` -> ⚠️ Invoker SHOULD utilize nonce on subsequent calls to avoid receiving response for the prior invocation. +> ⚠️ The invoker SHOULD utilize a nonce on subsequent calls to avoid receiving a response for the prior invocation. -_Deal Tracker_ MUST succeed invocation and return deal information for the aggregate if it is on chain. +The invocation to the _Deal Tracker_ MUST succeed and return deal information for the aggregate if it is on chain. ```json { @@ -712,7 +712,7 @@ _Deal Tracker_ MUST succeed invocation and return deal information for the aggre } ``` -_Deal Tracker_ MUST fail invocation if deal information for the aggregate is not on chain. +The invocation to the _Deal Tracker_ MUST fail if the deal information for the aggregate is _not_ on chain. ```json { @@ -740,11 +740,12 @@ _Deal Tracker_ MUST fail invocation if deal information for the aggregate is not type FilecoinCapability union { | FilecoinOffer "filecoin/offer" | FilecoinAccept "filecoin/accept" + | FilecoinSubmit "filecoin/submit" } representation inline { discriminantKey "can" } -type PieceCapability union { +type AggregatorCapability union { | PieceOffer "piece/offer" | PieceSubmit "piece/submit" | PieceAccept "piece/accept" @@ -752,15 +753,15 @@ type PieceCapability union { discriminantKey "can" } -type AggregateCapability union { +type DealerCapability union { | AggregateOffer "aggregate/offer" | AggregateAccept "aggregate/accept" } representation inline { discriminantKey "can" } -type DealCapability enum { - DealOffer "deal/info", +type DealCapability union { + | DealInfo "deal/info", } representation inline { discriminantKey "can" } From 3684bc856b450d3e4bc647c8c044818dc87a10c4 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 08:52:59 -0700 Subject: [PATCH 04/17] Apply suggestions from code review Co-authored-by: Vasco Santos --- w3-filecoin.md | 1 + 1 file changed, 1 insertion(+) diff --git a/w3-filecoin.md b/w3-filecoin.md index e29be51..a6c6c6c 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -741,6 +741,7 @@ type FilecoinCapability union { | FilecoinOffer "filecoin/offer" | FilecoinAccept "filecoin/accept" | FilecoinSubmit "filecoin/submit" + | FilecoinSubmit "filecoin/submit" } representation inline { discriminantKey "can" } From 0f9ad978e943aec2a8b4d9f6ed0f83209c304878 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 09:17:40 -0700 Subject: [PATCH 05/17] Turn common terms into links --- w3-filecoin.md | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index a6c6c6c..bbeaed9 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -24,26 +24,26 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S - [Terminology](#terminology) - [Roles](#roles) - - [Storefront](#storefront) - - [Aggregator](#aggregator) - - [Dealer](#dealer) - - [Deal Tracker](#deal-tracker) + - [Storefront] + - [Aggregator] + - [Dealer] + - [Deal Tracker] - [Protocol](#protocol) - [Overview](#overview) - [Authorization](#authorization) - [Capabilities](#capabilities) - [Storefront Capabilities](#storefront-capabilities) - - [`filecoin/offer`](#filecoinoffer) - - [`filecoin/submit`](#filecoinsubmit) - - [`filecoin/accept`](#filecoinaccept) + - [`filecoin/offer`] + - [`filecoin/submit`] + - [`filecoin/accept`] - [Aggregator Capabilities](#aggregator-capabilities) - - [`piece/offer`](#aggregateoffer) - - [`piece/accept`](#aggregateaccept) + - [`piece/offer`] + - [`piece/accept`] - [Dealer Capabilities](#storefront-capabilities) - - [`aggregate/offer`](#aggregateoffer) - - [`aggregate/accept`](#aggregateaccept) + - [`aggregate/offer`] + - [`aggregate/accept`] - [Deal Tracker Capabilities](#deal-tracker-capabilities) - - [`deal/info`](#dealinfo) + - [`deal/info`] - [Schema](#schema) - [Base types](#base-types) - [`filecoin/offer` schema](#filecoinoffer-schema) @@ -912,3 +912,16 @@ type DealInfoDetail struct { [effect]:https://github.com/ucan-wg/invocation/#7-effect [`DataAggregationProof`]:https://github.com/filecoin-project/go-data-segment/blob/e3257b64fa2c84e0df95df35de409cfed7a38438/datasegment/verifier.go#L8-L14 [`InclusionProof`]:https://github.com/filecoin-project/go-data-segment/blob/e3257b64fa2c84e0df95df35de409cfed7a38438/datasegment/inclusion.go#L30-L39 +[Storefront]:#storefront +[Aggregator]:#aggregator +[Dealer]:#dealer +[Deal Tracker]:#deal-tracker + +[`filecoin/offer`]:#filecoinoffer +[`filecoin/submit`]:#filecoinsubmit +[`filecoin/accept`]:#filecoinaccept +[`piece/offer`]:#aggregateoffer +[`piece/accept`]:#aggregateaccept +[`aggregate/offer`]:#aggregateoffer +[`aggregate/accept`]:#aggregateaccept +[`deal/info`]:#dealinfo From 5444fbc4ec7cfebb09b083cc5914ec2753f268d9 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 09:23:27 -0700 Subject: [PATCH 06/17] turn actor references to anchor links --- w3-filecoin.md | 86 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index bbeaed9..4e2bee7 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -63,27 +63,27 @@ There are several roles in the authorization flow: | Name | Description | | ------------ | ------------------------------------------------------------------------------------------------- | -| Storefront | [Principal] identified by a DID, representing a storage API like web3.storage. | -| Aggregator | [Principal] identified by a DID, representing a storage aggregator like w3filecoin. | -| Dealer | [Principal] identified by a DID, that arranges filecoin deals with storage providers. e.g. Spade. | -| Deal Tracker | [Principal] identified by a DID, that tracks deals made by the Dealer. | +| [Storefront] | [Principal] identified by a DID, representing a storage API like web3.storage. | +| [Aggregator] | [Principal] identified by a DID, representing a storage aggregator like w3filecoin. | +| [Dealer] | [Principal] identified by a DID, that arranges filecoin deals with storage providers. e.g. Spade. | +| [Deal Tracker] | [Principal] identified by a DID, that tracks deals made by the [Dealer]. | ### Storefront A _Storefront_ is a type of [principal] identified by a DID (typically a [`did:web`] identifier). -A Storefront facilitates data storage services to applications and users, getting the requested data stored into Filecoin deals asynchronously. +A _Storefront_ facilitates data storage services to applications and users, getting the requested data stored into Filecoin deals asynchronously. ### Aggregator An _Aggregator_ is a type of [principal] identified by a DID. It is RECOMMENDED to use use [`did:key`] identifier due to their stateless nature. -An Aggregator facilitates data storage into Filecoin deals by aggregating smaller data (Filecoin Pieces) into a larger piece that can effectively be stored with a Filecoin Storage Provider using [Verifiable Data Aggregation +An _Aggregator_ facilitates data storage into Filecoin deals by aggregating smaller data (Filecoin Pieces) into a larger piece that can effectively be stored with a Filecoin Storage Provider using [Verifiable Data Aggregation ](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md). ### Dealer -A _Dealer_ is a type of [principal] identified by a DID (typically a `did:key` identifier) that arranges deals for the aggregates submitted by _Storefront_. +A _Dealer_ is a type of [principal] identified by a DID (typically a `did:key` identifier) that arranges deals for the aggregates submitted by [Storefront]. ### Deal Tracker @@ -93,19 +93,19 @@ A _Deal Tracker_ is a type of [principal] identified by a DID (typically a `did: ## Overview -A Storefront is a service that ensures content addressed user/application data is stored perpetually on the decentralized web. A Storefront ingests user/application data and replicates it across various storage systems, including Filecoin Storage Providers. Content supplied to a Storefront can be of arbitrary size, while (Filecoin) Storage Providers demand large (>= 16GiB) content pieces. To align supply and demand requirements, the Aggregator accumulates supplied content pieces into a larger verifiable aggregate pieces per [FRC-0058](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md) that can be stored by Storage Providers. +A [Storefront] is a service that ensures content addressed user/application data is stored perpetually on the decentralized web. A [Storefront] ingests user/application data and replicates it across various storage systems, including Filecoin Storage Providers. Content supplied to a [Storefront] can be of arbitrary size, while (Filecoin) Storage Providers demand large (>= 16GiB) content pieces. To align supply and demand requirements, the [Aggregator] accumulates supplied content pieces into a larger verifiable aggregate pieces per [FRC-0058](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md) that can be stored by Storage Providers. ### Authorization -Storefronts MUST use UCAN based authorization mechanisms to interact with Aggregators, Dealers and Deal Trackers. The way in which Storefronts are registered to use Aggregators, Dealers and Deal Trackers is out of scope of this specification. +[Storefront]s MUST use UCAN based authorization mechanisms to interact with [Aggregator]s, [Dealer]s and [Deal Tracker]s. The way in which [Storefront]s are registered to use [Aggregator]s, [Dealer]s and [Deal Tracker]s is out of scope of this specification. -For example, an Aggregator can authorize invocations from `did:web:web3.storage` by validating the signature is from the DID. This way, it allows web3.storage to rotate keys and/or re-delegate access without having to coordinate with the Aggregator. +For example, an [Aggregator] can authorize invocations from `did:web:web3.storage` by validating the signature is from the DID. This way, it allows web3.storage to rotate keys and/or re-delegate access without having to coordinate with the [Aggregator]. ### Storefront receives a Filecoin piece -A Storefront MUST submit content for aggregation by it's piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the Storefront itself. A Storefront MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a Storefront client or delegated to a hired third party, ether way a Storefront MUST acknowledge request by issuing a signed receipt. A Storefront MAY decide to verify submitted piece prior to aggregation. A Storefront MAY also operate trusted actor that computes and submits pieces on content upload. +A [Storefront] MUST submit content for aggregation by it's piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the [Storefront] itself. A [Storefront] MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a [Storefront] client or delegated to a hired third party, ether way a [Storefront] MUST acknowledge request by issuing a signed receipt. A [Storefront] MAY decide to verify submitted piece prior to aggregation. A [Storefront] MAY also operate trusted actor that computes and submits pieces on content upload. -Once a Storefront receives the offer for a piece, it is pending for verification. The Storefront MUST issue a receipt proving that request state has transition from `uninitialized` to `pending` if result was `ok`, or to `failed` if result was `error`. The Storefront MAY fail invocation if piece `content` has not been provided. +Once a [Storefront] receives the offer for a piece, it is pending for verification. The [Storefront] MUST issue a receipt proving that request state has transition from `uninitialized` to `pending` if result was `ok`, or to `failed` if result was `error`. The [Storefront] MAY fail invocation if piece `content` has not been provided. #### `filecoin/accept` effect @@ -115,7 +115,7 @@ A successful invocation receipt MUST have `fx.join` [effect] that links to the t Successful invocation receipt MUST have an `fx.fork` [effect] that links to the next task of the workflow. It allows the observer to follow progress of the execution. -The Storefront MUST issue a receipt for the linked `filecoin/submit` task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a `piece/offer` task that forwards the submitted piece to the _Aggregator_. +The [Storefront] MUST issue a receipt for the linked `filecoin/submit` task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a `piece/offer` task that forwards the submitted piece to the [Aggregator]. ```mermaid sequenceDiagram @@ -150,17 +150,17 @@ sequenceDiagram ### Storefront offers a piece to aggregate -A Storefront SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an Aggregator. +A [Storefront] SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an [Aggregator]. -The Aggregator MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have an `fx.join` [effect] that links to a `piece/accept` task, which either succeeds with an (aggregate) inclusion proof or fails. +The [Aggregator] MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have an `fx.join` [effect] that links to a `piece/accept` task, which either succeeds with an (aggregate) inclusion proof or fails. -If the Storefront offers a piece multiple times, the Aggregator MUST respond with a receipt that contains the _same_ result and effect(s). +If the [Storefront] offers a piece multiple times, the [Aggregator] MUST respond with a receipt that contains the _same_ result and effect(s). > ℹ️ An invocation nonce MAY be used to force a piece to be included in another aggregate. -The same Piece submitted by different Storefronts SHOULD NOT be considered a duplicate. +The same Piece submitted by different [Storefront]s SHOULD NOT be considered a duplicate. -After an Aggregator includes a piece in an aggregate it MUST issue a `piece/accept` receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an `aggregate/offer` task for the aggregate where piece was included. +After an [Aggregator] includes a piece in an aggregate it MUST issue a `piece/accept` receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an `aggregate/offer` task for the aggregate where piece was included. ```mermaid sequenceDiagram @@ -182,18 +182,18 @@ sequenceDiagram ### Aggregator offers dealer an aggregate -When the Aggregator has enough content pieces to build a qualified aggregate (dealers MAY impose different requirements), it MUST offer an aggregate to the Dealer. The Dealer MUST issue a signed receipt acknowledging an offer, and then deal negotiation with Filecoin Storage Providers MAY be carried out of band. +When the [Aggregator] has enough content pieces to build a qualified aggregate ([Dealer]s MAY impose different requirements), it MUST offer an aggregate to the [Dealer]. The [Dealer] MUST issue a signed receipt acknowledging an offer, and then deal negotiation with Filecoin Storage Providers MAY be carried out of band. -If a Dealer receives a request with an aggregate multiple times it MUST (re)issue a receipt with the _same_ result and effects. +If a [Dealer] receives a request with an aggregate multiple times it MUST (re)issue a receipt with the _same_ result and effects. > ℹ️ An invocation nonce MAY be used to force an aggregate to be reprocessed. The issued receipt MUST have an `fx.join` [effect] linking to an `aggregate/accept` task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if a Storage Provider failed to replicate and reported an error). -The Dealer MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the `aggregate/accept` task with a succeed or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. +The [Dealer] MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the `aggregate/accept` task with a succeed or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. A failed task MUST provide an error reason. When pieces of the aggregate can be retried, the issued receipt MUST contain `fx.fork` [effect]s with `piece/offer` tasks per piece. -> Note: The Dealer MAY have several intermediate steps and states it transitions through, however those are _not_ captured by this protocol intentionally, because the other actor take no action until a success / failure condition is met. +> Note: The [Dealer] MAY have several intermediate steps and states it transitions through, however those are _not_ captured by this protocol intentionally, because the other actor take no action until a success / failure condition is met. ```mermaid sequenceDiagram @@ -213,9 +213,9 @@ sequenceDiagram ### _Deal Tracker_ can be queried for the aggregate status -Storefront users MAY want to check status of the deals for their content. Deals change over time as they get renewed. Therefore, the Storefront MAY invoke `deal/info` capability to gather information about an aggregate. The Storefront SHOULD be able to look up an aggregate from received inclusion proofs and use them to look up deal status information. +[Storefront] users MAY want to check status of the deals for their content. Deals change over time as they get renewed. Therefore, the [Storefront] MAY invoke `deal/info` capability to gather information about an aggregate. The [Storefront] SHOULD be able to look up an aggregate from received inclusion proofs and use them to look up deal status information. -The Dealer MAY also use a _Deal Tracker_ to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue `aggregate/accept` receipts when they do. +The [Dealer] MAY also use a [Deal Tracker] to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue `aggregate/accept` receipts when they do. ```mermaid sequenceDiagram @@ -233,7 +233,7 @@ sequenceDiagram This section describes the set of capabilities that form the w3 filecoin protocol, along with the details relevant for invoking them with a service provider. -In this document, we will be exposing capabilities implemented by Storefront `web3.storage`, Aggregator `aggregator.web3.storage`, Dealer `dealer.web3.storage` and Deal Tracker `tracker.web3.storage`. +In this document, we will be exposing capabilities implemented by [Storefront] `web3.storage`, [Aggregator] `aggregator.web3.storage`, [Dealer] `dealer.web3.storage` and [Deal Tracker] `tracker.web3.storage`. ### Storefront Capabilities @@ -264,7 +264,7 @@ An agent MAY invoke the `filecoin/offer` capability to request storing a content } ``` -The Storefront MAY fail the invocation if the linked `content` has not yet been stored in the given space. +The [Storefront] MAY fail the invocation if the linked `content` has not yet been stored in the given space. ```json { @@ -278,17 +278,17 @@ The Storefront MAY fail the invocation if the linked `content` has not yet been } ``` -Alternatively, the Storefront MAY choose to queue request until linked `content` has been uploaded. +Alternatively, the [Storefront] MAY choose to queue request until linked `content` has been uploaded. -Storefront MUST issue a signed receipt for a successful invocation acknowledging the request (regardless if it already has a `content` or if it chose to wait for an upload). +[Storefront] MUST issue a signed receipt for a successful invocation acknowledging the request (regardless if it already has a `content` or if it chose to wait for an upload). #### Effects -The issued receipt MUST have an `fx.join` [effect] that links to the `filecoin/accept` task. The Storefront MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. +The issued receipt MUST have an `fx.join` [effect] that links to the `filecoin/accept` task. The [Storefront] MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. > This allows an agent to get a result without having to follow progress across the entire invocation chain. -The issued receipt MUST have an `fx.fork` [effect] that links to the `filecoin/submit` task. The Storefront MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). +The issued receipt MUST have an `fx.fork` [effect] that links to the `filecoin/submit` task. The [Storefront] MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). > This allows an agent to follow progress across the entire invocation chain. @@ -311,7 +311,7 @@ The issued receipt MUST have an `fx.fork` [effect] that links to the `filecoin/s #### `filecoin/accept` -This task is effectively a shortcut allowing an observer to find out the result of the `filecoin/offer` task chain without having to follow each step. The _Storefront_ MUST issue a signed receipt with an [`DataAggregationProof`] result or an error. +This task is effectively a shortcut allowing an observer to find out the result of the `filecoin/offer` task chain without having to follow each step. The [Storefront] MUST issue a signed receipt with an [`DataAggregationProof`] result or an error. ##### Filecoin Accept Failure @@ -360,7 +360,7 @@ This task is effectively a shortcut allowing an observer to find out the result #### `filecoin/submit` -The task MUST be invoked by the Storefront which MAY be used to verify the offered content piece before propagating it through the pipeline. +The task MUST be invoked by the [Storefront] which MAY be used to verify the offered content piece before propagating it through the pipeline. > `did:web:web3.storage` invokes capability from `did:web:web3.storage` ```json @@ -384,7 +384,7 @@ The task MUST be invoked by the Storefront which MAY be used to verify the offer } ``` -A Storefront MUST issue a signed receipt that either succeeds and links to the `piece/offer` task via an `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). +A [Storefront] MUST issue a signed receipt that either succeeds and links to the `piece/offer` task via an `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). ```json { @@ -429,7 +429,7 @@ If the added piece is invalid, the reason for the failure is also reported: #### `piece/offer` -A Storefront can invoke a capability to offer a piece to be aggregated for upcoming Filecoin deal(s). See [schema](#pieceoffer-schema). +A [Storefront] can invoke a capability to offer a piece to be aggregated for upcoming Filecoin deal(s). See [schema](#pieceoffer-schema). > `did:web:web3.storage` invokes capability from `did:web:aggregator.web3.storage` @@ -454,7 +454,7 @@ A Storefront can invoke a capability to offer a piece to be aggregated for upcom } ``` -An _Aggregator_ MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] with an `piece/accept` task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. +An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] with an `piece/accept` task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. ```json { @@ -478,7 +478,7 @@ See the [`piece/accept`](#pieceaccept) section for the subsequent task. #### `piece/accept` -An _Aggregator_ MUST issue a receipt for the `piece/accept` task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and `fx.join` [effect] linking to `aggregate/offer` task, or an error detailing the reason. +An [Aggregator] MUST issue a receipt for the `piece/accept` task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and `fx.join` [effect] linking to `aggregate/offer` task, or an error detailing the reason. > It is RECOMMENDED to never fail `piece/accept` as piece inclusion is a deterministic computation occurring on validated data. @@ -514,7 +514,7 @@ An _Aggregator_ MUST issue a receipt for the `piece/accept` task for the offered #### `aggregate/offer` -An _Aggregator_ can offer an aggregate for Filecoin deal inclusion by invoking a `aggregate/offer` capability. See [schema](#aggregateoffer-schema). +An [Aggregator] can offer an aggregate for Filecoin deal inclusion by invoking a `aggregate/offer` capability. See [schema](#aggregateoffer-schema). > `did:web:aggregator.web3.storage` invokes capability from `did:web:dealer.web3.storage` @@ -557,7 +557,7 @@ The `nb.pieces` field represents a link to DAG-CBOR encoded list of pieces of an Each entry of the decoded offers block has all the necessary information for a Storage Provider to fetch and store a CAR file. -The Dealer MUST issue a signed receipt to acknowledge the request. The issued receipt MUST have an `fx.join` [effect] linking to the `deal/accept` task which MUST succeed with the [`DataAggregationProof`] after deals are live on the Filecoin chain or fail (with an `error` describing the problem with the `aggregate`). +The [Dealer] MUST issue a signed receipt to acknowledge the request. The issued receipt MUST have an `fx.join` [effect] linking to the `deal/accept` task which MUST succeed with the [`DataAggregationProof`] after deals are live on the Filecoin chain or fail (with an `error` describing the problem with the `aggregate`). ```json { @@ -581,7 +581,7 @@ See the [`aggregate/accept`](#aggregateaccept) section for the subsequent task. ### `aggregate/accept` -The _Dealer_ MUST issue a receipt for the `aggregate/accept` task once it arranges deals with Storage Providers and they are live on the Filecoin chain. The receipt MUST either succeed with the [`DataAggregationProof`] or fail (with an `error` describing the problem with the `aggregate`). +The [Dealer] MUST issue a receipt for the `aggregate/accept` task once it arranges deals with Storage Providers and they are live on the Filecoin chain. The receipt MUST either succeed with the [`DataAggregationProof`] or fail (with an `error` describing the problem with the `aggregate`). ```json { @@ -651,11 +651,11 @@ If a deal fails due to an invalid piece, the issued receipt MUST contain `fx.for } ``` -### Deal Tracker Capabilities +### _Deal Tracker_ Capabilities #### `deal/info` -A _Storefront_ and an _Aggregator_ MAY invoke a `deal/info` capability to request the current state of the aggregate. +A [Storefront] and an [Aggregator] MAY invoke a `deal/info` capability to request the current state of the aggregate. > `did:web:web3.storage` invokes capability from `did:web:tracker.web3.storage` @@ -681,7 +681,7 @@ A _Storefront_ and an _Aggregator_ MAY invoke a `deal/info` capability to reques > ⚠️ The invoker SHOULD utilize a nonce on subsequent calls to avoid receiving a response for the prior invocation. -The invocation to the _Deal Tracker_ MUST succeed and return deal information for the aggregate if it is on chain. +The invocation to the [Deal Tracker] MUST succeed and return deal information for the aggregate if it is on chain. ```json { @@ -712,7 +712,7 @@ The invocation to the _Deal Tracker_ MUST succeed and return deal information fo } ``` -The invocation to the _Deal Tracker_ MUST fail if the deal information for the aggregate is _not_ on chain. +The invocation to the [Deal Tracker] MUST fail if the deal information for the aggregate is _not_ on chain. ```json { From ffb3d9731cd2355bf4fbd54eaf39f7f3f5a8ce73 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 09:30:45 -0700 Subject: [PATCH 07/17] turn capability references to links --- w3-filecoin.md | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index 4e2bee7..b9485fc 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -101,7 +101,7 @@ A [Storefront] is a service that ensures content addressed user/application data For example, an [Aggregator] can authorize invocations from `did:web:web3.storage` by validating the signature is from the DID. This way, it allows web3.storage to rotate keys and/or re-delegate access without having to coordinate with the [Aggregator]. -### Storefront receives a Filecoin piece +### _Storefront_ receives a Filecoin piece A [Storefront] MUST submit content for aggregation by it's piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the [Storefront] itself. A [Storefront] MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a [Storefront] client or delegated to a hired third party, ether way a [Storefront] MUST acknowledge request by issuing a signed receipt. A [Storefront] MAY decide to verify submitted piece prior to aggregation. A [Storefront] MAY also operate trusted actor that computes and submits pieces on content upload. @@ -115,7 +115,7 @@ A successful invocation receipt MUST have `fx.join` [effect] that links to the t Successful invocation receipt MUST have an `fx.fork` [effect] that links to the next task of the workflow. It allows the observer to follow progress of the execution. -The [Storefront] MUST issue a receipt for the linked `filecoin/submit` task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a `piece/offer` task that forwards the submitted piece to the [Aggregator]. +The [Storefront] MUST issue a receipt for the linked [`filecoin/submit`] task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a [`piece/offer`] task that forwards the submitted piece to the [Aggregator]. ```mermaid sequenceDiagram @@ -148,11 +148,11 @@ sequenceDiagram ``` -### Storefront offers a piece to aggregate +### _Storefront_ offers a piece to aggregate A [Storefront] SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an [Aggregator]. -The [Aggregator] MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have an `fx.join` [effect] that links to a `piece/accept` task, which either succeeds with an (aggregate) inclusion proof or fails. +The [Aggregator] MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have an `fx.join` [effect] that links to a [`piece/accept`] task, which either succeeds with an (aggregate) inclusion proof or fails. If the [Storefront] offers a piece multiple times, the [Aggregator] MUST respond with a receipt that contains the _same_ result and effect(s). @@ -160,7 +160,7 @@ If the [Storefront] offers a piece multiple times, the [Aggregator] MUST respond The same Piece submitted by different [Storefront]s SHOULD NOT be considered a duplicate. -After an [Aggregator] includes a piece in an aggregate it MUST issue a `piece/accept` receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an `aggregate/offer` task for the aggregate where piece was included. +After an [Aggregator] includes a piece in an aggregate it MUST issue a [`piece/accept`] receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an [`aggregate/offer`] task for the aggregate where piece was included. ```mermaid sequenceDiagram @@ -180,7 +180,7 @@ sequenceDiagram deactivate Aggregator ``` -### Aggregator offers dealer an aggregate +### _Aggregator_ offers dealer an aggregate When the [Aggregator] has enough content pieces to build a qualified aggregate ([Dealer]s MAY impose different requirements), it MUST offer an aggregate to the [Dealer]. The [Dealer] MUST issue a signed receipt acknowledging an offer, and then deal negotiation with Filecoin Storage Providers MAY be carried out of band. @@ -188,10 +188,10 @@ If a [Dealer] receives a request with an aggregate multiple times it MUST (re)is > ℹ️ An invocation nonce MAY be used to force an aggregate to be reprocessed. -The issued receipt MUST have an `fx.join` [effect] linking to an `aggregate/accept` task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if a Storage Provider failed to replicate and reported an error). +The issued receipt MUST have an `fx.join` [effect] linking to an [`aggregate/accept`] task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if a Storage Provider failed to replicate and reported an error). -The [Dealer] MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the `aggregate/accept` task with a succeed or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. -A failed task MUST provide an error reason. When pieces of the aggregate can be retried, the issued receipt MUST contain `fx.fork` [effect]s with `piece/offer` tasks per piece. +The [Dealer] MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the [`aggregate/accept`] task with a succeed or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. +A failed task MUST provide an error reason. When pieces of the aggregate can be retried, the issued receipt MUST contain `fx.fork` [effect]s with [`piece/offer`] tasks per piece. > Note: The [Dealer] MAY have several intermediate steps and states it transitions through, however those are _not_ captured by this protocol intentionally, because the other actor take no action until a success / failure condition is met. @@ -213,9 +213,9 @@ sequenceDiagram ### _Deal Tracker_ can be queried for the aggregate status -[Storefront] users MAY want to check status of the deals for their content. Deals change over time as they get renewed. Therefore, the [Storefront] MAY invoke `deal/info` capability to gather information about an aggregate. The [Storefront] SHOULD be able to look up an aggregate from received inclusion proofs and use them to look up deal status information. +[Storefront] users MAY want to check status of the deals for their content. Deals change over time as they get renewed. Therefore, the [Storefront] MAY invoke [`deal/info`] capability to gather information about an aggregate. The [Storefront] SHOULD be able to look up an aggregate from received inclusion proofs and use them to look up deal status information. -The [Dealer] MAY also use a [Deal Tracker] to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue `aggregate/accept` receipts when they do. +The [Dealer] MAY also use a [Deal Tracker] to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue [`aggregate/accept`] receipts when they do. ```mermaid sequenceDiagram @@ -235,11 +235,11 @@ This section describes the set of capabilities that form the w3 filecoin protoco In this document, we will be exposing capabilities implemented by [Storefront] `web3.storage`, [Aggregator] `aggregator.web3.storage`, [Dealer] `dealer.web3.storage` and [Deal Tracker] `tracker.web3.storage`. -### Storefront Capabilities +### _Storefront_ Capabilities #### `filecoin/offer` -An agent MAY invoke the `filecoin/offer` capability to request storing a content piece in Filecoin. See [schema](#filecoinqueue-schema). +An agent MAY invoke the `filecoin/offer` capability to request storing a content piece in Filecoin. See [schema](#filecoinoffer-schema). > `did:key:zAliceAgent` invokes `filecoin/offer` capability provided by `did:web:web3.storage` @@ -282,13 +282,13 @@ Alternatively, the [Storefront] MAY choose to queue request until linked `conten [Storefront] MUST issue a signed receipt for a successful invocation acknowledging the request (regardless if it already has a `content` or if it chose to wait for an upload). -#### Effects +##### Effects -The issued receipt MUST have an `fx.join` [effect] that links to the `filecoin/accept` task. The [Storefront] MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. +The issued receipt MUST have an `fx.join` [effect] that links to the [`filecoin/accept`] task. The [Storefront] MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. > This allows an agent to get a result without having to follow progress across the entire invocation chain. -The issued receipt MUST have an `fx.fork` [effect] that links to the `filecoin/submit` task. The [Storefront] MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). +The issued receipt MUST have an `fx.fork` [effect] that links to the [`filecoin/submit`] task. The [Storefront] MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). > This allows an agent to follow progress across the entire invocation chain. @@ -311,7 +311,7 @@ The issued receipt MUST have an `fx.fork` [effect] that links to the `filecoin/s #### `filecoin/accept` -This task is effectively a shortcut allowing an observer to find out the result of the `filecoin/offer` task chain without having to follow each step. The [Storefront] MUST issue a signed receipt with an [`DataAggregationProof`] result or an error. +This task is effectively a shortcut allowing an observer to find out the result of the [`filecoin/offer`] task chain without having to follow each step. The [Storefront] MUST issue a signed receipt with an [`DataAggregationProof`] result or an error. ##### Filecoin Accept Failure @@ -384,7 +384,7 @@ The task MUST be invoked by the [Storefront] which MAY be used to verify the off } ``` -A [Storefront] MUST issue a signed receipt that either succeeds and links to the `piece/offer` task via an `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). +A [Storefront] MUST issue a signed receipt that either succeeds and links to the [`piece/offer`] task via an `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). ```json { @@ -404,7 +404,7 @@ A [Storefront] MUST issue a signed receipt that either succeeds and links to the } ``` -See the [`piece/offer`](#pieceoffer)section to see the subsequent task. +See the [`piece/offer`] section to see the subsequent task. If the added piece is invalid, the reason for the failure is also reported: ```json @@ -425,7 +425,7 @@ If the added piece is invalid, the reason for the failure is also reported: } ``` -### Aggregator Capabilities +### _Aggregator_ Capabilities #### `piece/offer` @@ -454,7 +454,7 @@ A [Storefront] can invoke a capability to offer a piece to be aggregated for upc } ``` -An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] with an `piece/accept` task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. +An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] with an [`piece/accept`] task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. ```json { @@ -474,13 +474,13 @@ An [Aggregator] MUST issue a signed receipt to acknowledge the received request. } ``` -See the [`piece/accept`](#pieceaccept) section for the subsequent task. +See the [`piece/accept`] section for the subsequent task. #### `piece/accept` -An [Aggregator] MUST issue a receipt for the `piece/accept` task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and `fx.join` [effect] linking to `aggregate/offer` task, or an error detailing the reason. +An [Aggregator] MUST issue a receipt for the [`piece/accept`] task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and `fx.join` [effect] linking to [`aggregate/offer`] task, or an error detailing the reason. -> It is RECOMMENDED to never fail `piece/accept` as piece inclusion is a deterministic computation occurring on validated data. +> It is RECOMMENDED to never fail [`piece/accept`] as piece inclusion is a deterministic computation occurring on validated data. ```json { @@ -510,11 +510,11 @@ An [Aggregator] MUST issue a receipt for the `piece/accept` task for the offered } ``` -### Dealer Capabilities +### _Dealer_ Capabilities #### `aggregate/offer` -An [Aggregator] can offer an aggregate for Filecoin deal inclusion by invoking a `aggregate/offer` capability. See [schema](#aggregateoffer-schema). +An [Aggregator] can offer an aggregate for Filecoin deal inclusion by invoking a [`aggregate/offer`] capability. See [schema](#aggregateoffer-schema). > `did:web:aggregator.web3.storage` invokes capability from `did:web:dealer.web3.storage` @@ -540,7 +540,7 @@ An [Aggregator] can offer an aggregate for Filecoin deal inclusion by invoking a } ``` -Invoking the `aggregate/offer` capability is a request to arrange Filecoin deals for the aggregate. +Invoking the [`aggregate/offer`] capability is a request to arrange Filecoin deals for the aggregate. The `nb.aggregate` field represents a commitment proof for the `aggregate` to arrange a deal(s) for. @@ -581,7 +581,7 @@ See the [`aggregate/accept`](#aggregateaccept) section for the subsequent task. ### `aggregate/accept` -The [Dealer] MUST issue a receipt for the `aggregate/accept` task once it arranges deals with Storage Providers and they are live on the Filecoin chain. The receipt MUST either succeed with the [`DataAggregationProof`] or fail (with an `error` describing the problem with the `aggregate`). +The [Dealer] MUST issue a receipt for the [`aggregate/accept`] task once it arranges deals with Storage Providers and they are live on the Filecoin chain. The receipt MUST either succeed with the [`DataAggregationProof`] or fail (with an `error` describing the problem with the `aggregate`). ```json { @@ -655,7 +655,7 @@ If a deal fails due to an invalid piece, the issued receipt MUST contain `fx.for #### `deal/info` -A [Storefront] and an [Aggregator] MAY invoke a `deal/info` capability to request the current state of the aggregate. +A [Storefront] and an [Aggregator] MAY invoke a [`deal/info`] capability to request the current state of the aggregate. > `did:web:web3.storage` invokes capability from `did:web:tracker.web3.storage` @@ -920,8 +920,8 @@ type DealInfoDetail struct { [`filecoin/offer`]:#filecoinoffer [`filecoin/submit`]:#filecoinsubmit [`filecoin/accept`]:#filecoinaccept -[`piece/offer`]:#aggregateoffer -[`piece/accept`]:#aggregateaccept +[`piece/offer`]:#pieceoffer +[`piece/accept`]:#pieceaccept [`aggregate/offer`]:#aggregateoffer [`aggregate/accept`]:#aggregateaccept [`deal/info`]:#dealinfo From 4335f3b257dd9e468da5bb5d7779c0477684686b Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 09:33:21 -0700 Subject: [PATCH 08/17] fix inconsistencies in schema --- w3-filecoin.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index b9485fc..052edb4 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -739,22 +739,20 @@ The invocation to the [Deal Tracker] MUST fail if the deal information for the a ```ipldsch type FilecoinCapability union { | FilecoinOffer "filecoin/offer" - | FilecoinAccept "filecoin/accept" - | FilecoinSubmit "filecoin/submit" | FilecoinSubmit "filecoin/submit" + | FilecoinAccept "filecoin/accept" } representation inline { discriminantKey "can" } -type AggregatorCapability union { +type PieceCapability union { | PieceOffer "piece/offer" - | PieceSubmit "piece/submit" | PieceAccept "piece/accept" } representation inline { discriminantKey "can" } -type DealerCapability union { +type AggregateCapability union { | AggregateOffer "aggregate/offer" | AggregateAccept "aggregate/accept" } representation inline { From 4298eff35853ca377ad8661a57a2c2fc7d6052cd Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 09:55:26 -0700 Subject: [PATCH 09/17] use svg diagrams --- w3-filecoin.md | 77 +- w3-filecoin/aggregator.svg | 17 + w3-filecoin/deal-tracker.svg | 17 + w3-filecoin/dealer.svg | 17 + w3-filecoin/storefront.svg | 17 + w3-filecoin/workflow.tldr | 5791 ++++++++++++++++++++++++++++++++++ 6 files changed, 5863 insertions(+), 73 deletions(-) create mode 100644 w3-filecoin/aggregator.svg create mode 100644 w3-filecoin/deal-tracker.svg create mode 100644 w3-filecoin/dealer.svg create mode 100644 w3-filecoin/storefront.svg create mode 100644 w3-filecoin/workflow.tldr diff --git a/w3-filecoin.md b/w3-filecoin.md index 052edb4..a166d49 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -117,36 +117,7 @@ Successful invocation receipt MUST have an `fx.fork` [effect] that links to the The [Storefront] MUST issue a receipt for the linked [`filecoin/submit`] task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a [`piece/offer`] task that forwards the submitted piece to the [Aggregator]. -```mermaid -sequenceDiagram - participant Agent as
did:key:aAlice
- participant Storefront as
did:web:web3.storage
- participant Aggregator as
did:web:aggregator.web3.storage
- - - Agent->>Storefront: run: filecoin/offer
with:did:key:aSpace - Activate Storefront - Note left of Storefront: Request piece to be added to filecoin deal - - par - Storefront->>Storefront: fx.fork: filecoin/submit
with:did:web:web3.storage - - Storefront->>Aggregator: fx.join: piece/offer - Storefront-->>Agent: Receipt accepting offer - end - par - - Storefront->>Storefront: fx.join: filecoin/accept
with:did:web:web3.storage - - Storefront-->>Agent: Receipt with final result - end - - Storefront-->>Agent: Receipt acknowledging offer - deactivate Storefront - - - -``` +![storefront flow](./w3-filecoin/storefront.svg) ### _Storefront_ offers a piece to aggregate @@ -162,23 +133,7 @@ The same Piece submitted by different [Storefront]s SHOULD NOT be considered a d After an [Aggregator] includes a piece in an aggregate it MUST issue a [`piece/accept`] receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an [`aggregate/offer`] task for the aggregate where piece was included. -```mermaid -sequenceDiagram - participant Storefront as
did:web:web3.storage
- participant Aggregator as
did:web:aggregator.web3.storage
- participant Dealer as
did:web:dealer.web3.storage
- - Storefront->>Aggregator: run: piece/offer
with: did:web:web3.storage - activate Aggregator - Note left of Aggregator: Request piece to be included in aggregate - par - Aggregator->>Aggregator: invoke piece/accept
with: did:key:agg... - Aggregator->>Dealer: fx.join aggregate/offer - Aggregator-->>Storefront: Receipt with inclusion proof - end - Aggregator-->>Storefront: Receipt acknowledging offer - deactivate Aggregator -``` +![aggregator flow](./w3-filecoin/aggregator.svg) ### _Aggregator_ offers dealer an aggregate @@ -195,21 +150,7 @@ A failed task MUST provide an error reason. When pieces of the aggregate can be > Note: The [Dealer] MAY have several intermediate steps and states it transitions through, however those are _not_ captured by this protocol intentionally, because the other actor take no action until a success / failure condition is met. -```mermaid -sequenceDiagram - participant Aggregator as
did:web:aggregator.web3.storage
- participant Dealer as
did:web:dealer.web3.storage
- - Aggregator->>Dealer: run: aggregate/offer
with: did:key:agg... - activate Dealer - Note left of Dealer: Request to arrange deal for the aggregate - par - Dealer->>Dealer: run: aggregate/accept
with: did:key:brk... - Dealer-->>Aggregator: Receipt with DataAggregationProof or error - end - Dealer-->>Aggregator: Receipt akwnoledging offer - deactivate Dealer -``` +![dealer flow](./w3-filecoin/dealer.svg) ### _Deal Tracker_ can be queried for the aggregate status @@ -217,17 +158,7 @@ sequenceDiagram The [Dealer] MAY also use a [Deal Tracker] to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue [`aggregate/accept`] receipts when they do. -```mermaid -sequenceDiagram - participant Storefront as
did:web:web3.storage
- participant DealTracker as
did:web:tracker.web3.storage
- participant Dealer as
did:web:dealer.web3.storage
- - Storefront->>DealTracker: run: deal/info - Note left of DealTracker: Request information about an aggregate - Dealer->>DealTracker: run deal/info - Note right of DealTracker: Request information about an aggregate -``` +![dealer tracker flow](./w3-filecoin/deal-tracker.svg) ## Capabilities diff --git a/w3-filecoin/aggregator.svg b/w3-filecoin/aggregator.svg new file mode 100644 index 0000000..b74c557 --- /dev/null +++ b/w3-filecoin/aggregator.svg @@ -0,0 +1,17 @@ + + + + + + + + + + piece/offerpiece/offerPut piece into PieceQueuePut piece into PieceQueuepiece/acceptpiece/acceptAccumulate pieces into groupsAccumulate pieces into groupsfx.joinfx.joinfx.joinfx.joinooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooPiece QueuePiece QueueooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooPiece set storePiece set storeooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooCreate AggregatesCreate AggregatesIssue receipt with inclusion proofIssue receipt with inclusion proofInclusionProofInclusionProofAggregatorAggregatorDealerDealeraggregate/offeraggregate/offer \ No newline at end of file diff --git a/w3-filecoin/deal-tracker.svg b/w3-filecoin/deal-tracker.svg new file mode 100644 index 0000000..37ef3a6 --- /dev/null +++ b/w3-filecoin/deal-tracker.svg @@ -0,0 +1,17 @@ + + + + + + + + + + fx.joinfx.joinpoll  aggregate deal infopoll  aggregate deal infoDataAggregationProofDataAggregationProofPublish aggregatesPublish aggregatesDealerDealerdeal/infodeal/infoDeal TrakerDeal Trakeraggregate/acceptaggregate/acceptaggregate/offeraggregate/offerissue receiptissue receiptCRONCRONDataAggregationProofDataAggregationProof \ No newline at end of file diff --git a/w3-filecoin/dealer.svg b/w3-filecoin/dealer.svg new file mode 100644 index 0000000..84a8af9 --- /dev/null +++ b/w3-filecoin/dealer.svg @@ -0,0 +1,17 @@ + + + + + + + + + + fx.joinfx.joinpoll  aggregate deal infopoll  aggregate deal infoDataAggregationProofDataAggregationProofPublish aggregatesPublish aggregatesDealerDealerdeal/infodeal/infoDeal TrakerDeal Trakeraggregate/acceptaggregate/acceptaggregate/offeraggregate/offerissue receiptissue receiptCRONCRONDataAggregationProofDataAggregationProof \ No newline at end of file diff --git a/w3-filecoin/storefront.svg b/w3-filecoin/storefront.svg new file mode 100644 index 0000000..c1cfefb --- /dev/null +++ b/w3-filecoin/storefront.svg @@ -0,0 +1,17 @@ + + + + + + + + + + piece/offerpiece/offerfx.joinfx.joinStorefrontStorefrontAggregatorAggregatorooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooEnqueue for validationEnqueue for validationfilecoin/accepetfilecoin/accepetDataAggregationProofDataAggregationProofS3S3R2R2Have piece ?Have piece ?filecoin/offerfilecoin/offerissue receiptissue receiptNotFoundErrorNotFoundErrorfilecoin/submitfilecoin/submitfx.forkfx.forkfx.joinfx.join \ No newline at end of file diff --git a/w3-filecoin/workflow.tldr b/w3-filecoin/workflow.tldr new file mode 100644 index 0000000..14c5614 --- /dev/null +++ b/w3-filecoin/workflow.tldr @@ -0,0 +1,5791 @@ +{ + "tldrawFileFormatVersion": 1, + "schema": { + "schemaVersion": 1, + "storeVersion": 4, + "recordVersions": { + "asset": { + "version": 1, + "subTypeKey": "type", + "subTypeVersions": { + "image": 2, + "video": 2, + "bookmark": 0 + } + }, + "camera": { + "version": 1 + }, + "document": { + "version": 2 + }, + "instance": { + "version": 17 + }, + "instance_page_state": { + "version": 3 + }, + "page": { + "version": 1 + }, + "shape": { + "version": 3, + "subTypeKey": "type", + "subTypeVersions": { + "group": 0, + "embed": 4, + "bookmark": 1, + "image": 2, + "text": 1, + "draw": 1, + "geo": 7, + "line": 0, + "note": 4, + "frame": 0, + "arrow": 1, + "highlight": 0, + "video": 1 + } + }, + "instance_presence": { + "version": 4 + }, + "pointer": { + "version": 1 + } + } + }, + "records": [ + { + "gridSize": 10, + "name": "", + "meta": {}, + "id": "document:document", + "typeName": "document" + }, + { + "id": "pointer:pointer", + "typeName": "pointer", + "x": 1141.039491751153, + "y": 680.0742666425292, + "lastActivityTimestamp": 1695141718721, + "meta": {} + }, + { + "meta": {}, + "id": "page:uQnL6FrXKA8qFUFS7ZQBe", + "name": "Page 1", + "index": "a1", + "typeName": "page" + }, + { + "x": -604.9989794535514, + "y": -89.72422461101107, + "z": 0.8881383292456979, + "meta": {}, + "id": "camera:page:uQnL6FrXKA8qFUFS7ZQBe", + "typeName": "camera" + }, + { + "editingId": null, + "croppingId": null, + "selectedIds": [], + "hoveredId": null, + "erasingIds": [], + "hintingIds": [], + "focusLayerId": null, + "meta": {}, + "id": "instance_page_state:page:uQnL6FrXKA8qFUFS7ZQBe", + "pageId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "typeName": "instance_page_state" + }, + { + "followingUserId": null, + "opacityForNextShape": 1, + "stylesForNextShape": { + "tldraw:font": "draw", + "tldraw:size": "s", + "tldraw:geo": "ellipse", + "tldraw:dash": "dashed", + "tldraw:fill": "none", + "tldraw:color": "yellow", + "tldraw:arrowheadStart": "none", + "tldraw:arrowheadEnd": "arrow" + }, + "brush": null, + "scribble": null, + "cursor": { + "type": "default", + "color": "white", + "rotation": 0 + }, + "isFocusMode": false, + "exportBackground": false, + "isDebugMode": false, + "isToolLocked": true, + "screenBounds": { + "x": 0, + "y": 0, + "w": 613, + "h": 805 + }, + "zoomBrush": null, + "isGridMode": false, + "isPenMode": false, + "chatMessage": "", + "isChatting": false, + "highlightedUserIds": [], + "meta": {}, + "id": "instance:instance", + "currentPageId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "typeName": "instance" + }, + { + "x": 5.140625, + "y": 5.699916294642861, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 161.171875, + "text": "filecoin/offer", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.8303571428571429 + }, + "parentId": "shape:zSnjIgfcjqBS6Nla81s4c", + "index": "a1", + "id": "shape:s4tx9ZPbadBRqXCGvRPp8", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 147.97265625, + "h": 30.523437500000004, + "geo": "rectangle", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:zSnjIgfcjqBS6Nla81s4c", + "index": "a2", + "id": "shape:sl_sOlmCGmzm5hkLk54mN", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 161.046875, + "h": 31.4140625, + "geo": "rectangle", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "mono", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:QPlv0N-DGw4Qb_d_XKklD", + "index": "a1", + "id": "shape:lXaT2F5R52ZppxOTEFLn-", + "typeName": "shape" + }, + { + "x": 8.95703125, + "y": 4.65694754464289, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 173.15591397849462, + "text": "filecoin/accepet", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.8303571428571429 + }, + "parentId": "shape:QPlv0N-DGw4Qb_d_XKklD", + "index": "a2", + "id": "shape:bkPEyXqRXraifW5xQMGEa", + "typeName": "shape" + }, + { + "x": 264.6640625, + "y": 125.328125, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b37", + "props": { + "dash": "dotted", + "size": "s", + "fill": "none", + "color": "light-blue", + "labelColor": "black", + "bend": 22.935606818376886, + "start": { + "type": "binding", + "boundShapeId": "shape:VAVedgHc0yS3OMctA4G8h", + "normalizedAnchor": { + "x": 0.21001293466416274, + "y": 0.5524392835097933 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:SSni0MIcFXh_cuHm7H2n-", + "normalizedAnchor": { + "x": 0.031902606622562585, + "y": 0.6255920584857024 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "mono" + }, + "id": "shape:1fLS4wyDMArcRzC9whQYP", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "shape:Mk4f3fcL2d7isqddkOs8t", + "index": "a1", + "props": {}, + "id": "shape:zSnjIgfcjqBS6Nla81s4c", + "typeName": "shape" + }, + { + "x": 530.7169569043787, + "y": 111.04572864356197, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 177.69424959397415, + "text": "piece/offer", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.7949880632388084 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "a9G", + "id": "shape:sJ9-pXd1-0nzzxX_hqYqX", + "typeName": "shape" + }, + { + "x": 547.9165520636107, + "y": 106.26908114417645, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 103.92964720530863, + "h": 28.741709286906364, + "geo": "rectangle", + "color": "green", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2c4", + "id": "shape:SSni0MIcFXh_cuHm7H2n-", + "typeName": "shape" + }, + { + "x": 725.447206646935, + "y": 163.03380588617202, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 112.96012952322627, + "text": "Put piece into PieceQueue", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aD", + "id": "shape:gOuys8sj40ijJo_rVvM1h", + "typeName": "shape" + }, + { + "x": 1.048889558678752, + "y": 4.556788813722676, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 161.171875, + "text": "piece/accept", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.7949880632388084 + }, + "parentId": "shape:6On9x8eTbP6rL2HnmYhX5", + "index": "a1", + "id": "shape:5Lt66Ml1iYp0BoXCaPLTq", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 130.37678915648195, + "h": 29.223291050427655, + "geo": "rectangle", + "color": "green", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "mono", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:6On9x8eTbP6rL2HnmYhX5", + "index": "a2", + "id": "shape:L7bbjqDsz6BBVYXPr2264", + "typeName": "shape" + }, + { + "x": 594.7109375, + "y": 148.9140625, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2d", + "props": { + "dash": "dashed", + "size": "m", + "fill": "pattern", + "color": "green", + "labelColor": "black", + "bend": 0, + "start": { + "type": "binding", + "boundShapeId": "shape:9iT0bjpsxoy6ZVbLglpvr", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:L7bbjqDsz6BBVYXPr2264", + "normalizedAnchor": { + "x": 0.4620921725391697, + "y": 0.5110276978880951 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:eD_gf3NnfwaceqK4mKb2x", + "typeName": "shape" + }, + { + "x": 549.5625, + "y": 449.9957763497862, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aF", + "props": {}, + "id": "shape:6On9x8eTbP6rL2HnmYhX5", + "typeName": "shape" + }, + { + "x": 718.9123057476287, + "y": 135.78496649098253, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2c6", + "props": { + "dash": "dotted", + "size": "s", + "fill": "solid", + "color": "green", + "labelColor": "black", + "bend": -11.785684597715475, + "start": { + "type": "binding", + "boundShapeId": "shape:SSni0MIcFXh_cuHm7H2n-", + "normalizedAnchor": { + "x": 0.9622508497926456, + "y": 0.5518055255871596 + }, + "isExact": false + }, + "end": { + "type": "point", + "x": -13.185995261224434, + "y": 51.2830421141324 + }, + "arrowheadStart": "arrow", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:D5vxmL53O6Ev2YZ7Vzrgk", + "typeName": "shape" + }, + { + "x": 209.37475489885836, + "y": 300.52807941292787, + "rotation": 1.5533430342749535, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "m", + "w": 35.42888303748985, + "text": "fx.join", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aI", + "id": "shape:v9lgXaCy3OqaAhsQIz__e", + "typeName": "shape" + }, + { + "x": 696.286059327439, + "y": 221.0137238938919, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "al", + "props": { + "dash": "dotted", + "size": "s", + "fill": "solid", + "color": "green", + "labelColor": "black", + "bend": 0.7825907510645673, + "start": { + "type": "point", + "x": 23.016519578240946, + "y": -0.087890625 + }, + "end": { + "type": "point", + "x": 22.94921037096617, + "y": 42.59469256964039 + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:9-VpTseezd3YGTwneQrUD", + "typeName": "shape" + }, + { + "x": 729.0584613389548, + "y": 238.32901967518967, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 137.02274230529247, + "text": "Accumulate pieces into groups", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4902149649247424 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aK", + "id": "shape:P7sSSGBVYpukvFKlankN1", + "typeName": "shape" + }, + { + "x": 622.2421875, + "y": 317.375, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2fV", + "props": { + "dash": "draw", + "size": "m", + "fill": "solid", + "color": "green", + "labelColor": "black", + "bend": 137.71849728549364, + "start": { + "type": "binding", + "boundShapeId": "shape:L7bbjqDsz6BBVYXPr2264", + "normalizedAnchor": { + "x": 0.5762345751117877, + "y": 0.5620769001842671 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:xAbgjN6ZYzHUJWzxDV2-0", + "normalizedAnchor": { + "x": 0.06336317329582292, + "y": 0.3818354128023348 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:y3s6ozpbVCKfUcNBNyV9b", + "typeName": "shape" + }, + { + "x": 701.5936427264085, + "y": 453.85825066959273, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "m", + "w": 35.42888303748985, + "text": "fx.join", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aP", + "id": "shape:UGF7Hx0v-nROxCMOFn2J_", + "typeName": "shape" + }, + { + "x": 597.1249953515861, + "y": 203.3988903439719, + "rotation": 1.5707963267948966, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "m", + "w": 35.42888303748985, + "text": "fx.join", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aQ", + "id": "shape:geqby3fDz9St6EjfDxvvT", + "typeName": "shape" + }, + { + "x": 0, + "y": 3.8049212610775527, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 161.171875, + "text": "aggregate/offer", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.7949880632388084 + }, + "parentId": "shape:Jigpp2ApvivD6nepjJ_ON", + "index": "a1", + "id": "shape:Jt4MVMmWZWixvBnDPchmX", + "typeName": "shape" + }, + { + "x": 0.2728954737179947, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 130.37678915648195, + "h": 29.223291050427655, + "geo": "rectangle", + "color": "yellow", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:Jigpp2ApvivD6nepjJ_ON", + "index": "a2", + "id": "shape:xAbgjN6ZYzHUJWzxDV2-0", + "typeName": "shape" + }, + { + "x": 787.5618681332389, + "y": 352.96090925193295, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aU", + "id": "shape:cxAeDGGXHP9xCkGPB9-Uk", + "typeName": "shape" + }, + { + "x": 787.6336459009037, + "y": 351.2197376222484, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aV", + "id": "shape:t5S0AcjZ9C6brqF-od616", + "typeName": "shape" + }, + { + "x": 787.5158855008287, + "y": 349.3647309391578, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aW", + "id": "shape:_jTvgGxuV3A9cwOK_77WW", + "typeName": "shape" + }, + { + "x": 787.5618681332389, + "y": 347.70991693619527, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aX", + "id": "shape:iJYYYa0J8E5nlALIYmp8g", + "typeName": "shape" + }, + { + "x": 784.28351507619, + "y": 347.7013366115577, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aY", + "id": "shape:ujRymt70YzRUoZDUuyAb1", + "typeName": "shape" + }, + { + "x": 784.28351507619, + "y": 349.43315227078546, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aZ", + "id": "shape:qLh8HHyd4w8TYyC81WB_F", + "typeName": "shape" + }, + { + "x": 784.28351507619, + "y": 351.16496793001335, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aa", + "id": "shape:b3EXBVfziDclLtM41M1Hw", + "typeName": "shape" + }, + { + "x": 784.28351507619, + "y": 352.89678358924124, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ab", + "id": "shape:2QlAqFKlFy3YMRcMZwsat", + "typeName": "shape" + }, + { + "x": 637.441425143759, + "y": 190.01025609977484, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ac", + "id": "shape:ZsGusXXgEDU5Tr9P397bw", + "typeName": "shape" + }, + { + "x": 637.2916308205558, + "y": 205.47772798925143, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 743.953125, + "text": "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ad", + "id": "shape:2ltaAMrtSK617OkGfnc2-", + "typeName": "shape" + }, + { + "x": 637.4423915587475, + "y": 209.05056420139726, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 743.953125, + "text": "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ae", + "id": "shape:skusL1ViupaeeffCUt4Ce", + "typeName": "shape" + }, + { + "x": 780.969678501873, + "y": 186.45338102130108, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 161.0234375, + "text": "oooooooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "af", + "id": "shape:Es2ZdCN6SNN-ZOsREjWVh", + "typeName": "shape" + }, + { + "x": 638.0583829456175, + "y": 178.1421791082704, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "l", + "w": 219.0234375, + "text": "Piece Queue", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ag", + "id": "shape:hgmXwr0iWs0ggqpWz-4JF", + "typeName": "shape" + }, + { + "x": 711.5337065164002, + "y": 276.8075868176975, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ah", + "id": "shape:mywOZCuWrlsASjkqo2bGL", + "typeName": "shape" + }, + { + "x": 711.6054842840653, + "y": 275.0664151880129, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ai", + "id": "shape:Gy_XVLILV5sQMvwLUbpZ0", + "typeName": "shape" + }, + { + "x": 711.4877238839898, + "y": 273.21140850492236, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aj", + "id": "shape:y_XesG9nD5zvPseEQbu19", + "typeName": "shape" + }, + { + "x": 711.5337065164002, + "y": 271.5565945019598, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ak", + "id": "shape:jUnwaCUys41Xx4lGDg-Mx", + "typeName": "shape" + }, + { + "x": 761.8964908073275, + "y": 276.9641460458197, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "am", + "id": "shape:_8sIGAYeHM5f6pT6-NiGa", + "typeName": "shape" + }, + { + "x": 761.9682685749925, + "y": 275.2229744161351, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "an", + "id": "shape:sG2u3eDikBhtlwPIDcZLX", + "typeName": "shape" + }, + { + "x": 761.8505081749171, + "y": 273.36796773304445, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ao", + "id": "shape:1muWihbbo2C3PFW_VMZj_", + "typeName": "shape" + }, + { + "x": 761.8964908073275, + "y": 271.713153730082, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ap", + "id": "shape:ikH246HtTpa2kVuxwHk7K", + "typeName": "shape" + }, + { + "x": 736.5985666656771, + "y": 276.98447120926767, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aq", + "id": "shape:FOTIXc3IEyyl8AWwb9LG4", + "typeName": "shape" + }, + { + "x": 736.6703444333419, + "y": 275.2432995795831, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ar", + "id": "shape:jnu5N5Cw3NF2y41TQGl7R", + "typeName": "shape" + }, + { + "x": 736.5525840332667, + "y": 273.38829289649243, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "as", + "id": "shape:wdDppHj7J9zh_US3znbUm", + "typeName": "shape" + }, + { + "x": 736.5985666656771, + "y": 271.73347889353, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "at", + "id": "shape:kZcE0hmH7z2JDV_zHAlY2", + "typeName": "shape" + }, + { + "x": 661.1622244905775, + "y": 288.5495289268597, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "au", + "id": "shape:4ysKVB4YEim4wBuZflmqx", + "typeName": "shape" + }, + { + "x": 661.2340022582423, + "y": 286.808357297175, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "av", + "id": "shape:mfputoFi7gPha9wM7R7If", + "typeName": "shape" + }, + { + "x": 661.1162418581671, + "y": 284.95335061408446, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aw", + "id": "shape:ba9cUU0Sxsox4k2hCSQ7u", + "typeName": "shape" + }, + { + "x": 661.1622244905775, + "y": 283.2985366111219, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ax", + "id": "shape:5uZsnVM4uQcAi1tj_yXxC", + "typeName": "shape" + }, + { + "x": 635.864300348927, + "y": 288.5698540903077, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "ay", + "id": "shape:GMTZCyRcNioWHO3rBTDYf", + "typeName": "shape" + }, + { + "x": 635.9360781165921, + "y": 286.8286824606231, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "az", + "id": "shape:AAMBtlx79jvES_zuvgJcK", + "typeName": "shape" + }, + { + "x": 635.8183177165167, + "y": 284.97367577753243, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b00", + "id": "shape:16M3fsfAn-q5qUJScpIrE", + "typeName": "shape" + }, + { + "x": 635.864300348927, + "y": 283.3188617745699, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b01", + "id": "shape:HYsboXnyy8h2V86IpNp1m", + "typeName": "shape" + }, + { + "x": 787.6562823233536, + "y": 288.8597481381387, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b02", + "id": "shape:DM19R7FlVKwdF0zpcEOEb", + "typeName": "shape" + }, + { + "x": 787.7280600910184, + "y": 287.1185765084542, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b03", + "id": "shape:_Q8FzXFiN-BKzafp2HWQ4", + "typeName": "shape" + }, + { + "x": 787.6102996909432, + "y": 285.2635698253637, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b04", + "id": "shape:vNYnWo2NVCpdIZp3G9pgY", + "typeName": "shape" + }, + { + "x": 787.6562823233536, + "y": 283.608755822401, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b05", + "id": "shape:TyUGHZe9hQLOoa4dor-ua", + "typeName": "shape" + }, + { + "x": 787.3430848770257, + "y": 276.7950538715396, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b06", + "id": "shape:djdRjDMkTu_QtnVD-Lqs-", + "typeName": "shape" + }, + { + "x": 787.4148626446907, + "y": 275.05388224185515, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b07", + "id": "shape:AYkmcMNbs4zbPvdb7ojU1", + "typeName": "shape" + }, + { + "x": 787.2971022446153, + "y": 273.1988755587645, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b08", + "id": "shape:KolyeRMYXzV6EcV4OmwbT", + "typeName": "shape" + }, + { + "x": 787.3430848770257, + "y": 271.5440615558018, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b09", + "id": "shape:Qhzpzzc07wnTPNlxYQsPi", + "typeName": "shape" + }, + { + "x": 711.5337065164002, + "y": 288.57948779150024, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0A", + "id": "shape:0XJA1rR4-hxDOu4HYYC__", + "typeName": "shape" + }, + { + "x": 711.6054842840653, + "y": 286.8383161618158, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0B", + "id": "shape:FDulyXFNG2vjBZiOp8k5d", + "typeName": "shape" + }, + { + "x": 711.4877238839898, + "y": 284.98330947872523, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0C", + "id": "shape:8lcFzdCwlB2n6MyWxSUEh", + "typeName": "shape" + }, + { + "x": 711.5337065164002, + "y": 283.32849547576257, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0D", + "id": "shape:6Xrg3OUofbz1mlOw8Yiwq", + "typeName": "shape" + }, + { + "x": 686.23578237475, + "y": 288.5998129549482, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0E", + "id": "shape:YkZT1N2pi2ZWJU6S5N7OQ", + "typeName": "shape" + }, + { + "x": 686.3075601424149, + "y": 286.85864132526376, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0F", + "id": "shape:AB4ZQB56ytaiCpJwO2j57", + "typeName": "shape" + }, + { + "x": 686.1897997423396, + "y": 285.0036346421731, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0G", + "id": "shape:cG6JjejDjZPxDLhPa5SWS", + "typeName": "shape" + }, + { + "x": 686.23578237475, + "y": 283.34882063921043, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0H", + "id": "shape:Z6FHeGh8SzbjenkkCeX0J", + "typeName": "shape" + }, + { + "x": 761.8964908073275, + "y": 288.73604701962245, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0I", + "id": "shape:FAbbWat5NNLqBWPbaC4zl", + "typeName": "shape" + }, + { + "x": 761.9682685749925, + "y": 286.994875389938, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0J", + "id": "shape:6Ky8wgHaIC1wWNWQo8yzk", + "typeName": "shape" + }, + { + "x": 761.8505081749171, + "y": 285.1398687068473, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0K", + "id": "shape:2swIbhk3P0Lww2XSzKU6P", + "typeName": "shape" + }, + { + "x": 761.8964908073275, + "y": 283.48505470388477, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0L", + "id": "shape:mj4WnuBz-FM9kP03oZ_sl", + "typeName": "shape" + }, + { + "x": 736.5985666656771, + "y": 288.7563721830704, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0M", + "id": "shape:bV1WeoKvkXVfpsU2Cwz0-", + "typeName": "shape" + }, + { + "x": 736.6703444333419, + "y": 287.01520055338597, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0N", + "id": "shape:De2f6LjPCeDKnUGo4RHDW", + "typeName": "shape" + }, + { + "x": 736.5525840332667, + "y": 285.1601938702953, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0O", + "id": "shape:5YCjbcMVI1qAue-aZUeca", + "typeName": "shape" + }, + { + "x": 736.5985666656771, + "y": 283.50537986733264, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0P", + "id": "shape:Imp1pLtY1mVDeCyd56YH6", + "typeName": "shape" + }, + { + "x": 636.4642248520937, + "y": 267.5133424165575, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "l", + "w": 269.9609375, + "text": "Piece set store", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0Q", + "id": "shape:mimu-uVUWDyr_bg-yy7oF", + "typeName": "shape" + }, + { + "x": 686.6270931212881, + "y": 352.7081825933581, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0R", + "id": "shape:GrjiSE68ExKBNklIUqMUR", + "typeName": "shape" + }, + { + "x": 686.698870888953, + "y": 350.96701096367366, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0S", + "id": "shape:i2E7tKtBAFUOo7Zv2jT1Z", + "typeName": "shape" + }, + { + "x": 686.5811104888777, + "y": 349.112004280583, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0T", + "id": "shape:HgP6xEjaBMBHIMfJAE--J", + "typeName": "shape" + }, + { + "x": 686.6270931212881, + "y": 347.4571902776203, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0U", + "id": "shape:EE6-7rNET5yQpJLT20PTv", + "typeName": "shape" + }, + { + "x": 665.1902787967917, + "y": 347.4820761715874, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0V", + "id": "shape:E-OcDM_V0mTDiKS-tvpTe", + "typeName": "shape" + }, + { + "x": 665.2667736720679, + "y": 350.8200191931068, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0W", + "id": "shape:ahP6r5M_VuSa3s4z1g-g2", + "typeName": "shape" + }, + { + "x": 665.1681947511272, + "y": 352.6517786338624, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0X", + "id": "shape:dGvZB1hJISaCMTdYwUER6", + "typeName": "shape" + }, + { + "x": 665.2195114642569, + "y": 349.08210217310165, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 86.80200761655354, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0Y", + "id": "shape:7C_zbEJdbGioxkfY4QBGR", + "typeName": "shape" + }, + { + "x": 732.4780983008734, + "y": 352.68167063841855, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0Z", + "id": "shape:Si9g7k_WnDFxt2x6ZVu1l", + "typeName": "shape" + }, + { + "x": 732.5498760685382, + "y": 350.940499008734, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0a", + "id": "shape:mE4PIzi7QrMk4zrIHeE-J", + "typeName": "shape" + }, + { + "x": 732.432115668463, + "y": 349.08549232564343, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0b", + "id": "shape:GukcjWtOoQ0zETH1or5hs", + "typeName": "shape" + }, + { + "x": 732.4780983008734, + "y": 347.4306783226809, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0c", + "id": "shape:lOK5LvoU2o6op7Ry_l-hA", + "typeName": "shape" + }, + { + "x": 711.0412839763769, + "y": 347.4555642166478, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0d", + "id": "shape:SuLqrBwoxikEz-BOAboDY", + "typeName": "shape" + }, + { + "x": 711.1177788516532, + "y": 350.79350723816736, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0e", + "id": "shape:I59cRtl3ighycc_7Vsu1h", + "typeName": "shape" + }, + { + "x": 711.0191999307126, + "y": 352.62526667892286, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0f", + "id": "shape:A7JiGGJO17zS4yw3qp7qN", + "typeName": "shape" + }, + { + "x": 753.8235885932868, + "y": 347.4962523619087, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0g", + "id": "shape:O2q3xHs8MtZeWnXA7GjK8", + "typeName": "shape" + }, + { + "x": 753.8699555219198, + "y": 349.2438113226297, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0h", + "id": "shape:re7ucbRIcGrbwnGU3uOTf", + "typeName": "shape" + }, + { + "x": 753.8350344400033, + "y": 351.04578342867984, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0i", + "id": "shape:J0BGiaxcSahexsvgYm1cV", + "typeName": "shape" + }, + { + "x": 753.8350344400033, + "y": 352.77759908790773, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0j", + "id": "shape:qwwqUrVdtGxMXq_5ZWvcH", + "typeName": "shape" + }, + { + "x": 711.0705166438422, + "y": 349.0555902181622, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 149.59375, + "text": "ooooooooooooo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0k", + "id": "shape:Zv2pLZQgufaYHZL09Kq6Y", + "typeName": "shape" + }, + { + "x": 741.2068976358064, + "y": 186.4859539287038, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 161.0234375, + "text": "oooooooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0l", + "id": "shape:vCD6kfVM0m6TWVXjoXc6P", + "typeName": "shape" + }, + { + "x": 637.441425143759, + "y": 190.01025609977484, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0m", + "id": "shape:nssifeB00-hq6yvKcjYDX", + "typeName": "shape" + }, + { + "x": 696.9441823570617, + "y": 190.16438156407094, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0n", + "id": "shape:EJeNRTrVqoT_S2wNwn9D-", + "typeName": "shape" + }, + { + "x": 756.5573696710712, + "y": 190.03250101214758, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 263.890625, + "text": "ooooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0o", + "id": "shape:YmvE_KR5l286_WLl6kyNJ", + "typeName": "shape" + }, + { + "x": 637.3222559703344, + "y": 193.90311576498414, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0p", + "id": "shape:Ib6V3O2hKXLiRbBDAQM1n", + "typeName": "shape" + }, + { + "x": 637.3222559703344, + "y": 193.90311576498414, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0q", + "id": "shape:jHnxNlSkr8R03KwFzqSQz", + "typeName": "shape" + }, + { + "x": 696.8250131836369, + "y": 194.0572412292803, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0r", + "id": "shape:2GG0Uo_8vYng6sdS18naD", + "typeName": "shape" + }, + { + "x": 756.4382004976464, + "y": 193.92536067735676, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 263.890625, + "text": "ooooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0s", + "id": "shape:7ARrfDB16lrpBErvEBgPV", + "typeName": "shape" + }, + { + "x": 637.493859580066, + "y": 197.72924069307567, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0t", + "id": "shape:e4HHUr0DVJ-p3JL5emRwq", + "typeName": "shape" + }, + { + "x": 637.493859580066, + "y": 197.72924069307567, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0u", + "id": "shape:4CupB51fXTbplCKFpOpUg", + "typeName": "shape" + }, + { + "x": 696.9966167933685, + "y": 197.8833661573717, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0v", + "id": "shape:N2nj-aa2yuzoX5mzDOfYy", + "typeName": "shape" + }, + { + "x": 756.6098041073781, + "y": 197.7514856054483, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 263.890625, + "text": "ooooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0w", + "id": "shape:HfaOBWgnq4GNFiukGSk9h", + "typeName": "shape" + }, + { + "x": 637.493859580066, + "y": 201.44027424856398, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0x", + "id": "shape:t_yoExPv5xjOg5rpPYbxp", + "typeName": "shape" + }, + { + "x": 637.493859580066, + "y": 201.44027424856398, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0y", + "id": "shape:KDhB_wbpHnaFxNT3IEdfJ", + "typeName": "shape" + }, + { + "x": 696.9966167933685, + "y": 201.59439971285997, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0z", + "id": "shape:oaP6smCKGNMKqysZzFxVH", + "typeName": "shape" + }, + { + "x": 756.6098041073781, + "y": 201.4625191609366, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 263.890625, + "text": "ooooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b10", + "id": "shape:qo1YqbOwpWXAgdivFPv9z", + "typeName": "shape" + }, + { + "x": 677.0331784679435, + "y": 212.67457148053234, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 161.0234375, + "text": "oooooooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b11", + "id": "shape:bg8NcM-Be8h-FyYMT2fiM", + "typeName": "shape" + }, + { + "x": 637.0229953648443, + "y": 212.70714438793527, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 161.0234375, + "text": "oooooooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b12", + "id": "shape:HEa4fUu_BOSx3VHW3CwoF", + "typeName": "shape" + }, + { + "x": 756.617999969324, + "y": 212.60068659300896, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 161.0234375, + "text": "oooooooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b13", + "id": "shape:nRElkiWAVD5apCxsGFced", + "typeName": "shape" + }, + { + "x": 716.8552191032572, + "y": 212.63325950041178, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 161.0234375, + "text": "oooooooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b14", + "id": "shape:2G0v3mEOgnPpIF0YA-jLn", + "typeName": "shape" + }, + { + "x": 796.2442292443648, + "y": 212.49263987577058, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 103.875, + "text": "ooooooooo", + "font": "draw", + "align": "end", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b15", + "id": "shape:yijJrzjMWxI0R_cEqWUve", + "typeName": "shape" + }, + { + "x": 778.221532792008, + "y": 347.69525914343336, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b16", + "id": "shape:v_RYz8wOu_Nd4fUiDT8vV", + "typeName": "shape" + }, + { + "x": 778.221532792008, + "y": 349.42707480266125, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b17", + "id": "shape:sfm72FpqP-IDyg4m1xZKd", + "typeName": "shape" + }, + { + "x": 778.221532792008, + "y": 351.15889046188914, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b18", + "id": "shape:7nUUVsgTThc-AI0BYOoJ2", + "typeName": "shape" + }, + { + "x": 778.221532792008, + "y": 352.8907061211169, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 13.848972909367614, + "text": "oo", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.1435555353298646 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b19", + "id": "shape:sIXkf-WJ0ekOmLH3Qrrvz", + "typeName": "shape" + }, + { + "x": 696.286059327439, + "y": 221.0137238938919, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b0kV", + "props": { + "dash": "dotted", + "size": "s", + "fill": "solid", + "color": "green", + "labelColor": "black", + "bend": 0.7825907510645673, + "start": { + "type": "point", + "x": 25.028038458498145, + "y": 76.15310560527928 + }, + "end": { + "type": "binding", + "boundShapeId": "shape:Zv2pLZQgufaYHZL09Kq6Y", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:mPYmAJr7DbtMhVvcsWwdv", + "typeName": "shape" + }, + { + "x": 729.6778665227424, + "y": 312.4321761541113, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 85.28208467925128, + "text": "Create Aggregates", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4902149649247424 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1B", + "id": "shape:VQZBbLz1vj5Z-2cceEpio", + "typeName": "shape" + }, + { + "x": 771.0085249700653, + "y": 300.83141492881606, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1C", + "props": { + "dash": "dotted", + "size": "s", + "fill": "solid", + "color": "green", + "labelColor": "black", + "bend": -10.057864861071021, + "start": { + "type": "point", + "x": -49.85488455836048, + "y": 62.24679983845539 + }, + "end": { + "type": "point", + "x": -86.83187165739727, + "y": 148.69685834522642 + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:j8zCHz6YBhJDvsEerfAi2", + "typeName": "shape" + }, + { + "x": 727.0397306869139, + "y": 376.6361409336539, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 128.4095819262487, + "text": "Issue receipt with inclusion proof", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4981306207710484 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1D", + "id": "shape:h7aElhk0NkVgd4JBboI9E", + "typeName": "shape" + }, + { + "x": 1056.7680379674068, + "y": 244.78902963738045, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 111.46688539546676, + "h": 23.43508641737577, + "geo": "rectangle", + "color": "yellow", + "labelColor": "black", + "fill": "pattern", + "dash": "draw", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1l2", + "id": "shape:brBie2GGoAj5_S8vqewkU", + "typeName": "shape" + }, + { + "x": 958.8244480060387, + "y": 509.3568777183632, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 147.3904969426513, + "h": 29.223291050427655, + "geo": "rectangle", + "color": "yellow", + "labelColor": "black", + "fill": "semi", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2U", + "id": "shape:WJgk-gBd47qYTGliTlu7_", + "typeName": "shape" + }, + { + "x": 1036.5558620510403, + "y": 142.1014312144177, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2g", + "props": { + "dash": "dashed", + "size": "m", + "fill": "pattern", + "color": "yellow", + "labelColor": "black", + "bend": -4.788377120515305, + "start": { + "type": "binding", + "boundShapeId": "shape:tlIEUmtxUNOSkrdY9qm7D", + "normalizedAnchor": { + "x": 0.5301753216863743, + "y": 0.8817657702458582 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:WJgk-gBd47qYTGliTlu7_", + "normalizedAnchor": { + "x": 0.527977395086915, + "y": 0.8886133682597449 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:_uznFc9WCu_DLBjQxZ0tB", + "typeName": "shape" + }, + { + "x": 1057.8746272474343, + "y": 189.72206120295303, + "rotation": 1.5882496193148403, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "m", + "w": 35.42888303748985, + "text": "fx.join", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1I", + "id": "shape:E-2NMYj49HIw2pUcB_dxJ", + "typeName": "shape" + }, + { + "x": 1198.9821231760845, + "y": 147.65953164551217, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2fG", + "props": { + "dash": "dotted", + "size": "s", + "fill": "solid", + "color": "yellow", + "labelColor": "black", + "bend": 2.8460566567638255, + "start": { + "type": "binding", + "boundShapeId": "shape:xAbgjN6ZYzHUJWzxDV2-0", + "normalizedAnchor": { + "x": 0.7649176870281691, + "y": 0.9664555514255365 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:brBie2GGoAj5_S8vqewkU", + "normalizedAnchor": { + "x": 0.1522599750913122, + "y": 0.4955812878989818 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:UIgscnuyRfxYHhc5tXsT7", + "typeName": "shape" + }, + { + "x": 1084.9987256867607, + "y": 218.91407887522925, + "rotation": 4.996003610813204e-16, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 126.02669786186983, + "text": "Publish aggregates", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.5755874097825592 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1l4", + "id": "shape:so6IA2n1CK05NW7NHMQtD", + "typeName": "shape" + }, + { + "x": 1208.63060417055, + "y": 121.82180506552601, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1lG", + "props": { + "dash": "dotted", + "size": "s", + "fill": "pattern", + "color": "light-red", + "labelColor": "black", + "bend": 76.92740306572928, + "start": { + "type": "binding", + "boundShapeId": "shape:brBie2GGoAj5_S8vqewkU", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:KJkbctMgsTxk0nnfXtIE_", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "arrowheadStart": "triangle", + "arrowheadEnd": "inverted", + "text": "", + "font": "draw" + }, + "id": "shape:MOOTnDyhcY4HH1YVuK7_E", + "typeName": "shape" + }, + { + "x": 1276.4669127708719, + "y": 228.56172212714034, + "rotation": 5.759586531581287, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-red", + "size": "s", + "w": 110.43966866388249, + "text": "Pulls aggregates", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.7125499061937073 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1l8", + "id": "shape:EbFu6Q7j67lvP9SQOt1zp", + "typeName": "shape" + }, + { + "x": 22.53213341027572, + "y": 42.11599617843632, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 40.12668847741402, + "h": 40.12668847741402, + "geo": "hexagon", + "color": "grey", + "labelColor": "black", + "fill": "solid", + "dash": "solid", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:ZsCAx3EBCL7wivyRyfdvO", + "index": "a1", + "id": "shape:8x2Omgqkarj7ipMsmeQEH", + "typeName": "shape" + }, + { + "x": 1429.5798273386122, + "y": 21.638050535624615, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 97.62908580323307, + "h": 97.62908580323307, + "geo": "hexagon", + "color": "light-red", + "labelColor": "black", + "fill": "solid", + "dash": "draw", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1lC", + "id": "shape:KJkbctMgsTxk0nnfXtIE_", + "typeName": "shape" + }, + { + "x": -2.6879784431146163, + "y": 2.085475261878173, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 40.12668847741402, + "h": 40.12668847741402, + "geo": "hexagon", + "color": "grey", + "labelColor": "black", + "fill": "solid", + "dash": "solid", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:ZsCAx3EBCL7wivyRyfdvO", + "index": "a2", + "id": "shape:q6D3vqmNmIXBJnptG3ogs", + "typeName": "shape" + }, + { + "x": 46.26177848045904, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 40.12668847741402, + "h": 40.12668847741402, + "geo": "hexagon", + "color": "grey", + "labelColor": "black", + "fill": "solid", + "dash": "solid", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:ZsCAx3EBCL7wivyRyfdvO", + "index": "a3", + "id": "shape:pT71SyCk5bzydEYcD8vaR", + "typeName": "shape" + }, + { + "x": 1567.4324991555357, + "y": 62.5624952936852, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2w", + "props": { + "dash": "dotted", + "size": "s", + "fill": "pattern", + "color": "light-red", + "labelColor": "black", + "bend": 74.86730301177893, + "start": { + "type": "binding", + "boundShapeId": "shape:KJkbctMgsTxk0nnfXtIE_", + "normalizedAnchor": { + "x": 0.6139211441080946, + "y": 0.7250708499542788 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:8x2Omgqkarj7ipMsmeQEH", + "normalizedAnchor": { + "x": 0.3080090982139755, + "y": 0.43406097567412255 + }, + "isExact": false + }, + "arrowheadStart": "inverted", + "arrowheadEnd": "triangle", + "text": "", + "font": "draw" + }, + "id": "shape:OSRJ1HE6F80jy0l-cULWv", + "typeName": "shape" + }, + { + "x": 1546.2048843124041, + "y": 121.1722114439543, + "rotation": 0.5410520681182421, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-red", + "size": "s", + "w": 94.71903635848382, + "text": "Arrange deals", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.7125499061937073 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1lQ", + "id": "shape:fCz24-4BKd9mKc48I4nX8", + "typeName": "shape" + }, + { + "x": 1149.2611409212593, + "y": 203.91995871429063, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2n", + "props": { + "dash": "dotted", + "size": "s", + "fill": "semi", + "color": "yellow", + "labelColor": "black", + "bend": 0.8081980980207013, + "start": { + "type": "binding", + "boundShapeId": "shape:tD1Gx--iMBrDlKaECYVeh", + "normalizedAnchor": { + "x": 0.9285729363134484, + "y": 0.5207192032425101 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:HlSRbdX0-sQHDUclkeaQd", + "normalizedAnchor": { + "x": 0.1936698235042795, + "y": 0.4738285293012442 + }, + "isExact": false + }, + "arrowheadStart": "arrow", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:OOB6NXBqIgRT3sdeMte33", + "typeName": "shape" + }, + { + "x": 1160.9449350449481, + "y": 329.56291581476313, + "rotation": 0.017453292519937966, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 163.7584421132835, + "text": "poll aggregate deal info", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.5608427478607705 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1a", + "id": "shape:IvcWsngY-3xUiUJb80UKf", + "typeName": "shape" + }, + { + "x": 1275.2013913827323, + "y": 521.8110993756895, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2ZV", + "props": { + "dash": "dotted", + "size": "s", + "fill": "semi", + "color": "yellow", + "labelColor": "black", + "bend": -83.3457304897702, + "start": { + "type": "point", + "x": -216.3874620720544, + "y": -152.47618927262158 + }, + "end": { + "type": "binding", + "boundShapeId": "shape:3VaCSFsMfZQnp0OIvUKKP", + "normalizedAnchor": { + "x": 0.41646129453946035, + "y": 0.6875698867910772 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:6OZwIHd2b3Q_tyx6OC4GZ", + "typeName": "shape" + }, + { + "x": 961.7468381817307, + "y": 602.0545815938264, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2c5", + "props": { + "dash": "draw", + "size": "m", + "fill": "none", + "color": "yellow", + "labelColor": "black", + "bend": -315.61524966091594, + "start": { + "type": "binding", + "boundShapeId": "shape:8iHgZmtN8Jx7lC99mGgQ3", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:SSni0MIcFXh_cuHm7H2n-", + "normalizedAnchor": { + "x": 0.5627344113895996, + "y": 0.38246040503512124 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:Xi-ZPIavF7C0RUi_TBJ4G", + "typeName": "shape" + }, + { + "x": 700.2392318339413, + "y": 647.8284189344248, + "rotation": 0.12217304763960346, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 102.92815809518783, + "text": "retry on error", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.7790671300445888 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1e", + "id": "shape:zY015Va46dKMW4ozVueV8", + "typeName": "shape" + }, + { + "x": 1080.4973476960497, + "y": 572.0507319164125, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 175.51646992383752, + "text": "DataAggregationProof", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.838725757867961 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1g", + "id": "shape:DcDeFeSZhfYopdng78gEE", + "typeName": "shape" + }, + { + "x": 629.0146675959021, + "y": 491.01322211101547, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "s", + "w": 134.328125, + "text": "InclusionProof", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1j", + "id": "shape:yD0GSLAUen5uMHBQyrT-3", + "typeName": "shape" + }, + { + "x": 1448.9591629045553, + "y": 57.01841875930478, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-red", + "size": "s", + "w": 56.03125, + "text": "Spade", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1lS", + "id": "shape:-Ws3BCAKvnDwaSul4-8BO", + "typeName": "shape" + }, + { + "x": 78.5479821473948, + "y": -61.56194334257296, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "l", + "w": 191.40625, + "text": "Storefront", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1m", + "id": "shape:GOA2_d6ImN9GaLi7Ep6QQ", + "typeName": "shape" + }, + { + "x": 508.24505886983854, + "y": -65.91562996188117, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "green", + "size": "l", + "w": 215.7109375, + "text": "Aggregator", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1n", + "id": "shape:EAGxgD5WMuisOqXWtMeeI", + "typeName": "shape" + }, + { + "x": 955.645633180489, + "y": -60.38722542901658, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "l", + "w": 120.8828125, + "text": "Dealer", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b1o", + "id": "shape:I5LMxA7f7gi7pkZ6ALxiq", + "typeName": "shape" + }, + { + "x": 540.9821597674772, + "y": 690.2404856916803, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2mV", + "props": { + "dash": "dotted", + "size": "s", + "fill": "semi", + "color": "yellow", + "labelColor": "black", + "bend": -169.29878752785638, + "start": { + "type": "binding", + "boundShapeId": "shape:tD1Gx--iMBrDlKaECYVeh", + "normalizedAnchor": { + "x": 0.22496998633102183, + "y": 0.7951795749491619 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:BoqOBydUYEOx_R0EjtT0l", + "normalizedAnchor": { + "x": 0.5709327757700031, + "y": 0.7473743921641 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:En4TS48hSq3AdodR47DLW", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 56.741802693501995, + "h": 56.741802693501995, + "geo": "ellipse", + "color": "yellow", + "labelColor": "black", + "fill": "semi", + "dash": "dashed", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:mSB_hgO9Tfwd5C9SjuUgv", + "index": "a1", + "id": "shape:tD1Gx--iMBrDlKaECYVeh", + "typeName": "shape" + }, + { + "x": 0, + "y": 3.570808649920366, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-violet", + "size": "s", + "w": 161.171875, + "text": "deal/info", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.7949880632388084 + }, + "parentId": "shape:0CHNFP6jv2334Dsb3NWak", + "index": "a1", + "id": "shape:IDfCHO9q9umgEcuKmcRj3", + "typeName": "shape" + }, + { + "x": 2.734853900725966, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 130.37678915648195, + "h": 29.223291050427655, + "geo": "rectangle", + "color": "light-violet", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:0CHNFP6jv2334Dsb3NWak", + "index": "a2", + "id": "shape:HlSRbdX0-sQHDUclkeaQd", + "typeName": "shape" + }, + { + "x": 0.11916917342466604, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a1", + "id": "shape:IcATrt_tUXB6EGiP4tx89", + "typeName": "shape" + }, + { + "x": 0.11916917342466604, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a2", + "id": "shape:LypIDxHdU4aMKk2V97V7V", + "typeName": "shape" + }, + { + "x": 59.621926386727296, + "y": 0.15412546429610074, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a3", + "id": "shape:t3Y5BPtUX_ZhNGAc29r7R", + "typeName": "shape" + }, + { + "x": 0, + "y": 3.8928596652093006, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a4", + "id": "shape:YJ3yRGuRNOYGF1Ugw7VdK", + "typeName": "shape" + }, + { + "x": 0, + "y": 3.8928596652093006, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a5", + "id": "shape:XBCUO1K4dr1yM_YzqOePJ", + "typeName": "shape" + }, + { + "x": 59.502757213302516, + "y": 4.046985129505458, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a6", + "id": "shape:LQS43Po3EiXzcSmZgczJ0", + "typeName": "shape" + }, + { + "x": 0.17160360973161914, + "y": 7.718984593300831, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a7", + "id": "shape:Jmmxv58PJIOdVM4r-_iV4", + "typeName": "shape" + }, + { + "x": 0.17160360973161914, + "y": 7.718984593300831, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a8", + "id": "shape:tWLtpPbjzEfO9i17iPMSR", + "typeName": "shape" + }, + { + "x": 59.674360823034135, + "y": 7.873110057596875, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "a9", + "id": "shape:lldpGmsxDy3_0hwbj5KVg", + "typeName": "shape" + }, + { + "x": 0.17160360973161914, + "y": 11.430018148789145, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "aA", + "id": "shape:R6v48hl8igyKvmiYpazKj", + "typeName": "shape" + }, + { + "x": 0.17160360973161914, + "y": 11.430018148789145, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "aB", + "id": "shape:vFXtT1VOfhfn04oO_Nqyo", + "typeName": "shape" + }, + { + "x": 59.674360823034135, + "y": 11.584143613085132, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 241.03125, + "text": "ooooooooooooooooooooo", + "font": "draw", + "align": "start", + "autoSize": true, + "scale": 0.24740223703255163 + }, + "parentId": "shape:UEikGHtv-k636L0-Z3U9N", + "index": "aC", + "id": "shape:tgg3aMz11u6r0jOwGGMyT", + "typeName": "shape" + }, + { + "x": 27.513048886853994, + "y": 253.76401347598244, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3BG", + "props": { + "dash": "dotted", + "size": "s", + "fill": "pattern", + "color": "light-blue", + "labelColor": "black", + "bend": 10.896035688405146, + "start": { + "type": "binding", + "boundShapeId": "shape:POGxu-Osjdvukt7In1jG1", + "normalizedAnchor": { + "x": 0.08401095703654343, + "y": 0.9390896710577633 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:lldpGmsxDy3_0hwbj5KVg", + "normalizedAnchor": { + "x": 0.9382855124765085, + "y": 0.14070044169369442 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:IwIW86tUz7HJp9Lz3uJcD", + "typeName": "shape" + }, + { + "x": 2.637305828481857, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 101.43765460882499, + "text": "Enqueue for validation", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "shape:O5d5pUw6Mb22cGRnsnFt7", + "index": "a2", + "id": "shape:KxDjegT8kJGi9mdMBiAqj", + "typeName": "shape" + }, + { + "x": 0, + "y": 12.94528873392818, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "shape:O5d5pUw6Mb22cGRnsnFt7", + "index": "a1", + "props": {}, + "id": "shape:UEikGHtv-k636L0-Z3U9N", + "typeName": "shape" + }, + { + "x": 1343.94280539441, + "y": 282.06308633964915, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-violet", + "size": "l", + "w": 215.09375, + "text": "Deal Traker", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2M", + "id": "shape:3LK-I9tW1w5hTtzCJ7dPI", + "typeName": "shape" + }, + { + "x": 1369.2387133223172, + "y": 337.87080864608237, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b22V", + "props": {}, + "id": "shape:0CHNFP6jv2334Dsb3NWak", + "typeName": "shape" + }, + { + "x": 9.919504509739, + "y": 19.470225993011013, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 38.58910575434876, + "text": "CRON", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.7454581250462784 + }, + "parentId": "shape:mSB_hgO9Tfwd5C9SjuUgv", + "index": "a2", + "id": "shape:X0-fKdQH_wlKtY4bJgMyD", + "typeName": "shape" + }, + { + "x": 978.4412998597703, + "y": 614.387912342076, + "rotation": 5.619960191421741, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 55.4375, + "text": "fx.join", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.7766291053285426 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2S", + "id": "shape:H45i8dglXMfkHWKC91mXe", + "typeName": "shape" + }, + { + "x": 960.6742801376071, + "y": 512.3335951443398, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 176.62110599720998, + "text": "aggregate/accept", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.7949880632388084 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2W", + "id": "shape:y6tvKDTZuFVuL7nEx6Wh7", + "typeName": "shape" + }, + { + "x": 1060.784440778255, + "y": 546.9185014604825, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "yellow", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2Z", + "id": "shape:3VaCSFsMfZQnp0OIvUKKP", + "typeName": "shape" + }, + { + "x": 1027.472526246424, + "y": 547.2331089863775, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 24.18359330727776, + "h": 24.18359330727776, + "geo": "x-box", + "color": "yellow", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2a", + "id": "shape:8iHgZmtN8Jx7lC99mGgQ3", + "typeName": "shape" + }, + { + "x": 588.2424979927698, + "y": 143.74067075041614, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "green", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2c8", + "id": "shape:9iT0bjpsxoy6ZVbLglpvr", + "typeName": "shape" + }, + { + "x": 599.2454669966369, + "y": 491.08029934091655, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "green", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2e", + "id": "shape:wNgMFBv6D5A3Duc0yrkZl", + "typeName": "shape" + }, + { + "x": 51.604842546490204, + "y": 36.827345295980535, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "yellow", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:x95YNgCI7orU9q-QzNEfP", + "index": "a2", + "id": "shape:tlIEUmtxUNOSkrdY9qm7D", + "typeName": "shape" + }, + { + "x": 1008.1098461502431, + "y": 318.4041082946175, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2m", + "props": {}, + "id": "shape:mSB_hgO9Tfwd5C9SjuUgv", + "typeName": "shape" + }, + { + "x": 1164.509274779339, + "y": 428.78993925741435, + "rotation": 1.5358897417550101, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 64.62836352301848, + "text": "issue receipt", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.5608427478607705 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2h", + "id": "shape:Mu_Lp1eL11EefZiI9Yx-s", + "typeName": "shape" + }, + { + "x": -183.75464809694273, + "y": -0.6255056886483885, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 175.51646992383752, + "text": "DataAggregationProof", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.838725757867961 + }, + "parentId": "shape:cmIXaGXMR2fkB9pPFkuDA", + "index": "a1", + "id": "shape:7K045ZrsU6yyKYj9q0Rc0", + "typeName": "shape" + }, + { + "x": -4.9588516090989, + "y": -2.383317897893278, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:cmIXaGXMR2fkB9pPFkuDA", + "index": "a2", + "id": "shape:BoqOBydUYEOx_R0EjtT0l", + "typeName": "shape" + }, + { + "x": 25.026512117758415, + "y": -1.1470108404746497, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 21.492182043801733, + "h": 20.634181808800975, + "geo": "x-box", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:cmIXaGXMR2fkB9pPFkuDA", + "index": "a3", + "id": "shape:78KGZzPOrKclANdpzFqQs", + "typeName": "shape" + }, + { + "x": 421.0847459895499, + "y": 608.7089907027737, + "rotation": 0.15707963267948966, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 64.62836352301848, + "text": "issue receipt", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.5608427478607705 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2o", + "id": "shape:R5ZaPn1Z5h0oPFPh6gKnU", + "typeName": "shape" + }, + { + "x": 1442.6885368524659, + "y": 376.8540213987918, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "light-violet", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2p", + "id": "shape:yPb5vq85dMs1H2sNb0UW6", + "typeName": "shape" + }, + { + "x": 1409.3766223206349, + "y": 377.1686289246868, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 24.18359330727776, + "h": 24.18359330727776, + "geo": "x-box", + "color": "light-violet", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2q", + "id": "shape:xg979wzRRWBdkIzalveSy", + "typeName": "shape" + }, + { + "x": 1469.4530663530638, + "y": 379.7003605770441, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-violet", + "size": "s", + "w": 175.51646992383752, + "text": "DataAggregationProof", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.838725757867961 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2r", + "id": "shape:ctUv2m9PAhsAux2o1rq5O", + "typeName": "shape" + }, + { + "x": 1772.7715559618575, + "y": 93.20458385301225, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2v", + "props": {}, + "id": "shape:ZsCAx3EBCL7wivyRyfdvO", + "typeName": "shape" + }, + { + "x": 1416.0496351110496, + "y": -68.40095676097276, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-red", + "size": "l", + "w": 123.4765625, + "text": "Broker", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2u", + "id": "shape:Hr7JTbUpVm76HUKvlBOjb", + "typeName": "shape" + }, + { + "x": 1724.8749527206564, + "y": -75.54812647313987, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "grey", + "size": "l", + "w": 174.1640625, + "text": "Storage\nProviders", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2x", + "id": "shape:2bE9IxLgigJF1vw5-XkjS", + "typeName": "shape" + }, + { + "x": 300.2749373004941, + "y": 183.87511500553495, + "rotation": 0.19198621771937496, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 16.923134725384937, + "text": "S3", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.7706116632890017 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b36V", + "id": "shape:RN57CDm6cCkR4eO0g1fLx", + "typeName": "shape" + }, + { + "x": 294.7421399581603, + "y": 176.396405650824, + "rotation": 0.19198621771937496, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 30.63569842285744, + "h": 30.60457915367307, + "geo": "pentagon", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b36G", + "id": "shape:I7g9AB0n_w8poa9vTH0WC", + "typeName": "shape" + }, + { + "x": 7.447118896666495, + "y": 9.980477980710077, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 19.51811564379471, + "text": "R2", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.6678911916888538 + }, + "parentId": "shape:KJmFeQCPwjiIV_KUa4ePU", + "index": "a1", + "id": "shape:hZfWM6FmOGQRlY-ENrHf_", + "typeName": "shape" + }, + { + "x": 0.813983029111796, + "y": 1.5267047773219815, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 30.452930631178752, + "h": 31.35238866209842, + "geo": "pentagon", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:KJmFeQCPwjiIV_KUa4ePU", + "index": "a2", + "id": "shape:VAVedgHc0yS3OMctA4G8h", + "typeName": "shape" + }, + { + "x": 335.64987374961754, + "y": 185.307548400455, + "rotation": 0.8726646259971647, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b36l", + "props": {}, + "id": "shape:KJmFeQCPwjiIV_KUa4ePU", + "typeName": "shape" + }, + { + "x": 232.50100486081897, + "y": 153.7614077003111, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3BV", + "props": { + "dash": "dotted", + "size": "s", + "fill": "semi", + "color": "light-blue", + "labelColor": "black", + "bend": -28.40759223221309, + "start": { + "type": "binding", + "boundShapeId": "shape:sl_sOlmCGmzm5hkLk54mN", + "normalizedAnchor": { + "x": 0.9876290315103136, + "y": 0.573066437526593 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:I7g9AB0n_w8poa9vTH0WC", + "normalizedAnchor": { + "x": 0.4794890752215548, + "y": 0.06913432986251565 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:2cXxCEUuS6yzpgn-PjcYw", + "typeName": "shape" + }, + { + "x": 242.0241677315165, + "y": 146.8009170846613, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 113.234375, + "text": "Have piece ?", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.45383513322791913 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b39", + "id": "shape:pwizf0OV_qnBvwZg1mavl", + "typeName": "shape" + }, + { + "x": 72.0357584416796, + "y": 50.35795084846396, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:Mk4f3fcL2d7isqddkOs8t", + "index": "a2", + "id": "shape:POGxu-Osjdvukt7In1jG1", + "typeName": "shape" + }, + { + "x": 37.31371765356073, + "y": 50.61553927223835, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 24.18359330727776, + "h": 24.18359330727776, + "geo": "x-box", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:Mk4f3fcL2d7isqddkOs8t", + "index": "a3", + "id": "shape:w2RwV86S_hv0KuAN0K2jL", + "typeName": "shape" + }, + { + "x": 232.50100486081897, + "y": 153.7614077003111, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3B8", + "props": { + "dash": "dotted", + "size": "s", + "fill": "semi", + "color": "light-blue", + "labelColor": "black", + "bend": -27.56696255291565, + "start": { + "type": "binding", + "boundShapeId": "shape:I7g9AB0n_w8poa9vTH0WC", + "normalizedAnchor": { + "x": 0.2476071840580876, + "y": 0.885729661394414 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:POGxu-Osjdvukt7In1jG1", + "normalizedAnchor": { + "x": 0.9374548128116142, + "y": 0.8789543929416722 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:iUV5glQ0iF-yIL77UhNec", + "typeName": "shape" + }, + { + "x": 236.75971756283403, + "y": 179.35848592154468, + "rotation": 0.1745329251994331, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 52.29740793056099, + "text": "issue receipt", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.37360317579776914 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3C", + "id": "shape:6AeV9hHNJ1FFrCta67sak", + "typeName": "shape" + }, + { + "x": 3.8288019706485557, + "y": 158.09947147407837, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 139.3671875, + "text": "NotFoundError", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3D", + "id": "shape:KK4ThgFXzgx4Vnxxw9ygG", + "typeName": "shape" + }, + { + "x": 37.91914771251004, + "y": 244.79815741312885, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2G", + "props": {}, + "id": "shape:O5d5pUw6Mb22cGRnsnFt7", + "typeName": "shape" + }, + { + "x": 196.98740153021868, + "y": 180.87657698435078, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3B4", + "props": { + "dash": "dashed", + "size": "m", + "fill": "semi", + "color": "light-blue", + "labelColor": "black", + "bend": 0, + "start": { + "type": "binding", + "boundShapeId": "shape:POGxu-Osjdvukt7In1jG1", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:bkPEyXqRXraifW5xQMGEa", + "normalizedAnchor": { + "x": 0.5607543561544333, + "y": 0.816484416858504 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:1H2s5gZYuSrl-dmMNXW4y", + "typeName": "shape" + }, + { + "x": 164.46844528686935, + "y": 482.10754930571835, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2lO", + "props": {}, + "id": "shape:cmIXaGXMR2fkB9pPFkuDA", + "typeName": "shape" + }, + { + "x": 239.8461160087665, + "y": 286.34292685837545, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3E", + "props": {}, + "id": "shape:kBQMJdI53P2NtvGuRlntY", + "typeName": "shape" + }, + { + "x": 5.140625, + "y": 5.699916294642861, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "s", + "w": 161.171875, + "text": "filecoin/submit", + "font": "draw", + "align": "middle", + "autoSize": false, + "scale": 0.8303571428571429 + }, + "parentId": "shape:kBQMJdI53P2NtvGuRlntY", + "index": "a1", + "id": "shape:jFRa9rYFZznzS1kCDV_o_", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 147.97265625, + "h": 30.523437500000004, + "geo": "rectangle", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "shape:kBQMJdI53P2NtvGuRlntY", + "index": "a2", + "id": "shape:S0KU_cMjqwTWtinegZdC9", + "typeName": "shape" + }, + { + "x": 196.98740153021868, + "y": 180.87657698435078, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3F", + "props": { + "dash": "dashed", + "size": "m", + "fill": "semi", + "color": "light-blue", + "labelColor": "black", + "bend": 9.994495161364814, + "start": { + "type": "point", + "x": 1.5192195726918953, + "y": 1.7165734183521124 + }, + "end": { + "type": "binding", + "boundShapeId": "shape:S0KU_cMjqwTWtinegZdC9", + "normalizedAnchor": { + "x": 0.26304329906937696, + "y": 0.25172866743297284 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:x9gr25Gt5j0rpsnyOMbbY", + "typeName": "shape" + }, + { + "x": 361.74890993817974, + "y": 300.9080934804685, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3H", + "props": { + "dash": "draw", + "size": "m", + "fill": "semi", + "color": "light-blue", + "labelColor": "black", + "bend": 34.15497773420907, + "start": { + "type": "binding", + "boundShapeId": "shape:QNCpNKmd9fehQt2HHGSgD", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:SSni0MIcFXh_cuHm7H2n-", + "normalizedAnchor": { + "x": 0.13600925596480712, + "y": 0.9611916169936818 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:cZc11ZEl2kUv-OOy_ZAGr", + "typeName": "shape" + }, + { + "x": -54.19854842227306, + "y": 364.3337412656227, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3J", + "props": { + "dash": "dotted", + "size": "s", + "fill": "pattern", + "color": "light-blue", + "labelColor": "black", + "bend": 53.5629748090655, + "start": { + "type": "binding", + "boundShapeId": "shape:vFXtT1VOfhfn04oO_Nqyo", + "normalizedAnchor": { + "x": 0.8712441426605876, + "y": 0.8597866031319065 + }, + "isExact": false + }, + "end": { + "type": "binding", + "boundShapeId": "shape:1fR3s8PjhDLgxlruj__a7", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:K9DwSY3XnT8ailR8UpoYa", + "typeName": "shape" + }, + { + "x": 338.53512559152705, + "y": 329.1432836364356, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 23.07894955423899, + "h": 23.07894955423899, + "geo": "check-box", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3G", + "id": "shape:QNCpNKmd9fehQt2HHGSgD", + "typeName": "shape" + }, + { + "x": 305.98443279283384, + "y": 328.49678285334903, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 24.18359330727776, + "h": 24.18359330727776, + "geo": "x-box", + "color": "light-blue", + "labelColor": "black", + "fill": "none", + "dash": "draw", + "size": "m", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3I", + "id": "shape:1fR3s8PjhDLgxlruj__a7", + "typeName": "shape" + }, + { + "x": 239.6116228859265, + "y": 221.77172516346457, + "rotation": 1.0122909661567112, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "m", + "w": 38.42329702112139, + "text": "fx.fork", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3K", + "id": "shape:3f-oawqLI8BKd5VUciBXw", + "typeName": "shape" + }, + { + "x": 314.70669887313204, + "y": 354.65141145747805, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "arrow", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2lV", + "props": { + "dash": "dotted", + "size": "s", + "fill": "semi", + "color": "light-blue", + "labelColor": "black", + "bend": -39.64146167065855, + "start": { + "type": "point", + "x": 0, + "y": 0 + }, + "end": { + "type": "binding", + "boundShapeId": "shape:78KGZzPOrKclANdpzFqQs", + "normalizedAnchor": { + "x": 0.5, + "y": 0.5 + }, + "isExact": false + }, + "arrowheadStart": "none", + "arrowheadEnd": "arrow", + "text": "", + "font": "draw" + }, + "id": "shape:eqCts3KSm1xYaJNH_kWHR", + "typeName": "shape" + }, + { + "x": 89.03881481408766, + "y": 436.32670728285666, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2lG", + "props": {}, + "id": "shape:QPlv0N-DGw4Qb_d_XKklD", + "typeName": "shape" + }, + { + "x": 398.40697676036933, + "y": 323.8809690588092, + "rotation": 5.742133239061344, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "text", + "props": { + "color": "light-blue", + "size": "m", + "w": 35.42888303748985, + "text": "fx.join", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 0.4815138064131132 + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3L", + "id": "shape:liAQQ6TPqZHwefNSizmYV", + "typeName": "shape" + }, + { + "x": 0, + "y": 0, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "shape:x95YNgCI7orU9q-QzNEfP", + "index": "a1", + "props": {}, + "id": "shape:Jigpp2ApvivD6nepjJ_ON", + "typeName": "shape" + }, + { + "x": 974.173006998417, + "y": 101.67910627037338, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2f", + "props": {}, + "id": "shape:x95YNgCI7orU9q-QzNEfP", + "typeName": "shape" + }, + { + "x": 114.9140625, + "y": 109.15625, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "group", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b3B", + "props": {}, + "id": "shape:Mk4f3fcL2d7isqddkOs8t", + "typeName": "shape" + } + ] +} \ No newline at end of file From f8a0b2e3198717d9ac24ca4873a2c6739538c5d8 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 10:45:23 -0700 Subject: [PATCH 10/17] touchup svgs --- w3-filecoin/aggregator.svg | 5 +- w3-filecoin/deal-tracker.svg | 5 +- w3-filecoin/dealer.svg | 7 +- w3-filecoin/storefront.svg | 9 +- w3-filecoin/workflow.tldr | 207 ++++++++++++++++------------------- 5 files changed, 117 insertions(+), 116 deletions(-) diff --git a/w3-filecoin/aggregator.svg b/w3-filecoin/aggregator.svg index b74c557..bad86e8 100644 --- a/w3-filecoin/aggregator.svg +++ b/w3-filecoin/aggregator.svg @@ -8,10 +8,13 @@ piece/offerpiece/offerPut piece into PieceQueuePut piece into PieceQueuepiece/acceptpiece/acceptAccumulate pieces into groupsAccumulate pieces into groupsfx.joinfx.joinfx.joinfx.joinooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooPiece QueuePiece QueueooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooPiece set storePiece set storeooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooCreate AggregatesCreate AggregatesIssue receipt with inclusion proofIssue receipt with inclusion proofInclusionProofInclusionProofAggregatorAggregatorDealerDealeraggregate/offeraggregate/offer \ No newline at end of file +}piece/offerpiece/offerPut piece into PieceQueuePut piece into PieceQueuepiece/acceptpiece/acceptAccumulate pieces into groupsAccumulate pieces into groupsfx.joinfx.joinfx.joinfx.joinooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooPiece QueuePiece QueueooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooPiece set storePiece set storeooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooCreate AggregatesCreate AggregatesIssue receipt with inclusion proofIssue receipt with inclusion proofInclusionProofInclusionProofAggregatorAggregatorDealerDealeraggregate/offeraggregate/offer diff --git a/w3-filecoin/deal-tracker.svg b/w3-filecoin/deal-tracker.svg index 37ef3a6..034b00b 100644 --- a/w3-filecoin/deal-tracker.svg +++ b/w3-filecoin/deal-tracker.svg @@ -8,10 +8,13 @@ fx.joinfx.joinpoll  aggregate deal infopoll  aggregate deal infoDataAggregationProofDataAggregationProofPublish aggregatesPublish aggregatesDealerDealerdeal/infodeal/infoDeal TrakerDeal Trakeraggregate/acceptaggregate/acceptaggregate/offeraggregate/offerissue receiptissue receiptCRONCRONDataAggregationProofDataAggregationProof \ No newline at end of file +}fx.joinfx.joinpoll  aggregate deal infopoll  aggregate deal infoDataAggregationProofDataAggregationProofDealerDealerdeal/infodeal/infoDeal TrakerDeal Trakeraggregate/acceptaggregate/acceptaggregate/offeraggregate/offerissue receiptissue receiptCRONCRONDataAggregationProofDataAggregationProof diff --git a/w3-filecoin/dealer.svg b/w3-filecoin/dealer.svg index 84a8af9..5791265 100644 --- a/w3-filecoin/dealer.svg +++ b/w3-filecoin/dealer.svg @@ -1,4 +1,4 @@ - + @@ -8,10 +8,13 @@ fx.joinfx.joinpoll  aggregate deal infopoll  aggregate deal infoDataAggregationProofDataAggregationProofPublish aggregatesPublish aggregatesDealerDealerdeal/infodeal/infoDeal TrakerDeal Trakeraggregate/acceptaggregate/acceptaggregate/offeraggregate/offerissue receiptissue receiptCRONCRONDataAggregationProofDataAggregationProof \ No newline at end of file +}piece/offerpiece/offerfx.joinfx.joinpoll  aggregate deal infopoll  aggregate deal inforetry on errorretry on errorDataAggregationProofDataAggregationProofPublish aggregatesPublish aggregatesAggregatorAggregatorDealerDealerdeal/infodeal/infoDeal TrakerDeal Trakerfx.joinfx.joinaggregate/acceptaggregate/acceptaggregate/offeraggregate/offerissue receiptissue receiptCRONCRONDataAggregationProofDataAggregationProof|||||||||||||||||||||||| diff --git a/w3-filecoin/storefront.svg b/w3-filecoin/storefront.svg index c1cfefb..59f1da4 100644 --- a/w3-filecoin/storefront.svg +++ b/w3-filecoin/storefront.svg @@ -8,10 +8,17 @@ piece/offerpiece/offerfx.joinfx.joinStorefrontStorefrontAggregatorAggregatorooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooEnqueue for validationEnqueue for validationfilecoin/accepetfilecoin/accepetDataAggregationProofDataAggregationProofS3S3R2R2Have piece ?Have piece ?filecoin/offerfilecoin/offerissue receiptissue receiptNotFoundErrorNotFoundErrorfilecoin/submitfilecoin/submitfx.forkfx.forkfx.joinfx.join \ No newline at end of file +} +[stroke="#212529"] { + display: none; +} +piece/offerpiece/offerfx.joinfx.joinStorefrontStorefrontAggregatorAggregatorooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooEnqueue for validationEnqueue for validationfilecoin/accepetfilecoin/accepetDataAggregationProofDataAggregationProofS3S3R2R2Have piece ?Have piece ?filecoin/offerfilecoin/offerissue receiptissue receiptNotFoundErrorNotFoundErrorfilecoin/submitfilecoin/submitfx.forkfx.forkfx.joinfx.join diff --git a/w3-filecoin/workflow.tldr b/w3-filecoin/workflow.tldr index 14c5614..8c6c9b1 100644 --- a/w3-filecoin/workflow.tldr +++ b/w3-filecoin/workflow.tldr @@ -66,9 +66,9 @@ { "id": "pointer:pointer", "typeName": "pointer", - "x": 1141.039491751153, - "y": 680.0742666425292, - "lastActivityTimestamp": 1695141718721, + "x": 1218.7447767049023, + "y": 488.97326557525315, + "lastActivityTimestamp": 1695145224939, "meta": {} }, { @@ -79,9 +79,9 @@ "typeName": "page" }, { - "x": -604.9989794535514, - "y": -89.72422461101107, - "z": 0.8881383292456979, + "x": -840.7212266329193, + "y": -272.67435305454455, + "z": 2.0057240808294137, "meta": {}, "id": "camera:page:uQnL6FrXKA8qFUFS7ZQBe", "typeName": "camera" @@ -103,8 +103,8 @@ "followingUserId": null, "opacityForNextShape": 1, "stylesForNextShape": { - "tldraw:font": "draw", - "tldraw:size": "s", + "tldraw:font": "serif", + "tldraw:size": "xl", "tldraw:geo": "ellipse", "tldraw:dash": "dashed", "tldraw:fill": "none", @@ -126,7 +126,7 @@ "screenBounds": { "x": 0, "y": 0, - "w": 613, + "w": 1226, "h": 805 }, "zoomBrush": null, @@ -377,8 +377,8 @@ "typeName": "shape" }, { - "x": 1.048889558678752, - "y": 4.556788813722676, + "x": 550.6113895586788, + "y": 454.55256516350886, "rotation": 0, "isLocked": false, "opacity": 1, @@ -394,14 +394,14 @@ "autoSize": false, "scale": 0.7949880632388084 }, - "parentId": "shape:6On9x8eTbP6rL2HnmYhX5", - "index": "a1", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aFV", "id": "shape:5Lt66Ml1iYp0BoXCaPLTq", "typeName": "shape" }, { - "x": 0, - "y": 0, + "x": 549.5625, + "y": 449.9957763497862, "rotation": 0, "isLocked": false, "opacity": 1, @@ -423,8 +423,8 @@ "growY": 0, "url": "" }, - "parentId": "shape:6On9x8eTbP6rL2HnmYhX5", - "index": "a2", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "aG", "id": "shape:L7bbjqDsz6BBVYXPr2264", "typeName": "shape" }, @@ -471,20 +471,6 @@ "id": "shape:eD_gf3NnfwaceqK4mKb2x", "typeName": "shape" }, - { - "x": 549.5625, - "y": 449.9957763497862, - "rotation": 0, - "isLocked": false, - "opacity": 1, - "meta": {}, - "type": "group", - "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "aF", - "props": {}, - "id": "shape:6On9x8eTbP6rL2HnmYhX5", - "typeName": "shape" - }, { "x": 718.9123057476287, "y": 135.78496649098253, @@ -614,7 +600,7 @@ "meta": {}, "type": "arrow", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2fV", + "index": "b2f6", "props": { "dash": "draw", "size": "m", @@ -3249,7 +3235,7 @@ "geo": "rectangle", "color": "yellow", "labelColor": "black", - "fill": "pattern", + "fill": "none", "dash": "draw", "size": "s", "font": "draw", @@ -3278,7 +3264,7 @@ "geo": "rectangle", "color": "yellow", "labelColor": "black", - "fill": "semi", + "fill": "none", "dash": "draw", "size": "m", "font": "draw", @@ -3368,7 +3354,7 @@ "meta": {}, "type": "arrow", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2fG", + "index": "b2f5", "props": { "dash": "dotted", "size": "s", @@ -3505,7 +3491,7 @@ "geo": "hexagon", "color": "grey", "labelColor": "black", - "fill": "solid", + "fill": "none", "dash": "solid", "size": "s", "font": "draw", @@ -3534,7 +3520,7 @@ "geo": "hexagon", "color": "light-red", "labelColor": "black", - "fill": "solid", + "fill": "none", "dash": "draw", "size": "s", "font": "draw", @@ -3563,7 +3549,7 @@ "geo": "hexagon", "color": "grey", "labelColor": "black", - "fill": "solid", + "fill": "none", "dash": "solid", "size": "s", "font": "draw", @@ -3592,7 +3578,7 @@ "geo": "hexagon", "color": "grey", "labelColor": "black", - "fill": "solid", + "fill": "none", "dash": "solid", "size": "s", "font": "draw", @@ -3682,7 +3668,7 @@ "meta": {}, "type": "arrow", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2n", + "index": "b2m4", "props": { "dash": "dotted", "size": "s", @@ -3748,18 +3734,22 @@ "meta": {}, "type": "arrow", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2ZV", + "index": "b2m3G", "props": { "dash": "dotted", "size": "s", "fill": "semi", "color": "yellow", "labelColor": "black", - "bend": -83.3457304897702, + "bend": -68.65388248884989, "start": { - "type": "point", - "x": -216.3874620720544, - "y": -152.47618927262158 + "type": "binding", + "boundShapeId": "shape:tD1Gx--iMBrDlKaECYVeh", + "normalizedAnchor": { + "x": 0.651478388742536, + "y": 0.9266260055931591 + }, + "isExact": false }, "end": { "type": "binding", @@ -3991,7 +3981,7 @@ "meta": {}, "type": "arrow", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2mV", + "index": "b2m3V", "props": { "dash": "dotted", "size": "s", @@ -4025,35 +4015,6 @@ "id": "shape:En4TS48hSq3AdodR47DLW", "typeName": "shape" }, - { - "x": 0, - "y": 0, - "rotation": 0, - "isLocked": false, - "opacity": 1, - "meta": {}, - "type": "geo", - "props": { - "w": 56.741802693501995, - "h": 56.741802693501995, - "geo": "ellipse", - "color": "yellow", - "labelColor": "black", - "fill": "semi", - "dash": "dashed", - "size": "s", - "font": "draw", - "text": "", - "align": "middle", - "verticalAlign": "middle", - "growY": 0, - "url": "" - }, - "parentId": "shape:mSB_hgO9Tfwd5C9SjuUgv", - "index": "a1", - "id": "shape:tD1Gx--iMBrDlKaECYVeh", - "typeName": "shape" - }, { "x": 0, "y": 3.570808649920366, @@ -4500,8 +4461,8 @@ "typeName": "shape" }, { - "x": 9.919504509739, - "y": 19.470225993011013, + "x": 1060.2444667915022, + "y": 341.4441953260616, "rotation": 0, "isLocked": false, "opacity": 1, @@ -4517,8 +4478,8 @@ "autoSize": true, "scale": 0.7454581250462784 }, - "parentId": "shape:mSB_hgO9Tfwd5C9SjuUgv", - "index": "a2", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2m5", "id": "shape:X0-fKdQH_wlKtY4bJgMyD", "typeName": "shape" }, @@ -4685,8 +4646,8 @@ "typeName": "shape" }, { - "x": 51.604842546490204, - "y": 36.827345295980535, + "x": 1025.7778495449072, + "y": 138.50645156635392, "rotation": 0, "isLocked": false, "opacity": 1, @@ -4708,23 +4669,9 @@ "growY": 0, "url": "" }, - "parentId": "shape:x95YNgCI7orU9q-QzNEfP", - "index": "a2", - "id": "shape:tlIEUmtxUNOSkrdY9qm7D", - "typeName": "shape" - }, - { - "x": 1008.1098461502431, - "y": 318.4041082946175, - "rotation": 0, - "isLocked": false, - "opacity": 1, - "meta": {}, - "type": "group", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2m", - "props": {}, - "id": "shape:mSB_hgO9Tfwd5C9SjuUgv", + "index": "b2f8", + "id": "shape:tlIEUmtxUNOSkrdY9qm7D", "typeName": "shape" }, { @@ -5746,45 +5693,83 @@ "typeName": "shape" }, { - "x": 0, - "y": 0, + "x": 974.173006998417, + "y": 101.67910627037338, "rotation": 0, "isLocked": false, "opacity": 1, "meta": {}, "type": "group", - "parentId": "shape:x95YNgCI7orU9q-QzNEfP", - "index": "a1", + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2f4", "props": {}, "id": "shape:Jigpp2ApvivD6nepjJ_ON", "typeName": "shape" }, { - "x": 974.173006998417, - "y": 101.67910627037338, + "x": 114.9140625, + "y": 109.15625, "rotation": 0, "isLocked": false, "opacity": 1, "meta": {}, "type": "group", "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b2f", + "index": "b3B", "props": {}, - "id": "shape:x95YNgCI7orU9q-QzNEfP", + "id": "shape:Mk4f3fcL2d7isqddkOs8t", "typeName": "shape" }, { - "x": 114.9140625, - "y": 109.15625, + "x": 1058.9434029839306, + "y": 243.9497130154686, "rotation": 0, "isLocked": false, "opacity": 1, "meta": {}, - "type": "group", + "id": "shape:B-2r67LUy5Ow-mqY9SBa2", + "type": "text", + "props": { + "color": "yellow", + "size": "s", + "w": 69.90625, + "text": "||||||||||||", + "font": "draw", + "align": "middle", + "autoSize": true, + "scale": 1 + }, "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", - "index": "b3B", - "props": {}, - "id": "shape:Mk4f3fcL2d7isqddkOs8t", + "index": "b3N", + "typeName": "shape" + }, + { + "x": 1052.1420273929787, + "y": 321.94086096553656, + "rotation": 0, + "isLocked": false, + "opacity": 1, + "meta": {}, + "type": "geo", + "props": { + "w": 56.741802693501995, + "h": 56.741802693501995, + "geo": "ellipse", + "color": "yellow", + "labelColor": "black", + "fill": "none", + "dash": "dashed", + "size": "s", + "font": "draw", + "text": "", + "align": "middle", + "verticalAlign": "middle", + "growY": 0, + "url": "" + }, + "parentId": "page:uQnL6FrXKA8qFUFS7ZQBe", + "index": "b2m3", + "id": "shape:tD1Gx--iMBrDlKaECYVeh", "typeName": "shape" } ] From d5b491491ce0c1f8eea189ce8a37307c9ca8660c Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 11:05:42 -0700 Subject: [PATCH 11/17] update github action --- .github/workflows/spellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index a16cbfd..4388d50 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: matheus23/md-spellcheck-action@v4.1.0 + - uses: matheus23/md-spellcheck-action@v4.2.2 with: files-to-check: '**/*.md' files-to-exclude: | From d4b5ce489581789cd167a1106fd9ad1c4bebdacb Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 11:08:52 -0700 Subject: [PATCH 12/17] fix grammar errors --- w3-filecoin.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index a166d49..079846a 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -76,10 +76,9 @@ A _Storefront_ facilitates data storage services to applications and users, gett ### Aggregator -An _Aggregator_ is a type of [principal] identified by a DID. It is RECOMMENDED to use use [`did:key`] identifier due to their stateless nature. +An _Aggregator_ is a type of [principal] identified by a DID. It is RECOMMENDED to use [`did:key`] identifier due to their stateless nature. -An _Aggregator_ facilitates data storage into Filecoin deals by aggregating smaller data (Filecoin Pieces) into a larger piece that can effectively be stored with a Filecoin Storage Provider using [Verifiable Data Aggregation -](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md). +An _Aggregator_ facilitates data storage into Filecoin deals by aggregating smaller data (Filecoin Pieces) into a larger piece that can effectively be stored with a Filecoin Storage Provider using [Verifiable Data Aggregation](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md). ### Dealer @@ -103,7 +102,7 @@ For example, an [Aggregator] can authorize invocations from `did:web:web3.storag ### _Storefront_ receives a Filecoin piece -A [Storefront] MUST submit content for aggregation by it's piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the [Storefront] itself. A [Storefront] MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a [Storefront] client or delegated to a hired third party, ether way a [Storefront] MUST acknowledge request by issuing a signed receipt. A [Storefront] MAY decide to verify submitted piece prior to aggregation. A [Storefront] MAY also operate trusted actor that computes and submits pieces on content upload. +A [Storefront] MUST submit content for aggregation by its piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the [Storefront] itself. A [Storefront] MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a [Storefront] client or delegated to a hired third party, ether way a [Storefront] MUST acknowledge request by issuing a signed receipt. A [Storefront] MAY decide to verify submitted piece prior to aggregation. A [Storefront] MAY also operate trusted actor that computes and submits pieces on content upload. Once a [Storefront] receives the offer for a piece, it is pending for verification. The [Storefront] MUST issue a receipt proving that request state has transition from `uninitialized` to `pending` if result was `ok`, or to `failed` if result was `error`. The [Storefront] MAY fail invocation if piece `content` has not been provided. @@ -113,9 +112,9 @@ A successful invocation receipt MUST have `fx.join` [effect] that links to the t #### `filecoin/submit` effect -Successful invocation receipt MUST have an `fx.fork` [effect] that links to the next task of the workflow. It allows the observer to follow progress of the execution. +Successful invocation receipt MUST have a `fx.fork` [effect] that links to the next task of the workflow. It allows the observer to follow progress of the execution. -The [Storefront] MUST issue a receipt for the linked [`filecoin/submit`] task after it verifies the offered piece and queues it for aggregation. This receipt MUST have an `fx.join` [effect] that links to a [`piece/offer`] task that forwards the submitted piece to the [Aggregator]. +The [Storefront] MUST issue a receipt for the linked [`filecoin/submit`] task after it verifies the offered piece and queues it for aggregation. This receipt MUST have a `fx.join` [effect] that links to a [`piece/offer`] task that forwards the submitted piece to the [Aggregator]. ![storefront flow](./w3-filecoin/storefront.svg) @@ -123,7 +122,7 @@ The [Storefront] MUST issue a receipt for the linked [`filecoin/submit`] task af A [Storefront] SHOULD propagate offered pieces to Filecoin Storage Providers by forwarding them to an [Aggregator]. -The [Aggregator] MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have an `fx.join` [effect] that links to a [`piece/accept`] task, which either succeeds with an (aggregate) inclusion proof or fails. +The [Aggregator] MUST queue offered pieces for an aggregation and issue a signed receipt proving that the piece is being `pending` to be added. The issued receipt MUST have a `fx.join` [effect] that links to a [`piece/accept`] task, which either succeeds with an (aggregate) inclusion proof or fails. If the [Storefront] offers a piece multiple times, the [Aggregator] MUST respond with a receipt that contains the _same_ result and effect(s). @@ -131,7 +130,7 @@ If the [Storefront] offers a piece multiple times, the [Aggregator] MUST respond The same Piece submitted by different [Storefront]s SHOULD NOT be considered a duplicate. -After an [Aggregator] includes a piece in an aggregate it MUST issue a [`piece/accept`] receipt with a piece inclusion proof as the result. The receipt MUST have an `fx.join` [effect] that links to an [`aggregate/offer`] task for the aggregate where piece was included. +After an [Aggregator] includes a piece in an aggregate it MUST issue a [`piece/accept`] receipt with a piece inclusion proof as the result. The receipt MUST have a `fx.join` [effect] that links to an [`aggregate/offer`] task for the aggregate where piece was included. ![aggregator flow](./w3-filecoin/aggregator.svg) @@ -143,9 +142,9 @@ If a [Dealer] receives a request with an aggregate multiple times it MUST (re)is > ℹ️ An invocation nonce MAY be used to force an aggregate to be reprocessed. -The issued receipt MUST have an `fx.join` [effect] linking to an [`aggregate/accept`] task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if a Storage Provider failed to replicate and reported an error). +The issued receipt MUST have a `fx.join` [effect] linking to an [`aggregate/accept`] task which either succeeds with filecoin [`DataAggregationProof`] result or fails (e.g. if a Storage Provider failed to replicate and reported an error). -The [Dealer] MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the [`aggregate/accept`] task with a succeed or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. +The [Dealer] MUST broker deal(s) with Filecoin Storage Providers (out of band). It MUST issue a receipt for the [`aggregate/accept`] task with a successful or failed result depending on the availability of Storage Providers and their ability to replicate content pieces in the aggregate. A successful task MUST have a [`DataAggregationProof`] as it's result and contain no [effect]s. A failed task MUST provide an error reason. When pieces of the aggregate can be retried, the issued receipt MUST contain `fx.fork` [effect]s with [`piece/offer`] tasks per piece. > Note: The [Dealer] MAY have several intermediate steps and states it transitions through, however those are _not_ captured by this protocol intentionally, because the other actor take no action until a success / failure condition is met. @@ -156,7 +155,7 @@ A failed task MUST provide an error reason. When pieces of the aggregate can be [Storefront] users MAY want to check status of the deals for their content. Deals change over time as they get renewed. Therefore, the [Storefront] MAY invoke [`deal/info`] capability to gather information about an aggregate. The [Storefront] SHOULD be able to look up an aggregate from received inclusion proofs and use them to look up deal status information. -The [Dealer] MAY also use a [Deal Tracker] to poll for status of the the aggregates to obtain proof that deals have made it onto a chain and to issue [`aggregate/accept`] receipts when they do. +The [Dealer] MAY also use a [Deal Tracker] to poll for status of the aggregates to obtain proof that deals have made it onto a chain and to issue [`aggregate/accept`] receipts when they do. ![dealer tracker flow](./w3-filecoin/deal-tracker.svg) @@ -164,7 +163,7 @@ The [Dealer] MAY also use a [Deal Tracker] to poll for status of the the aggrega This section describes the set of capabilities that form the w3 filecoin protocol, along with the details relevant for invoking them with a service provider. -In this document, we will be exposing capabilities implemented by [Storefront] `web3.storage`, [Aggregator] `aggregator.web3.storage`, [Dealer] `dealer.web3.storage` and [Deal Tracker] `tracker.web3.storage`. +In this document, we describe capabilities provided by [Storefront] `web3.storage`, [Aggregator] `aggregator.web3.storage`, [Dealer] `dealer.web3.storage` and [Deal Tracker] `tracker.web3.storage`. ### _Storefront_ Capabilities @@ -215,11 +214,11 @@ Alternatively, the [Storefront] MAY choose to queue request until linked `conten ##### Effects -The issued receipt MUST have an `fx.join` [effect] that links to the [`filecoin/accept`] task. The [Storefront] MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. +The issued receipt MUST have a `fx.join` [effect] that links to the [`filecoin/accept`] task. The [Storefront] MUST issue the receipt for this task once the content piece is aggregated and the deal is published to the filecoin chain. > This allows an agent to get a result without having to follow progress across the entire invocation chain. -The issued receipt MUST have an `fx.fork` [effect] that links to the [`filecoin/submit`] task. The [Storefront] MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). +The issued receipt MUST have a `fx.fork` [effect] that links to the [`filecoin/submit`] task. The [Storefront] MUST issue a receipt for this task once it has processed the request and queued it for aggregation, or failed with an error (implying a problem with the piece or content). > This allows an agent to follow progress across the entire invocation chain. @@ -315,7 +314,7 @@ The task MUST be invoked by the [Storefront] which MAY be used to verify the off } ``` -A [Storefront] MUST issue a signed receipt that either succeeds and links to the [`piece/offer`] task via an `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). +A [Storefront] MUST issue a signed receipt that either succeeds and links to the [`piece/offer`] task via a `fx.join` [effect] or fails with specified reason (e.g. the `content` does not correspond to the provided `piece`). ```json { @@ -385,7 +384,7 @@ A [Storefront] can invoke a capability to offer a piece to be aggregated for upc } ``` -An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] with an [`piece/accept`] task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. +An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain a `fx.join` [effect] linking to [`piece/accept`] task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. ```json { From 9bb16f2c58b12d3cda9af3e5179b16bfd148fb88 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 11:17:30 -0700 Subject: [PATCH 13/17] ignore more words --- .github/workflows/words-to-ignore.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt index 9d552c6..370ef8d 100644 --- a/.github/workflows/words-to-ignore.txt +++ b/.github/workflows/words-to-ignore.txt @@ -122,3 +122,14 @@ deduplicated AggregatorPrincipal w3filecoin DealerPrincipal +ipld +dag-ucan +markdownlint +markdownlint-cli +vscode-markdownlint +md-spellcheck-action +github +txt +Irakli +Gozalishvili +Vasco From f3f5423baa071e9c66d849b33da0bc8e0efcbc69 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 11:18:45 -0700 Subject: [PATCH 14/17] revert spellchecker upgrade --- .github/workflows/spellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index 4388d50..a16cbfd 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: matheus23/md-spellcheck-action@v4.2.2 + - uses: matheus23/md-spellcheck-action@v4.1.0 with: files-to-check: '**/*.md' files-to-exclude: | From 151e602b596fcc51cb98efa211ae5da63b155814 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Tue, 19 Sep 2023 11:22:27 -0700 Subject: [PATCH 15/17] ignore more words --- .github/workflows/words-to-ignore.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/words-to-ignore.txt b/.github/workflows/words-to-ignore.txt index 370ef8d..3c54472 100644 --- a/.github/workflows/words-to-ignore.txt +++ b/.github/workflows/words-to-ignore.txt @@ -133,3 +133,4 @@ txt Irakli Gozalishvili Vasco +invoker From eb95739be992a211bdb889fec867a5e00bdd2191 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Wed, 20 Sep 2023 11:48:13 -0700 Subject: [PATCH 16/17] Apply suggestions from code review Co-authored-by: Vasco Santos Co-authored-by: Alan Shaw --- w3-filecoin.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index 079846a..6d05826 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -104,7 +104,7 @@ For example, an [Aggregator] can authorize invocations from `did:web:web3.storag A [Storefront] MUST submit content for aggregation by its piece CID. It MAY be computed from content by a trusted actor or it MAY be computed by the [Storefront] itself. A [Storefront] MUST provide a capability that can be used to submit a piece to be replicated by (Filecoin) Storage Providers. It may be invoked by a [Storefront] client or delegated to a hired third party, ether way a [Storefront] MUST acknowledge request by issuing a signed receipt. A [Storefront] MAY decide to verify submitted piece prior to aggregation. A [Storefront] MAY also operate trusted actor that computes and submits pieces on content upload. -Once a [Storefront] receives the offer for a piece, it is pending for verification. The [Storefront] MUST issue a receipt proving that request state has transition from `uninitialized` to `pending` if result was `ok`, or to `failed` if result was `error`. The [Storefront] MAY fail invocation if piece `content` has not been provided. +Once a [Storefront] receives the offer for a piece, it is pending for verification. The [Storefront] MUST issue a receipt proving that request state has transitioned from `uninitialized` to `pending` if result was `ok`, or to `failed` if result was `error`. The [Storefront] MAY fail invocation if piece `content` has not been provided. #### `filecoin/accept` effect @@ -241,7 +241,7 @@ The issued receipt MUST have a `fx.fork` [effect] that links to the [`filecoin/s #### `filecoin/accept` -This task is effectively a shortcut allowing an observer to find out the result of the [`filecoin/offer`] task chain without having to follow each step. The [Storefront] MUST issue a signed receipt with an [`DataAggregationProof`] result or an error. +This task is effectively a shortcut allowing an observer to find out the result of the [`filecoin/offer`] task chain without having to follow each step. The [Storefront] MUST issue a signed receipt with a [`DataAggregationProof`] result or an error. ##### Filecoin Accept Failure @@ -334,7 +334,7 @@ A [Storefront] MUST issue a signed receipt that either succeeds and links to the } ``` -See the [`piece/offer`] section to see the subsequent task. +See the [`piece/offer`] section for the subsequent task. If the added piece is invalid, the reason for the failure is also reported: ```json @@ -384,7 +384,7 @@ A [Storefront] can invoke a capability to offer a piece to be aggregated for upc } ``` -An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain a `fx.join` [effect] linking to [`piece/accept`] task that MUST either succeed with [`InclusionProof`] or fail with an error describing the reason. +An [Aggregator] MUST issue a signed receipt to acknowledge the received request. The receipt MUST contain an `fx.join` [effect] linking to [`piece/accept`] task that MUST either succeed with an [`InclusionProof`] or fail with an error describing the reason. ```json { @@ -408,7 +408,7 @@ See the [`piece/accept`] section for the subsequent task. #### `piece/accept` -An [Aggregator] MUST issue a receipt for the [`piece/accept`] task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and `fx.join` [effect] linking to [`aggregate/offer`] task, or an error detailing the reason. +An [Aggregator] MUST issue a receipt for the [`piece/accept`] task for the offered piece that was included in an aggregate. The receipt MUST contain an [`InclusionProof`] in the result and an `fx.join` [effect] linking to [`aggregate/offer`] task, or an error detailing the reason. > It is RECOMMENDED to never fail [`piece/accept`] as piece inclusion is a deterministic computation occurring on validated data. @@ -433,6 +433,8 @@ An [Aggregator] MUST issue a receipt for the [`piece/accept`] task for the offer } } } + "fx": { + "join": { "/": "bafy...aggregateOffer" } }, "meta": {}, "iss": "did:web:aggregator.web3.storage", @@ -444,7 +446,7 @@ An [Aggregator] MUST issue a receipt for the [`piece/accept`] task for the offer #### `aggregate/offer` -An [Aggregator] can offer an aggregate for Filecoin deal inclusion by invoking a [`aggregate/offer`] capability. See [schema](#aggregateoffer-schema). +An [Aggregator] can offer an aggregate for Filecoin deal inclusion by invoking an [`aggregate/offer`] capability. See [schema](#aggregateoffer-schema). > `did:web:aggregator.web3.storage` invokes capability from `did:web:dealer.web3.storage` @@ -474,7 +476,7 @@ Invoking the [`aggregate/offer`] capability is a request to arrange Filecoin dea The `nb.aggregate` field represents a commitment proof for the `aggregate` to arrange a deal(s) for. -The `nb.pieces` field represents a link to DAG-CBOR encoded list of pieces of an `aggregate`. The elements of the `nb.pieces` field MUST be sorted in the _same_ order as they were used to compute the aggregate piece CID. This block MUST be included with the invocation. Its format is: +The `nb.pieces` field represents a link to a DAG-CBOR encoded list of pieces of an `aggregate`. The elements of the `nb.pieces` field MUST be sorted in the _same_ order as they were used to compute the aggregate piece CID. This block MUST be included with the invocation. Its format is: ```json /* offers block as an array of piece CIDs, encoded as DAG-JSON (for readability) */ From d00ad7721ff222f298184a3c0f6fe04ec91ab160 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Wed, 20 Sep 2023 11:50:58 -0700 Subject: [PATCH 17/17] Use type aliases instead of duplicates --- w3-filecoin.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/w3-filecoin.md b/w3-filecoin.md index 6d05826..700a609 100644 --- a/w3-filecoin.md +++ b/w3-filecoin.md @@ -777,12 +777,7 @@ type PieceAccept struct { nb PieceAcceptDetail } -type PieceAcceptDetail struct { - # Piece as Filecoin Piece with padding - piece PieceLink - # Grouping for joining segments into an aggregate (subset of space) - group string -} +type PieceAcceptDetail = PieceOfferDetail ``` ### `aggregate/offer` schema @@ -809,12 +804,7 @@ type AggregateAccept struct { nb AggregateAcceptDetail } -type AggregateAcceptDetail struct { - # Contains each individual piece within Aggregate piece - pieces &AggregatePieces - # Piece as Aggregate of CARs with padding - aggregate PieceLink -} +type AggregateAcceptDetail = AggregateOfferDetail ``` ### `deal/info` schema