Skip to content

Commit

Permalink
draft: deal/sign capability
Browse files Browse the repository at this point in the history
  • Loading branch information
Gozala committed Aug 30, 2023
1 parent 77e4d7d commit b2e8e57
Show file tree
Hide file tree
Showing 10 changed files with 1,922 additions and 1,520 deletions.
4 changes: 2 additions & 2 deletions packages/access-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"@ipld/car": "^5.1.1",
"@ipld/dag-ucan": "^3.3.2",
"@ucanto/client": "^8.0.0",
"@ucanto/core": "^8.0.0",
"@ucanto/core": "^8.1.0",
"@ucanto/interface": "^8.0.0",
"@ucanto/principal": "^8.0.0",
"@ucanto/transport": "^8.0.0",
Expand Down Expand Up @@ -92,7 +92,7 @@
"@types/sinon": "^10.0.13",
"@types/varint": "^6.0.1",
"@types/ws": "^8.5.4",
"@ucanto/server": "^8.0.1",
"@ucanto/server": "^8.0.2",
"assert": "^2.0.0",
"hd-scripts": "^4.0.0",
"mocha": "^10.2.0",
Expand Down
5 changes: 3 additions & 2 deletions packages/capabilities/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"dist/src/**/*.d.ts.map"
],
"dependencies": {
"@ucanto/core": "^8.0.0",
"@ucanto/core": "^8.1.0",
"@ucanto/interface": "^8.0.0",
"@ucanto/principal": "^8.0.0",
"@ucanto/transport": "^8.0.0",
Expand All @@ -72,7 +72,8 @@
"playwright-test": "^8.1.2",
"type-fest": "^3.3.0",
"typescript": "4.9.5",
"watch": "^1.0.2"
"watch": "^1.0.2",
"multiformats": "^12.1.0"
},
"eslintConfig": {
"extends": [
Expand Down
239 changes: 239 additions & 0 deletions packages/capabilities/src/deal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/**
* Deal signing capabilities used for signing filecoin deals.
*
* @see https://github.com/web3-storage/specs/blob/feat/w3-deal/w3-deal.md
*
* These can be imported directly with:
* ```js
* import * as Filecoin from '@web3-storage/capabilities/deal'
* ```
*
* @module
*/

import { capability, Schema, ok } from '@ucanto/validator'
import * as API from '@ucanto/interface'
import { equal, equalWith, checkLink, and } from './utils.js'

/**
* Payload size after 0-padding.
*
* @see https://github.com/filecoin-project/go-state-types/blob/ff2ed169ff566458f2acd8b135d62e8ca27e7d0c/abi/piece.go#L12
*/
export const PaddedPieceSize = Schema.uint64()

/**
* @see https://github.com/ipfs/go-cid/blob/829c826f6be23320846f4b7318aee4d17bf8e094/cid.go#L104
* @type {API.MulticodecCode<0xf101, 'fil-commitment-unsealed'>}
*/
export const FilCommitmentUnsealed = 0xf101

/**
* @see https://github.com/multiformats/go-multihash/blob/dc3bd6897fcd17f6acd8d4d6ffd2cea3d4d3ebeb/multihash.go#L73
* @type {API.MulticodecCode<0x1012, 'sha2-256-trunc254-padded'>}
*/
export const Sha256Trunc254Padded = 0x1012

/**
* Filecoin contracts use legacy Piece V1 CID links.
*/
export const PieceLinkV1 = Schema.link({
version: 1,
code: FilCommitmentUnsealed,
multihash: {
code: Sha256Trunc254Padded,
},
})

/**
* An address in the filecoin network
*
* @see https://github.com/filecoin-project/go-address/blob/37ccdec47b76ea45424c7c9310e821cb224894e6/address.go#L39-L40
*/
export const Address = Schema.struct({
addr: Schema.string(),
})

/**
* Represents an arbitrary label of the deal either as string (in which case
* `notString` is `false`) or as bytes (in which case `notString` is `true`).
*
* Empty value is represented as an empty string.
*
* @see https://github.com/filecoin-project/go-state-types/blob/ff2ed169ff566458f2acd8b135d62e8ca27e7d0c/builtin/v9/market/deal.go#L36-L44
*/
export const DealLabel = Schema.struct({
bs: Schema.bytes(),
notString: Schema.boolean().default(false),
})

/**
* Epoch number of the chain state
*
* @see https://github.com/filecoin-project/go-state-types/blob/a154da53dfeff49744c94715f74d6edd54d2f6d2/abi/chain.go#L8-L10
*/
export const ChainEpoch = Schema.uint64()

/**
* TokenAmount is an amount of Filecoin tokens serialized into a string.
*
* @see https://github.com/filecoin-project/go-state-types/blob/a154da53dfeff49744c94715f74d6edd54d2f6d2/abi/chain.go#L22
*
* As far as I can tell reference implementation serializes / deserializes it
* into a CBOR string.
*
* @see https://github.com/filecoin-project/go-state-types/blob/a154da53dfeff49744c94715f74d6edd54d2f6d2/big/int.go#L278-L304
*
*/
export const TokenAmount = Schema.string()

/**
* Represents a deal proposal to be signed by the Storefront (`client` field)
* which is an actor in the Filecoin network that compensates the storage
* provider for storing the data.
*
* @see https://github.com/filecoin-project/go-state-types/blob/ff2ed169ff566458f2acd8b135d62e8ca27e7d0c/builtin/v9/market/deal.go#L201-L221
*/
export const Proposal = Schema.struct({
Piece: PieceLinkV1,
Size: PaddedPieceSize,
VerifiedDeal: Schema.boolean(),
Client: Address,
Provider: Address,
Label: DealLabel,

StartEpoch: ChainEpoch,
EndEpoch: ChainEpoch,

StoragePricePerEpoch: TokenAmount,

ProviderCollateral: TokenAmount,
ClientCollateral: TokenAmount,
})

export const ProposalV2 = Schema.tuple([
PieceLinkV1,
PaddedPieceSize,
Schema.boolean(),
Address,
Address,
DealLabel,

ChainEpoch,
ChainEpoch,

TokenAmount,

TokenAmount,
TokenAmount,
])

/**
* The `deal/sign` capability allows actor with corresponding capability to sign
* filecoin deals with the given storefront.
*/
export const sign = capability({
can: 'deal/sign',
/**
* DID identifier of the storefront that will sign the deal.
*/
with: Schema.did(),
nb: Schema.struct({
/**
* Deal proposal to be signed by the storefront.
*/
proposal: Proposal,
}),
derives: (claim, from) =>
and(equalWith(claim, from)) ||
// At the moment we simply check that the fields are equal. In the future
// we might instead check that TokenAmounts are less than equal instead.
and(
checkLink(
claim.nb.proposal.Piece,
from.nb.proposal.Piece,
'nb.proposal.Piece'
)
) ||
and(
equal(claim.nb.proposal.Size, from.nb.proposal.Size, 'nb.proposal.Size')
) ||
and(
equal(
claim.nb.proposal.VerifiedDeal,
from.nb.proposal.VerifiedDeal,
'nb.proposal.VerifiedDeal'
)
) ||
and(
equal(
claim.nb.proposal.Client.addr,
from.nb.proposal.Client.addr,
'nb.proposal.Client'
)
) ||
and(
equal(
claim.nb.proposal.Provider.addr,
from.nb.proposal.Provider.addr,
'nb.proposal.Provider'
)
) ||
and(
equal(
claim.nb.proposal.Label.notString,
from.nb.proposal.Label.notString,
'nb.proposal.Label'
)
) ||
and(
equal(
claim.nb.proposal.Label.notString,
from.nb.proposal.Label.notString,
'nb.proposal.Label.notString'
)
) ||
and(
equal(
claim.nb.proposal.Label.bs.join(''),
from.nb.proposal.Label.bs.join(''),
'nb.proposal.Label.notString'
)
) ||
and(
equal(
claim.nb.proposal.StartEpoch,
from.nb.proposal.StartEpoch,
'nb.proposal.StartEpoch'
)
) ||
and(
equal(
claim.nb.proposal.EndEpoch,
from.nb.proposal.EndEpoch,
'nb.proposal.EndEpoch'
)
) ||
and(
equal(
claim.nb.proposal.StoragePricePerEpoch,
from.nb.proposal.StoragePricePerEpoch,
'nb.proposal.StoragePricePerEpoch'
)
) ||
and(
equal(
claim.nb.proposal.ProviderCollateral,
from.nb.proposal.ProviderCollateral,
'nb.proposal.ProviderCollateral'
)
) ||
and(
equal(
claim.nb.proposal.ClientCollateral,
from.nb.proposal.ClientCollateral,
'nb.proposal.ClientCollateral'
)
) ||
ok({}),
})
25 changes: 25 additions & 0 deletions packages/capabilities/test/capabilities/deal.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import assert from 'assert'
import { access } from '@ucanto/validator'
import { delegate } from '@ucanto/core'
import { Verifier } from '@ucanto/principal/ed25519'
import * as Deal from '../../src/deal.js'
import { bobAccount, service, alice } from '../helpers/fixtures.js'
import { base64 } from 'multiformats/bases/base64'
import { CBOR } from '@ucanto/core'

describe('deal/sign', () => {
it.only('can be created', async () => {
const bytes = base64.baseDecode(
'i9gqWCgAAYHiA5IgIGqqcbfkfeHyoBH/CkAziiM2HrrxRau2SKjYSv55vjgUGQEA9VUCRxawI7f+hLbn3NowPD11SxqP8vxVAkcWsCO3/oS259zaMDw9dUsaj/L8YAAAQEBA'
)

const payload = CBOR.decode(bytes)
// const proposal = Deal.Proposal.create({})

console.log(payload)
console.log(new TextDecoder().decode(payload[3]))

// const tuple = Deal.ProposalV2.from(payload)
// console.log(tuple)
})
})
4 changes: 2 additions & 2 deletions packages/filecoin-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@
"dependencies": {
"@ipld/dag-ucan": "^3.3.2",
"@ucanto/client": "^8.0.0",
"@ucanto/core": "^8.0.0",
"@ucanto/core": "^8.1.0",
"@ucanto/interface": "^8.0.0",
"@ucanto/server": "^8.0.0",
"@ucanto/server": "^8.0.2",
"@ucanto/transport": "^8.0.0",
"@web3-storage/capabilities": "workspace:^",
"@web3-storage/data-segment": "^3.0.1"
Expand Down
6 changes: 3 additions & 3 deletions packages/filecoin-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@
"dist/src/**/*.d.ts.map"
],
"dependencies": {
"@ipld/dag-ucan": "^3.3.2",
"@ipld/dag-cbor": "^9.0.0",
"@ipld/dag-ucan": "^3.3.2",
"@ucanto/client": "^8.0.0",
"@ucanto/core": "^8.0.0",
"@ucanto/core": "^8.1.0",
"@ucanto/interface": "^8.0.0",
"@ucanto/transport": "^8.0.0",
"@web3-storage/capabilities": "workspace:^"
Expand All @@ -68,7 +68,7 @@
"@types/assert": "^1.5.6",
"@types/mocha": "^10.0.1",
"@ucanto/principal": "^8.0.0",
"@ucanto/server": "^8.0.1",
"@ucanto/server": "^8.0.2",
"@web3-storage/data-segment": "^3.0.1",
"assert": "^2.0.0",
"c8": "^7.13.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/upload-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"@ucanto/client": "^8.0.0",
"@ucanto/interface": "^8.0.0",
"@ucanto/principal": "^8.0.0",
"@ucanto/server": "^8.0.1",
"@ucanto/server": "^8.0.2",
"@ucanto/transport": "^8.0.0",
"@ucanto/validator": "^8.0.0",
"@web3-storage/access": "workspace:^",
Expand All @@ -123,7 +123,7 @@
"@ipld/car": "^5.1.1",
"@ipld/dag-ucan": "^3.3.2",
"@types/mocha": "^10.0.1",
"@ucanto/core": "^8.0.0",
"@ucanto/core": "^8.1.0",
"@web-std/blob": "^3.0.4",
"@web3-storage/sigv4": "^1.0.2",
"hd-scripts": "^4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/upload-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"@types/assert": "^1.5.6",
"@types/mocha": "^10.0.1",
"@ucanto/principal": "^8.0.0",
"@ucanto/server": "^8.0.1",
"@ucanto/server": "^8.0.2",
"assert": "^2.0.0",
"blockstore-core": "^3.0.0",
"c8": "^7.13.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/w3up-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"dependencies": {
"@ipld/dag-ucan": "^3.3.2",
"@ucanto/client": "^8.0.0",
"@ucanto/core": "^8.0.0",
"@ucanto/core": "^8.1.0",
"@ucanto/interface": "^8.0.0",
"@ucanto/principal": "^8.0.0",
"@ucanto/transport": "^8.0.0",
Expand All @@ -87,7 +87,7 @@
"@docusaurus/core": "^2.2.0",
"@ipld/car": "^5.1.1",
"@types/mocha": "^10.0.1",
"@ucanto/server": "^8.0.1",
"@ucanto/server": "^8.0.2",
"assert": "^2.0.0",
"c8": "^7.13.0",
"docusaurus-plugin-typedoc": "^0.18.0",
Expand Down
Loading

0 comments on commit b2e8e57

Please sign in to comment.