-
Notifications
You must be signed in to change notification settings - Fork 7
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
feat: render non-vbank NFTs in offers #125
Conversation
Deploying with Cloudflare Pages
|
41b024f
to
ea7eb7b
Compare
d37cc23
to
0471b92
Compare
const value = String(entry.value); | ||
return [kw, { pursePetname, value }]; | ||
}), | ||
await Promise.all( |
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 looks like an opportunity to simplify with objectMap
and deeplyFulfilledObject
. I think with that you would need no await
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 tried playing around with this but couldn't get it working. If we have time, I'd love to pair on this
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.
check out 04ae1c6
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 that refactoring makes sense to apply here too, but not a blocker
@@ -402,7 +403,13 @@ export const makeWalletBridgeFromFollowers = ( | |||
// If we ever add non 'set' amount purses that aren't in the vbank, it's | |||
// not currently possible to read their decimalPlaces, so this code | |||
// will need updating. | |||
if (!Array.isArray(purse.balance.value)) { | |||
|
|||
const isCopyBag = Object.prototype.hasOwnProperty.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.
we must have something already in Endo to check this. if not, please file an 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.
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 tried using isCopySet
, but it kept returning false. Maybe I'm not passing in the correct data. I looked at how the method was used in other projects and couldn't discern what object shape is expects to be passed in
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.
wallet/src/service/Offers.ts
Outdated
import { M } from '@agoric/vat-data'; | ||
import { mustMatch } from '@agoric/store'; |
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.
available in Endo now
import { M } from '@agoric/vat-data'; | |
import { mustMatch } from '@agoric/store'; | |
import { M, mustMatch } from '@endo/patterns'; |
wallet/src/service/Offers.ts
Outdated
@@ -41,6 +44,41 @@ type GiveOrWantEntries = { | |||
}; | |||
}; | |||
|
|||
const CapDataShape = harden({ body: M.string(), slots: M.array() }); |
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 looks right but is a concern of Endo. If it's not available in Endo please file an issue for Endo to provide 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.
wallet/src/service/Offers.ts
Outdated
@@ -41,6 +44,41 @@ type GiveOrWantEntries = { | |||
}; | |||
}; | |||
|
|||
const CapDataShape = harden({ body: M.string(), slots: M.array() }); | |||
|
|||
const theOne = <T>(array: Array<T> | undefined) => { |
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.
consider putting this in a utils module. eventually we might want it in @agoric/internal
but it's pretty lightweight to copy around
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 this abstraction is appropriate for this use-case, explained in my comment below. Is this motivated rather by some other code in the sdk?
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.
You're right. I misread the error conditions for #125 (comment)
There are other cases where an array length other than 1 is an error, and the utility is useful for those, but this spot want undefined
in that case.
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'll file an issue in agoric-sdk
to have this added to @agoric/internal
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.
wallet/src/service/Offers.ts
Outdated
const theOne = <T>(array: Array<T> | undefined) => { | ||
assert(array?.length === 1); | ||
|
||
const first = array.at(0); |
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.
surprising to see at
const first = array.at(0); | |
const first = array[0]; |
but actually, the first element could very well be undefined. so,
const first = array.at(0); | |
return array[0]; |
@@ -402,7 +403,13 @@ export const makeWalletBridgeFromFollowers = ( | |||
// If we ever add non 'set' amount purses that aren't in the vbank, it's | |||
// not currently possible to read their decimalPlaces, so this code | |||
// will need updating. | |||
if (!Array.isArray(purse.balance.value)) { | |||
|
|||
const isCopyBag = Object.prototype.hasOwnProperty.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.
const value = String(entry.value); | ||
return [kw, { pursePetname, value }]; | ||
}), | ||
await Promise.all( |
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.
check out 04ae1c6
wallet/src/service/Offers.ts
Outdated
), | ||
]); | ||
|
||
const brandPetname = theOne(brands.find(([_, brand]) => brand === brand)); |
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.
Did you test this before pushing? brands
is an array of tuples of [petname, brand]
, so assert(array?.length === 1);
above would always throw since the length is 2. I think it's better to leave the ?.at(0)
and leave the brandPetname
undefined if missing, then show an error in the component that renders the offer so that the user doesn't have to open the console to know something went wrong. Additionally, I think throwing will break the loop that watches pending offers, preventing it from rendering other offers.
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 pointing this out. Turns out the purse was created, so I was no longer executing this code path
wallet/src/service/Offers.ts
Outdated
@@ -41,6 +44,41 @@ type GiveOrWantEntries = { | |||
}; | |||
}; | |||
|
|||
const CapDataShape = harden({ body: M.string(), slots: M.array() }); | |||
|
|||
const theOne = <T>(array: Array<T> | undefined) => { |
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 this abstraction is appropriate for this use-case, explained in my comment below. Is this motivated rather by some other code in the sdk?
wallet/src/components/PurseValue.tsx
Outdated
@@ -191,7 +192,7 @@ const PurseValue = ({ value, displayInfo, brandPetname }) => { | |||
const isSet = displayInfo?.assetKind === AssetKind.SET; | |||
const isCopyBag = displayInfo?.assetKind === AssetKind.COPY_BAG; | |||
|
|||
if (isCopyBag && Object.prototype.hasOwnProperty.call(value, 'payload')) { | |||
if (isCopyBag && endoIsCopyBag(value)) { |
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 wonder why one would be true and not the other. Is that exceptional?
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 wasn't sure if there was some legacy situation where we could have a copyBag
, but it didn't have the correct payload. @samsiegart, do you think this is a safe change?
wallet/src/service/Offers.ts
Outdated
); | ||
const purse = brandToPurse.get(amount.brand); | ||
|
||
// if (purse) { |
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.
remove disabled code
wallet/src/service/Offers.ts
Outdated
await getBrandPetNameAndDisplayInfoWithoutPurse( | ||
watcher, | ||
amount.brand, | ||
); | ||
); | ||
console.log("GYT") |
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.
remove
@@ -402,7 +404,10 @@ export const makeWalletBridgeFromFollowers = ( | |||
// If we ever add non 'set' amount purses that aren't in the vbank, it's | |||
// not currently possible to read their decimalPlaces, so this code | |||
// will need updating. | |||
if (!Array.isArray(purse.balance.value)) { | |||
|
|||
const isCopyBag = endoIsCopyBag(purse.balance.value); |
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 it comes from Endo isn't semantically meaningful. please omit from the name.
I think the bar should be high for renaming an import so I'd suggest keeping the imported name and using a different name for the boolean.
otherwise import the function as something meaningful like isCopyBagValue
.
wallet/src/service/Offers.ts
Outdated
watcher: ChainStorageWatcher, | ||
brand: Brand, | ||
) => { | ||
const brandsP = watcher.queryOnce<[string, unknown][]>([ |
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 used to be in the top-level of offer service so it's queried one time, but now it's queried for every proposal entry. Consider moving it back so it can be memoized.
wallet/src/service/Offers.ts
Outdated
|
||
const [brands, boardAux] = await Promise.all([ | ||
brandsP, | ||
watcher.queryBoardAux<{ |
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.
Similarly here, consider memoizing the boardAux for each brand.
wallet/src/service/Offers.ts
Outdated
@@ -109,26 +141,34 @@ export const getOfferService = ( | |||
return Object.fromEntries(entries); | |||
}; | |||
|
|||
const readDisplayInfo = async (entry: PurseDisplayInfo) => { | |||
mustMatch(harden(entry.amount), CapDataShape, 'amount'); |
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.
Why enforce the shape here instead of deferring to the marshaller what it will accept?
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.
No blockers. I trust you'll use "squash" to merge.
const value = String(entry.value); | ||
return [kw, { pursePetname, value }]; | ||
}), | ||
await Promise.all( |
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 that refactoring makes sense to apply here too, but not a blocker
bf91ffe
to
7ff97c0
Compare
Co-authored-by: Samuel Siegart <[email protected]>
Closes #116