-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Improve offer documentation #876
Conversation
Deploying with Cloudflare Pages
|
82dd218
to
a689047
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of minor nits, but this seems like a strict improvement.
main/glossary/README.md
Outdated
Passables include pass-by-copy primitive values such as numbers and strings and | ||
pass-by-reference values such as Remotables and Promises. | ||
Passables also include hardened acyclic pass-by-copy containers that recursively terminate | ||
in non-container passables, such as CopyArrays like `harden(['foo', 'bar'])` and | ||
CopyRecords like `harden({ keys: [0, 1], values: ['foo', 'bar'] })`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth a mention in passing of some things that aren't passable, just to underscore that it's a meaningful concept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps, but if so, let's put that in the Marshaling section.
I'd rather not have any novel info in the glossary. I'd like it to be more of an index. Each item should have a brief gloss plus a link to where the term is defined in context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! Lots of helpful changes here. I have a few suggestions, but mostly this is very good as it stands.
I'll bring up a local copy and verify links and visual formatting before approving.
(For more detail, see [Why do Zoe keywords have to start with a capital letter? #8241](https://github.com/Agoric/agoric-sdk/discussions/8241).) | ||
`NaN` and `Infinity` are also not allowed as keywords. | ||
|
||
<a name="amountkeywordrecord"></a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't that HTML tag have to surround something to have an effect? https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a says to use id
instead.
stackoverflow thinks it's not okay for it to be empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve found that this works, but the browser is not obliged to scroll farther than necessary to put the top of this marker above the fold. Capturing content obliges the browser to scroll to show as much of the content as fits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id
is definitely the correct attribute (my muscle memory here is very old and outdated), but inner content is not necessary to establish what I know of as an "anchor link". This particular technique of using an empty a
element before a Markdown section heading allows external links using an old target to still land in approximately the right place without suffering automatic slug generation issues that cause otherwise preferable Markdown like ## KeywordRecord <a id="amountkeywordrecord"></a>
to render incorrectly in many implementations, e.g.:
--- expected
+++ actual
-<h2 id="keywordrecord">KeywordRecord <a id="amountkeywordrecord"></a></h2>
+<h2 id="keywordrecord-a-id-amountkeywordrecord">KeywordRecord <a id="amountkeywordrecord"></a></h2>
main/reference/zoe-api/zoe.md
Outdated
respectively expressing conditions regarding what assets will be given, what must be | ||
received in exchange, and an exit rule defining how/when the offer can be canceled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... what is being given, what must be received to satisfy offer safety, and an exit rule ...
I'd say "is being given" because zoe requires that the proposal match the payments, and the contract won't see the offer if they don't match. (and the invitation will be burned.
"what must be received to satisfy offer safety" because the user can want any arbitrary thing (subject to want patterns
provided by the contract), and it's a valid offer. If the contract doesn't match the want, then the offer gets its give back.
Is there a reasonable place to describe want patterns
? Do we talk about makeInvitation
from the contract author's perspective?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... what is being given, what must be received to satisfy offer safety, and an exit rule ...
I'd say "is being given" because zoe requires that the proposal match the payments, and the contract won't see the offer if they don't match. (and the invitation will be burned.
"what must be received to satisfy offer safety" because the user can want any arbitrary thing (subject to
want patterns
provided by the contract), and it's a valid offer. If the contract doesn't match the want, then the offer gets its give back.
Done.
Is there a reasonable place to describe
want patterns
?
I'll defer on this question, although Zoe Data Types and The Structure of Offers seem like reasonable locations for followup.
Do we talk about
makeInvitation
from the contract author's perspective?
It's mentioned at ZCF documentation and Writing and Installing a Contract, but they could go further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not yet support want patterns. Looking forward to it though!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The keyword record stuff doesn't look right.
An [invitation](#invitation) optionally returned by [`startInstance()`](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) that the contract instance | ||
An [invitation](#invitation) optionally returned by [`E(zoe).startInstance(...)`](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) that the contract instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISTR some discussion of deprecating / removing creator invitation in the name of zoe durability.
@Chris-Hibbert @erights what became of that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a hope, with no concrete plan behind it. Not worth covering in the docs at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might also be worth noting that startInstance
is subsumed into startUpgradable
. (It is, right?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might also be worth noting that startInstance is subsumed into startUpgradable. (It is, right?)
That doesn't sound familiar. I think you're misremembering something, though I don't know what.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dug into this. The Agoric chain home object can provide startUpgradable
as a thin wrapper for E(zoe).startInstance
. It’s provided by vats/src/core/basic-behaviors.js
. This is why we were unable to find startInstance
in the core proposal in the dapp-game-places
template during the hackathon. We eventually found startUpgradable
and from there were able to figure out how to thread offerArgs
thru the level of indirection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
startUpgradable
is a power from the bootstrap environment; it's available to core-evals, but it's not part of the Zoe API.
The purpose of startUpgradable
is somewhat relevant, though: it's to make sure we don't lose admin facets needed for upgrade.
Do we tell folks in the Zoe docs that startInstance() also returns an admin facet, and if you lose it, you will NEVER BE ABLE TO UPGRADE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
startUpgradable
should be covered in docs for bootstrap powers. Those are pretty thin. That's probably worth a separate issue...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISTR some discussion of deprecating / removing creator invitation in the name of zoe durability.
@Chris-Hibbert @erights what became of that?
It's a hope, with no concrete plan behind it. Not worth covering in the docs at this point.
I think we should explicitly state that it is deprecated. Whether we will ever be able to remove it remains to be seen, but I'm hopeful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked for a relevant issue and found:
- deprecate and remove use of creatorInvitation as a legal return value from contracts agoric-sdk#5775
But it's one of those "do X" issues that doesn't say why do X... other than
That functionality can be supplied from the creatorFacet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for finding that. In light of @samsiegart 's two comments at Agoric/agoric-sdk#5775 (comment) , I withdraw the request to emphasize the deprecation of creator invitation until Sam's question is resolved.
main/glossary/README.md
Outdated
Passables include pass-by-copy primitive values such as numbers and strings and | ||
pass-by-reference values such as Remotables and Promises. | ||
Passables also include hardened acyclic pass-by-copy containers that recursively terminate | ||
in non-container passables, such as CopyArrays like `harden(['foo', 'bar'])` and | ||
CopyRecords like `harden({ keys: [0, 1], values: ['foo', 'bar'] })`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps, but if so, let's put that in the Marshaling section.
I'd rather not have any novel info in the glossary. I'd like it to be more of an index. Each item should have a brief gloss plus a link to where the term is defined in context.
main/guides/zoe/proposal.md
Outdated
## Offer Arguments | ||
|
||
To pass additional arguments to the **offerHandler** contract code associated with the | ||
invitation, send them in an **offerArgs** record. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it reasonable to assume that our audience is familiar with the use of "record" to mean "object"?
When we talk about things like a keyword record or an issuer record, there's more context. But here, there is precious little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that was official JavaScript terminology.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe @erights coined record
and in his interpretation, record means const-object-as-struct. The TC-39 Records and Tuples proposal uses the word to mean new-primitive-as-immutable-struct. TypeScript’s Record
type suggests object-as-mutable-dictionary. I believe offerArgs
is a const-object-as-dictionary. I am distinguishing “const” from “hardened” to mean: the informal contract is that this method will not mutate it and it consequently may be hardened.
It might be best to just say Object
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gibson042 This is great. We saw places where offerArgs was typed unknown
and others where it was typed Object
. I think we need to also converge on the latter in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
To pass additional arguments to the offerHandler contract code associated with the
invitation, send them in an offerArgs CopyRecord.
## KeywordRecord | ||
|
||
A **KeywordRecord** is a [CopyRecord](/glossary/#passable) in which every property name | ||
is a **[Keyword](#keyword)**, such as `harden({ Currency: quatloosBrand, CurrencyUnit: 100n })`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That example seems weird. I don't believe anything in our Record<Keyword, Brand | bigint>
. Did you mean to exhibit a Record<Keyword, Amount<'nat'>>
? aka a Record<Keyword, { brand: Brand<'nat'>, value: NatValue }>
I wonder if it's useful to generalize to KeywordRecord at all. If so, we might as well lean into TypeScript notation: Record<Keyword, T>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That example seems weird. I don't believe anything in our
Record<Keyword, Brand | bigint>
. Did you mean to exhibit aRecord<Keyword, Amount<'nat'>>
? aka aRecord<Keyword, { brand: Brand<'nat'>, value: NatValue }>
No, for that first example I specifically wanted a KeywordRecord that had heterogeneous value types and so was not an AmountKeywordRecord/PaymentKeywordRecord/etc. But if you think this one is confusing, perhaps it could drift even further away from our flavor of DeFi?
is a **[Keyword](#keyword)**, such as `harden({ Currency: quatloosBrand, CurrencyUnit: 100n })`. | |
is a **[Keyword](#keyword)**, such as `harden({ Remotable: myMap, SupportedMethods: ['delete', 'get', 'has', 'set'] })`. |
I wonder if it's useful to generalize to KeywordRecord at all. If so, we might as well lean into TypeScript notation:
Record<Keyword, T>
I thought about that and actually started with something similar, but ultimately decided not to because a) the site already uses AmountKeywordRecord and PaymentKeywordRecord, and b) we don't explain use of TypeScript syntax and AFAICT don't expect developers to know it. But a thought did occur to me in typing the last response—what would you think about using it to help explain the concept for people who are familiar with it?
KeywordRecord
A KeywordRecord is a CopyRecord in which every property name
is a Keyword, such asharden({ Currency: quatloosBrand, CurrencyUnit: 100n })
.
Subtypes further constrain property values (for example, an
AmountKeywordRecord is a KeywordRecord<Amount> in which every value is an
Amount and a
PaymentKeywordRecord is a KeywordRecord<Payment> in which every value is a
Payment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... for that first example I specifically wanted a KeywordRecord that had heterogeneous value types ...
Such an example is a distraction, no? There is no such data type in the Zoe API.
This is the core of my request for changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. There are no KeywordRecords with heterogeneous value types, and I don't think we're likely to add them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, updated.
A KeywordRecord is a CopyRecord in which every property name
is a Keyword, such asharden({ Asset: moolaIssuer, Bid: simoleanIssuer })
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KeywordRecord that had heterogeneous value types
Please don't. None of our keyword records are heterogeneous, and likely none ever will be, since the point of keywords as names is to support lookup by []
user-defined names, and therefore computed property names.
main/reference/zoe-api/zoe.md
Outdated
## E(Zoe).offer(invitation, proposal?, paymentKeywordRecord?, offerArgs?) | ||
- **invitation**: **[Invitation](./zoe-data-types.md#invitation) | Promise<[Invitation](./zoe-data-types.md#invitation)>** | ||
- **proposal**: **[Proposal](/glossary/#proposal)** - Optional. | ||
- **paymentKeywordRecord**: **[PaymentKeywordRecord](./zoe-data-types.md#keywordrecord)** - Optional. | ||
- **offerArgs**: **[CopyRecord](/glossary/#passable)** - Optional. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment: not having these kept in sync with agoric-sdk by machine is just maddening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment: not having these kept in sync with agoric-sdk by machine is just maddening
Indeed!
main/reference/zoe-api/zoe.md
Outdated
|
||
### OfferArgs | ||
**paymentKeywordRecord** must be either `undefined` or a **[PaymentKeywordRecord](./zoe-data-types.md#keywordrecord)** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
**paymentKeywordRecord** must be either `undefined` or a **[PaymentKeywordRecord](./zoe-data-types.md#keywordrecord)** | |
**paymentKeywordRecord** must be either `undefined` or a **[PaymentPKeywordRecord](./zoe-data-types.md#keywordrecord)** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you're right. I consider the typeGuards definitive. Thanks for the correction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, suggestions only.
An [invitation](#invitation) optionally returned by [`startInstance()`](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) that the contract instance | ||
An [invitation](#invitation) optionally returned by [`E(zoe).startInstance(...)`](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) that the contract instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might also be worth noting that startInstance
is subsumed into startUpgradable
. (It is, right?)
A *passable* is something that can be marshalled (see the | ||
[Marshaling section in the JavaScript Distributed Programming Guide](/guides/js-programming/far.md#marshaling-by-copy-or-by-presence)) | ||
and sent to and from remote objects. | ||
A *passable* is something that can be sent to and from remote objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A *passable* is something that can be sent to and from remote objects. | |
A *passable* value is a JavaScript value that can be sent to and from remote objects. |
main/guides/zoe/proposal.md
Outdated
## Offer Arguments | ||
|
||
To pass additional arguments to the **offerHandler** contract code associated with the | ||
invitation, send them in an **offerArgs** record. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe @erights coined record
and in his interpretation, record means const-object-as-struct. The TC-39 Records and Tuples proposal uses the word to mean new-primitive-as-immutable-struct. TypeScript’s Record
type suggests object-as-mutable-dictionary. I believe offerArgs
is a const-object-as-dictionary. I am distinguishing “const” from “hardened” to mean: the informal contract is that this method will not mutate it and it consequently may be hardened.
It might be best to just say Object
here.
main/guides/zoe/proposal.md
Outdated
## Offer Arguments | ||
|
||
To pass additional arguments to the **offerHandler** contract code associated with the | ||
invitation, send them in an **offerArgs** record. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gibson042 This is great. We saw places where offerArgs was typed unknown
and others where it was typed Object
. I think we need to also converge on the latter in the code.
(For more detail, see [Why do Zoe keywords have to start with a capital letter? #8241](https://github.com/Agoric/agoric-sdk/discussions/8241).) | ||
`NaN` and `Infinity` are also not allowed as keywords. | ||
|
||
<a name="amountkeywordrecord"></a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve found that this works, but the browser is not obliged to scroll farther than necessary to put the top of this marker above the fold. Capturing content obliges the browser to scroll to show as much of the content as fits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keyword stuff is addressed to my satisfaction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just comments so far, only on the README
An [invitation](#invitation) optionally returned by [`startInstance()`](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) that the contract instance | ||
An [invitation](#invitation) optionally returned by [`E(zoe).startInstance(...)`](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) that the contract instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISTR some discussion of deprecating / removing creator invitation in the name of zoe durability.
@Chris-Hibbert @erights what became of that?
It's a hope, with no concrete plan behind it. Not worth covering in the docs at this point.
I think we should explicitly state that it is deprecated. Whether we will ever be able to remove it remains to be seen, but I'm hopeful.
@@ -288,7 +301,7 @@ is available [here](https://www.computerweekly.com/blog/Open-Source-Insider/What | |||
A [payment](#payment) whose amount represents (and is required for) participation in a contract instance. | |||
Contracts often return a creator invitation on their instantiation, in case the contract instantiator wants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I think we should deemphasize and deprecate creator invitations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise withdrawn until Sam's question is resolved.
main/glossary/README.md
Outdated
(see [Exit Rule](#exit-rule) for details on the last). For example: | ||
Proposals are records with `give`, `want`, and/or `exit` properties respectively | ||
expressing [offer](#offer) conditions regarding what assets will be given, | ||
what must be received in exchange to satisfy offer safety, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible misunderstanding that offer safety means you'll get what you said you want. At least make "offer safety" and explicit link to that glossary entry. Avoiding the possible misunderstanding would be even better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more. But I clearly won't finish tonight.
Btw, I am not trying to check or follow any links, as I cannot do so simply in the markdown preview mode.
@@ -112,7 +112,7 @@ The [vstorage-viewer](https://github.com/p2p-org/p2p-agoric-vstorage-viewer) con | |||
## Specifying Offers | |||
|
|||
Recall that for an agent within the JavaScript VM, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's an agent? Can we avoid this terminology completely please?
Sigh. To get rid of "agent" you'd also need to fix the diagram.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That diagram is nice!
main/guides/js-programming/far.md
Outdated
|
||
- `farName` `{ String }` | ||
- `object-with-methods` `{ Object }` `[remotable={}]` | ||
- `objectWithMethods` `{ Object }` `[remotable={}]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worse here. Is the parameter name objectWithMethods
or remotable
?
Probably worth emphasizing that the objectsWithMethods
MUST not be hardened or even frozen at the time of the Far
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some more. not done yet.
@@ -13,7 +13,7 @@ Returns an **IssuerRecord** containing the **[Issuer](/reference/ertp-api/issuer | |||
**[Brand](/reference/ertp-api/brand.md)** associated with the **zcfMint**. | |||
|
|||
## aZCFMint.mintGains(gains, zcfSeat?) | |||
- **gains**: **[AmountKeywordRecord](./zoe-data-types.md#amountkeywordrecord)** | |||
- **gains**: **[AmountKeywordRecord](./zoe-data-types.md#keywordrecord)** | |||
- **zcfSeat**: **[ZCFSeat](./zcfseat.md)** - Optional. | |||
- Returns: **ZCFSeat** | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
below
The *gains*' **[Keywords](./zoe-data-types.md#keyword)** are in that **seat**'s namespace.
What does this mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your guess is as good as mine... maybe referring to use of Keywords defined by the contract?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems like a good interpretation, but we don't refer to keywords as a namespace anywhere else, so better to recast this in more familiar terminology.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My best-effort rewording:
aZCFMint.mintGains(gains, zcfSeat?)
- gains: AmountKeywordRecord
- zcfSeat: ZCFSeat - Optional.
- Returns: ZCFSeat
All amounts in gains must be of this ZCFMint's Brand
and the gains' Keywords should be defined by the contract instance in which zcfSeat is participating.
If zcfSeat is not provided, a new seat is used.
Mints the gains Amount of assets and adds them to zcfSeat's Allocation, then returns zcfSeat.aZCFMint.burnLosses(losses, zcfSeat)
- losses: AmountKeywordRecord
- zcfSeat: ZCFSeat
- Returns: None
All amounts in losses must be of this ZCFMint's Brand
and the losses' Keywords must be defined by the contract instance in which zcfSeat is participating.
Subtracts losses from zcfSeat's Allocation, then
burns that amount of assets from the pooled Purse.
@@ -24,7 +24,7 @@ that **seat**'s **[Allocation](./zoe-data-types.md#allocation)**. If a **seat** | |||
it is returned. Otherwise a new **seat** is returned. | |||
|
|||
## aZCFMint.burnLosses(losses, zcfSeat?) | |||
- **losses**: **[AmountKeywordRecord](./zoe-data-types.md#amountkeywordrecord)** | |||
- **losses**: **[AmountKeywordRecord](./zoe-data-types.md#keywordrecord)** | |||
- **zcfSeat**: **[ZCFSeat](./zcfseat.md)** - Optional. | |||
- Returns: None | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
below
then burn that amount of assets from the pooled Purse.
This is true and important. But would a reader have any idea what this pooled Purse is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about changing then burns that amount of assets from the pooled Purse.
to
then burns that amount of assets from the amount escrowed by Zoe for this contract instance.
@@ -235,7 +236,7 @@ zcf.assertUniqueKeyword(keyword); | |||
- Returns: None. | |||
|
|||
Prohibit invocation of invitatations whose description include any of the strings. | |||
Any of the strings that end with a colon (:) will be treated as a prefix, | |||
Any of the strings that end with a colon (`:`) will be treated as a prefix, | |||
and invitations whose description string begins with the string (including the colon) | |||
will be burned and not processed if passed to **E(Zoe).offer()**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Chris-Hibbert , are they actually burned? That surprises me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your instincts are correct. If the invitation is blocked, we Fail
out of the offer()
call and don't get to the immediately following burnInvitation()
.
!instanceAdmin.isBlocked(description) ||
Fail`not accepting offer with description ${q(description)}`;
const { invitationHandle } = await burnInvitation(
invitationIssuer,
invitation,
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change "will be burned and not processed if passed to E(Zoe).offer()" to "will not be processed if passed to E(Zoe).offer(). Instead, an exception will be thrown.".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, I am not trying to check or follow any links, as I cannot do so simply in the markdown preview mode.
I am planning to pull down the whole PR and do the local build and review for link consistency, but I'm waiting for the changes to settle down.
@@ -288,7 +301,7 @@ is available [here](https://www.computerweekly.com/blog/Open-Source-Insider/What | |||
A [payment](#payment) whose amount represents (and is required for) participation in a contract instance. | |||
Contracts often return a creator invitation on their instantiation, in case the contract instantiator wants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise withdrawn until Sam's question is resolved.
main/guides/js-programming/far.md
Outdated
- Pass-by-reference **_Remotables_**: objects that can be shared with remote systems which can then | ||
invoke methods using e.g. `E()` eventual send notation. Remotables are created by [`Far()`](#far-api) | ||
and related functions. | ||
- Pass-by-reference **Promises** for Passables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about Errors?
|
||
Users submit their **payments** and receive their **payouts** as **KeywordRecords**: | ||
```js | ||
quatloosPurse.deposit(payouts.Asset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since payouts.Asset
may be a promise for a payment, and since purse.deposit
demands a non-promise for its payment argument, this example is incorrect or at best misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This review pass complete. Over to you ;)
…mple PaymentKeywordRecord isn't actually used, so replace it with BrandKeywordRecord Co-authored-by: Chris Hibbert <Chris-Hibbert@users.noreply.github.com>
Per @dckc and @Chris-Hibbert, APIs deal with KeywordRecord<ERef<Payment>> rather than KeywordRecord<Payment>
Co-authored-by: Mark S. Miller <erights@users.noreply.github.com>
…mentPKeywordRecord`
e0e0fd8
to
95f4e80
Compare
Thanks for the astonishingly thorough review, @erights! I believe I've addressed all feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extremely close. A few last-second nits.
main/guides/zoe/proposal.md
Outdated
`Invitations` are a special case of ERTP `payments`. They are linked to a specific contract `instance`, and | ||
having one gives you the right to participate in that contract `instance`, for example, by making offers in it. | ||
An [Invitation](/reference/zoe-api/zoe-data-types.md#invitation) is a special case of ERTP [Payment](/reference/ertp-api/payment.md). Each is linked to a specific contract [Instance](/reference/zoe-api/zoe-data-types.md#instance), and | ||
having one gives you the right to participate in that contract instance by making offers with it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I keep reading this and trying to re-word to "by making offers to it". But I think the it
in "with it" is the invitation and the it
in "to it" is the contract. Would you mind rewording? Perhaps "by using the invitation as the first argument to zoe.offer()
".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those pronouns. Dereference them!
@@ -24,7 +24,7 @@ that **seat**'s **[Allocation](./zoe-data-types.md#allocation)**. If a **seat** | |||
it is returned. Otherwise a new **seat** is returned. | |||
|
|||
## aZCFMint.burnLosses(losses, zcfSeat?) | |||
- **losses**: **[AmountKeywordRecord](./zoe-data-types.md#amountkeywordrecord)** | |||
- **losses**: **[AmountKeywordRecord](./zoe-data-types.md#keywordrecord)** | |||
- **zcfSeat**: **[ZCFSeat](./zcfseat.md)** - Optional. | |||
- Returns: None | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about changing then burns that amount of assets from the pooled Purse.
to
then burns that amount of assets from the amount escrowed by Zoe for this contract instance.
**description** is a required string describing the **Invitation**, | ||
and should include whatever information is needed for a potential recipient of the **Invitation** | ||
to know what they are getting in the optional *customProperties* argument, which is | ||
put in the **Invitation**'s **value**. | ||
to know what they are getting in the optional **customProperties** argument, which is | ||
put in the **Invitation**'s **amount**. | ||
Each one should be a string literal that is unique within its contract and | ||
used only as the argument to make invitations of a particular kind. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woops! customProperties
should be customDetails
. (Please fix above) The description here is garbled.
**description** is a required string describing the **Invitation**, | |
and should include whatever information is needed for a potential recipient of the **Invitation** | |
to know what they are getting in the optional *customProperties* argument, which is | |
put in the **Invitation**'s **value**. | |
to know what they are getting in the optional **customProperties** argument, which is | |
put in the **Invitation**'s **amount**. | |
Each one should be a string literal that is unique within its contract and | |
used only as the argument to make invitations of a particular kind. | |
**description** is a required string describing the role of this **Invitation**, | |
and should include whatever information is needed for a potential recipient of the **Invitation** to distinguish amoung this contract's invitations. Each description | |
should be a string literal that is unique within its contract. | |
The (optional) **customDetails** argument is included in the **Invitation**'s | |
**amount** and not otherwise relied on by Zoe. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that proposalShape
lacks a description; would you care to suggest some text for it as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, man, that is not a small topic, and I don't see it touched on anywhere in these docs. The only reference material for it that I can find is in endo, and it is far from adequate as developer documentation.
I would say "a Pattern[ref] describing the required and allowed components of the proposal. Proposals that don't match the pattern will be rejected by Zoe without interacting with the contract." I won't claim that's adequate, but to say any more would take a week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think you need to explicitly say that they are unique to a static call site within this contract. Or better, within this contract's source text. Otherwise, someone might misread to think they need to be unique per dynamic call to makeInstance
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@erights's comment applies to the description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Only the description string. Thx.
@@ -235,7 +236,7 @@ zcf.assertUniqueKeyword(keyword); | |||
- Returns: None. | |||
|
|||
Prohibit invocation of invitatations whose description include any of the strings. | |||
Any of the strings that end with a colon (:) will be treated as a prefix, | |||
Any of the strings that end with a colon (`:`) will be treated as a prefix, | |||
and invitations whose description string begins with the string (including the colon) | |||
will be burned and not processed if passed to **E(Zoe).offer()**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change "will be burned and not processed if passed to E(Zoe).offer()" to "will not be processed if passed to E(Zoe).offer(). Instead, an exception will be thrown.".
The **InvitationIssuer** is a special type of **[Issuer](/reference/ertp-api/issuer.md)**. | ||
Zoe has a single **InvitationIssuer** for its entire lifetime. All **Invitations** come from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's a different type of issuer. How about
The **InvitationIssuer** is a special type of **[Issuer](/reference/ertp-api/issuer.md)**. | |
Zoe has a single **InvitationIssuer** for its entire lifetime. All **Invitations** come from the | |
The **InvitationIssuer** is an **[Issuer](/reference/ertp-api/issuer.md)** that plays a | |
special role throughout Zoe. Zoe has a single **InvitationIssuer** for its entire | |
lifetime. All **Invitations** come from the **[Mint](/reference/ertp-api/mint.md)** | |
associated with the Zoe instance's **InvitationIssuer**. | |
The issuer is publicly available (via `E(Zoe).getInvitationIssuer()`), so the ability | |
to validate invitations is widely available. |
main/reference/zoe-api/zoe.md
Outdated
Some example timers use Unix epoch time, while others count block height. | ||
**proposal** must be either `undefined` or a record with **give**, **want**, and/or **exit** properties | ||
respectively expressing conditions regarding what is being given, | ||
what is expected in exchange (protected by offer safety), and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is expected in exchange (protected by offer safety), and | |
what is desired in exchange (protected by offer safety), and |
main/reference/zoe-api/zoe.md
Outdated
### OfferArgs | ||
**paymentPKeywordRecord** must be either `undefined` or a **[PaymentPKeywordRecord](./zoe-data-types.md#keywordrecord)** | ||
containing the actual **payments** to be escrowed by Zoe. | ||
Every **Keyword** in **give** must also have a corresponding **payment**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every **Keyword** in **give** must also have a corresponding **payment**. | |
Every **Keyword** in **give** must have a corresponding **payment**. |
@Chris-Hibbert updated with your suggestions. |
Thanks all! |
@erights Please remove or replace your "changes requested" review so this can merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Please do look at all unresolved conversations to see if there's anything unaddressed before merging. Otherwise good to go. Awesome improvements, thanks!
...particularly to document
offerArgs
.