diff --git a/contract/src/offer-up-proposal.js b/contract/src/offer-up-proposal.js index d35e1e3..637a2b2 100644 --- a/contract/src/offer-up-proposal.js +++ b/contract/src/offer-up-proposal.js @@ -12,9 +12,6 @@ const BOARD_AUX = 'boardAux'; const marshalData = makeMarshal(_val => Fail`data only`); -const IST_UNIT = 1_000_000n; -const CENT = IST_UNIT / 100n; - /** * Make a storage node for auxilliary data for a value on the board. * @@ -44,7 +41,13 @@ const publishBrandInfo = async (chainStorage, board, brand) => { export const startOfferUpContract = async permittedPowers => { console.error('startOfferUpContract()...'); const { - consume: { board, chainStorage, startUpgradable, zoe }, + consume: { + board, + chainStorage, + startUpgradable, + zoe, + // chainTimerService: chainTimerServiceP, + }, brand: { consume: { IST: istBrandP }, // @ts-expect-error dynamic extension to promise space @@ -66,8 +69,12 @@ export const startOfferUpContract = async permittedPowers => { const istIssuer = await istIssuerP; const istBrand = await istBrandP; + // const timerService = await await chainTimerServiceP; - const terms = { tradePrice: AmountMath.make(istBrand, 25n * CENT) }; + const terms = { + subscriptionPrice: AmountMath.make(istBrand, 10000000n), + // timerService, + }; // agoricNames gets updated each time; the promise space only once XXXXXXX const installation = await offerUpInstallationP; @@ -107,6 +114,7 @@ const offerUpManifest = { chainStorage: true, // to publish boardAux info for NFT brand startUpgradable: true, // to start contract and save adminFacet zoe: true, // to get contract terms, including issuer/brand + // chainTimerService: true, }, installation: { consume: { offerUp: true } }, issuer: { consume: { IST: true }, produce: { Item: true } }, diff --git a/contract/src/offer-up.contract.js b/contract/src/offer-up.contract.js index e24f7d7..36fa043 100644 --- a/contract/src/offer-up.contract.js +++ b/contract/src/offer-up.contract.js @@ -19,58 +19,47 @@ */ // @ts-check -import { Far } from '@endo/far'; -import { M, getCopyBagEntries } from '@endo/patterns'; -import { AssetKind } from '@agoric/ertp/src/amountMath.js'; -import { AmountShape } from '@agoric/ertp/src/typeGuards.js'; +import { Far, E } from '@endo/far'; +import { AmountMath, AssetKind } from '@agoric/ertp/src/amountMath.js'; +import { makeCopyBag, M } from '@endo/patterns'; import { atomicRearrange } from '@agoric/zoe/src/contractSupport/atomicTransfer.js'; import '@agoric/zoe/exported.js'; -const { Fail, quote: q } = assert; - -// #region bag utilities -/** @type { (xs: bigint[]) => bigint } */ -const sum = xs => xs.reduce((acc, x) => acc + x, 0n); - -/** - * @param {import('@endo/patterns').CopyBag} bag - * @returns {bigint[]} - */ -const bagCounts = bag => { - const entries = getCopyBagEntries(bag); - return entries.map(([_k, ct]) => ct); -}; -// #endregion - /** * In addition to the standard `issuers` and `brands` terms, * this contract is parameterized by terms for price and, * optionally, a maximum number of items sold for that price (default: 3). * * @typedef {{ - * tradePrice: Amount; - * maxItems?: bigint; - * }} OfferUpTerms + * subscriptionPrice: Amount; + * subscriptionPeriod?: string; + * servicesToAvail?: Array; + * }} SubscriptionServiceTerms */ -export const meta = { - customTermsShape: M.splitRecord( - { tradePrice: AmountShape }, - { maxItems: M.bigint() }, - ), -}; -// compatibility with an earlier contract metadata API -export const customTermsShape = meta.customTermsShape; - /** * Start a contract that * - creates a new non-fungible asset type for Items, and * - handles offers to buy up to `maxItems` items at a time. * - * @param {ZCF} zcf + * @param {ZCF} zcf */ export const start = async zcf => { - const { tradePrice, maxItems = 3n } = zcf.getTerms(); + const { + // timerService, + subscriptionPrice, + subscriptionPeriod = 'MONTHLY', + servicesToAvail = ['Netflix', 'Amazon', 'HboMax', 'Disney'], + } = zcf.getTerms(); + + const subscriptionResources = {}; + + servicesToAvail.forEach(element => { + subscriptionResources[element] = [ + `${element}_Movie_1`, + `${element}_Movie_2`, + ]; + }); /** * a new ERTP mint for items, accessed thru the Zoe Contract Facet. @@ -81,7 +70,8 @@ export const start = async zcf => { * amounts such as: 3 potions and 1 map. */ const itemMint = await zcf.makeZCFMint('Item', AssetKind.COPY_BAG); - const { brand: itemBrand } = itemMint.getIssuerRecord(); + + const { brand } = itemMint.getIssuerRecord(); /** * a pattern to constrain proposals given to {@link tradeHandler} @@ -90,36 +80,56 @@ export const start = async zcf => { * The `Items` amount must use the `Item` brand and a bag value. */ const proposalShape = harden({ - give: { Price: M.gte(tradePrice) }, - want: { Items: { brand: itemBrand, value: M.bag() } }, + give: { Price: M.eq(subscriptionPrice) }, + want: { Items: { brand: M.any(), value: M.bag() } }, exit: M.any(), }); /** a seat for allocating proceeds of sales */ const proceeds = zcf.makeEmptySeatKit().zcfSeat; - /** @type {OfferHandler} */ - const tradeHandler = buyerSeat => { - // give and want are guaranteed by Zoe to match proposalShape - const { want } = buyerSeat.getProposal(); - - sum(bagCounts(want.Items.value)) <= maxItems || - Fail`max ${q(maxItems)} items allowed: ${q(want.Items)}`; - - const newItems = itemMint.mintGains(want); - atomicRearrange( - zcf, - harden([ - // price from buyer to proceeds - [buyerSeat, proceeds, { Price: tradePrice }], - // new items to buyer - [newItems, buyerSeat, want], - ]), - ); + const subscriptions = new Map(); - buyerSeat.exit(true); - newItems.exit(); - return 'trade complete'; + /** @type {OfferHandler} */ + const tradeHandler = (buyerSeat, offerArgs) => { + // @ts-ignore + const { userAddress, serviceType, offerType } = offerArgs; + // const currentTimeRecord = await E(timerService).getCurrentTimestamp(); + + if (offerType === 'BUY_SUBSCRIPTION') { + const amountObject = AmountMath.make( + brand, + makeCopyBag([[{ serviceStarted: '123', serviceType }, 1n]]), + ); + const want = { Items: amountObject }; + + const newSubscription = itemMint.mintGains(want); + + atomicRearrange( + zcf, + harden([ + // price from buyer to proceeds + [buyerSeat, proceeds, { Price: subscriptionPrice }], + // new items to buyer + [newSubscription, buyerSeat, want], + ]), + ); + + const subscriptionKey = `${userAddress}_${serviceType}`; + subscriptions.set(subscriptionKey, want.Items); + + + buyerSeat.exit(true); + newSubscription.exit(); + return 'Subscription Granted'; + + } + else if (offerType === 'VIEW_SUBSCRIPTION') { + buyerSeat.exit(); + return getSubscriptionResources(userAddress, serviceType); + } + + }; /** @@ -130,11 +140,43 @@ export const start = async zcf => { * - want: `Items` */ const makeTradeInvitation = () => - zcf.makeInvitation(tradeHandler, 'buy items', undefined, proposalShape); + zcf.makeInvitation( + tradeHandler, + 'buy subscription', + undefined, + proposalShape, + ); + + const isSubscriptionValid = userSubscription => { + if (!userSubscription || !userSubscription.value.payload) return false; + + const serviceStarted = userSubscription.value.payload[0][0].serviceStarted; + + // Here we'll check with current time from time service. + if (!serviceStarted || serviceStarted !== '123') return false; + return true; + // + }; + + const getSubscriptionResources = (userAddress, serviceType) => { + const subscriptionKey = `${userAddress}_${serviceType}`; + const userSubscription = subscriptions.get(subscriptionKey); + + const isValidSub = isSubscriptionValid(userSubscription); + if (isValidSub) { + // User has a valid subscription, return the resources + const serviceType = userSubscription.value.payload[0][0].serviceType; + return JSON.stringify(subscriptionResources[serviceType]); + } else { + // User doesn't have a valid subscription + return 'Access denied: You do not have a valid subscription.'; + } + }; // Mark the publicFacet Far, i.e. reachable from outside the contract const publicFacet = Far('Items Public Facet', { makeTradeInvitation, + getSubscriptionResources, }); return harden({ publicFacet }); }; diff --git a/contract/test/test-contract.js b/contract/test/test-contract.js index 6dc1f6a..59573ef 100644 --- a/contract/test/test-contract.js +++ b/contract/test/test-contract.js @@ -5,7 +5,7 @@ /* eslint-disable import/order -- https://github.com/endojs/endo/issues/1235 */ import { test as anyTest } from './prepare-test-env-ava.js'; - +import buildZoeManualTimer from '@agoric/zoe/tools/manualTimer.js'; import { createRequire } from 'module'; import { E, Far } from '@endo/far'; import { makePromiseKit } from '@endo/promise-kit'; @@ -26,7 +26,6 @@ const contractPath = myRequire.resolve(`../src/offer-up.contract.js`); const test = anyTest; const UNIT6 = 1_000_000n; -const CENT = UNIT6 / 100n; /** * Tests assume access to the zoe service and that contracts are bundled. @@ -63,7 +62,12 @@ test('Start the contract', async t => { const money = makeIssuerKit('PlayMoney'); const issuers = { Price: money.issuer }; - const terms = { tradePrice: AmountMath.make(money.brand, 5n) }; + const timer = buildZoeManualTimer(); + const terms = { + subscriptionPrice: AmountMath.make(money.brand, 10000000n), + timerService: timer, + }; + t.log('terms:', terms); /** @type {ERef>} */ @@ -78,43 +82,62 @@ test('Start the contract', async t => { * * @param {import('ava').ExecutionContext} t * @param {ZoeService} zoe - * @param {ERef} instance + * @param {ERef>} instance * @param {Purse} purse - * @param {string[]} choices */ -const alice = async (t, zoe, instance, purse, choices = ['map', 'scroll']) => { +const alice = async (t, zoe, instance, purse) => { const publicFacet = E(zoe).getPublicFacet(instance); // @ts-expect-error Promise seems to work const terms = await E(zoe).getTerms(instance); - const { issuers, brands, tradePrice } = terms; + const { issuers, brands, subscriptionPrice, timerService } = terms; + + const currentTimeRecord = await E(timerService).getCurrentTimestamp(); + const serviceType = 'Netflix'; + const choiceBag = makeCopyBag([ + [{ serviceStarted: currentTimeRecord, serviceType }, 1n], + ]); - const choiceBag = makeCopyBag(choices.map(name => [name, 1n])); const proposal = { - give: { Price: tradePrice }, + give: { Price: subscriptionPrice }, want: { Items: AmountMath.make(brands.Item, choiceBag) }, }; - const pmt = await E(purse).withdraw(tradePrice); + + const pmt = await E(purse).withdraw(subscriptionPrice); t.log('Alice gives', proposal.give); - // #endregion makeProposal const toTrade = E(publicFacet).makeTradeInvitation(); - const seat = E(zoe).offer(toTrade, proposal, { Price: pmt }); + const userAddress = 'agoric123456'; + const seat = E(zoe).offer( + toTrade, + proposal, + { Price: pmt }, + { userAddress, serviceType }, + ); const items = await E(seat).getPayout('Items'); const actual = await E(issuers.Item).getAmountOf(items); t.log('Alice payout brand', actual.brand); t.log('Alice payout value', actual.value); t.deepEqual(actual, proposal.want.Items); + + const actualMovies = [`${serviceType}_Movie_1`, `${serviceType}_Movie_2`]; + const subscriptionMovies = + await E(publicFacet).getSubscriptionResources(userAddress, serviceType); + + t.deepEqual(actualMovies, subscriptionMovies); }; -test('Alice trades: give some play money, want items', async t => { +test('Alice trades: give some play money, want subscription', async t => { const { zoe, bundle } = t.context; const money = makeIssuerKit('PlayMoney'); const issuers = { Price: money.issuer }; - const terms = { tradePrice: AmountMath.make(money.brand, 5n) }; - + const timer = buildZoeManualTimer(); + const terms = { + subscriptionPrice: AmountMath.make(money.brand, 10000000n), + timerService: timer, + }; /** @type {ERef>} */ const installation = E(zoe).install(bundle); const { instance } = await E(zoe).startInstance(installation, issuers, terms); @@ -122,7 +145,7 @@ test('Alice trades: give some play money, want items', async t => { t.is(typeof instance, 'object'); const alicePurse = money.issuer.makeEmptyPurse(); - const amountOfMoney = AmountMath.make(money.brand, 10n); + const amountOfMoney = AmountMath.make(money.brand, 10000000n); const moneyPayment = money.mint.mintPayment(amountOfMoney); alicePurse.deposit(moneyPayment); await alice(t, zoe, instance, alicePurse); @@ -140,18 +163,19 @@ test('Trade in IST rather than play money', async t => { const installation = E(zoe).install(bundle); const feeIssuer = await E(zoe).getFeeIssuer(); const feeBrand = await E(feeIssuer).getBrand(); - const tradePrice = AmountMath.make(feeBrand, 25n * CENT); + const subscriptionPrice = AmountMath.make(feeBrand, 10000000n); + const timer = buildZoeManualTimer(); return E(zoe).startInstance( installation, { Price: feeIssuer }, - { tradePrice }, + { subscriptionPrice, timerService: timer }, ); }; const { zoe, bundle, bundleCache, feeMintAccess } = t.context; const { instance } = await startContract({ zoe, bundle }); const { faucet } = makeStableFaucet({ bundleCache, feeMintAccess, zoe }); - await alice(t, zoe, instance, await faucet(5n * UNIT6)); + await alice(t, zoe, instance, await faucet(10n * UNIT6)); }); test('use the code that will go on chain to start the contract', async t => { @@ -225,5 +249,5 @@ test('use the code that will go on chain to start the contract', async t => { // Now that we have the instance, resume testing as above. const { feeMintAccess, bundleCache } = t.context; const { faucet } = makeStableFaucet({ bundleCache, feeMintAccess, zoe }); - await alice(t, zoe, instance, await faucet(5n * UNIT6)); + await alice(t, zoe, instance, await faucet(10n * UNIT6)); }); diff --git a/ui/package.json b/ui/package.json index 608cbaa..6828924 100644 --- a/ui/package.json +++ b/ui/package.json @@ -43,10 +43,6 @@ "vitest": "^1.2.1", "zustand": "^4.4.1" }, - "resolutions": { - "**/ses": "^1.3.0", - "**/@agoric/xsnap": "0.14.3-dev-9f085d3.0" - }, "prettier": { "trailingComma": "all", "arrowParens": "avoid", diff --git a/ui/src/App.css b/ui/src/App.css index b4d6ec7..d86ace3 100644 --- a/ui/src/App.css +++ b/ui/src/App.css @@ -30,16 +30,15 @@ } } -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } +.selected { + outline: 2px solid #007bff; } .card { padding: 1em; } + .read-the-docs { color: #888; } @@ -54,6 +53,11 @@ margin: 10px; } +.service { + height: 48px; + width: 48px; +} + .trade { display: flex; flex-direction: column; diff --git a/ui/src/App.tsx b/ui/src/App.tsx index db4c2a2..c80a372 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -14,11 +14,13 @@ import { subscribeLatest } from '@agoric/notifier'; import { makeCopyBag } from '@agoric/store'; import { Logos } from './components/Logos'; import { Inventory } from './components/Inventory'; -import { Trade } from './components/Trade'; +import { Subscribe } from './components/Trade'; + +import { AmountMath } from '@agoric/ertp'; const { entries, fromEntries } = Object; -type Wallet = Awaited>; +export type Wallet = Awaited>; const ENDPOINTS = { RPC: 'http://localhost:26657', @@ -86,15 +88,38 @@ const connectWallet = async () => { } }; -const makeOffer = (giveValue: bigint, wantChoices: Record) => { +// const watchUpdates = async () => { +// const { wallet, offerUpInstance, brands } = useAppStore.getState(); +// const iterator = subscribeLatest(wallet?.walletUpdatesNotifier); +// for await (const update of iterator) { +// console.log("MUNEEB", update) +// // numWantsSatisfied can either be 1 or 0 until "multiples" are +// // supported. +// // +// // https://github.com/Agoric/agoric-sdk/blob/1b5e57f17a043a43171621bbe3ef68131954f714/packages/zoe/src/zoeService/types.js#L213 +// if (update.status.numWantsSatisfied > 0) { +// console.log('Offer accepted', update); +// return; +// } +// } +// }; + +const makeOffer = async (giveValue: bigint, wantChoice: string, offerType: string, watchUpdates: Function) => { const { wallet, offerUpInstance, brands } = useAppStore.getState(); if (!offerUpInstance) throw Error('no contract instance'); if (!(brands && brands.IST && brands.Item)) throw Error('brands not available'); - const value = makeCopyBag(entries(wantChoices)); - const want = { Items: { brand: brands.Item, value } }; - const give = { Price: { brand: brands.IST, value: giveValue } }; + const choiceBag = makeCopyBag([ + [{ serviceStarted: '123', serviceType: wantChoice }, 1n], + ]); + + // want: { Items: AmountMath.make(brands.Item, choiceBag) } + + // const value = makeCopyBag(entries(wantChoices)); + const want = { Items: AmountMath.make(brands.Item, choiceBag) }; + const give = { Price: AmountMath.make(brands.IST, 10000000n) }; + wallet?.makeOffer( { @@ -103,8 +128,14 @@ const makeOffer = (giveValue: bigint, wantChoices: Record) => { publicInvitationMaker: 'makeTradeInvitation', }, { give, want }, - undefined, + { + userAddress: wallet.address, + serviceType: wantChoice, + offerType: offerType, + }, (update: { status: string; data?: unknown }) => { + if (offerType === 'BUY_SUBSCRIPTION') { + if (update.status === 'error') { alert(`Offer error: ${update.data}`); } @@ -114,8 +145,10 @@ const makeOffer = (giveValue: bigint, wantChoices: Record) => { if (update.status === 'refunded') { alert('Offer rejected'); } - }, + } + } ); + watchUpdates(wallet, offerType, wantChoice); }; function App() { @@ -145,10 +178,10 @@ function App() { return ( <> -

Items Listed on Offer Up

+

All-in-One Subscription Service

- ) : ( diff --git a/ui/src/assets/amazon.svg b/ui/src/assets/amazon.svg new file mode 100644 index 0000000..8d6c7bf --- /dev/null +++ b/ui/src/assets/amazon.svg @@ -0,0 +1,51 @@ + + + + +PrimeLogo_Blue + + + + + + + + diff --git a/ui/src/assets/disney.svg b/ui/src/assets/disney.svg new file mode 100644 index 0000000..1b49efe --- /dev/null +++ b/ui/src/assets/disney.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/src/assets/hbomax.svg b/ui/src/assets/hbomax.svg new file mode 100644 index 0000000..efe5102 --- /dev/null +++ b/ui/src/assets/hbomax.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/src/assets/netflix.svg b/ui/src/assets/netflix.svg new file mode 100644 index 0000000..e2736b8 --- /dev/null +++ b/ui/src/assets/netflix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/src/components/Inventory.tsx b/ui/src/components/Inventory.tsx index 53dea99..7f71b1c 100644 --- a/ui/src/components/Inventory.tsx +++ b/ui/src/components/Inventory.tsx @@ -25,7 +25,7 @@ const Inventory = ({ address, istPurse, itemsPurse }: InventoryProps) => ( istPurse.displayInfo.decimalPlaces, )}
-
+ {/*
Items: {itemsPurse ? (
    @@ -40,7 +40,7 @@ const Inventory = ({ address, istPurse, itemsPurse }: InventoryProps) => ( ) : ( 'None' )} -
+
*/} diff --git a/ui/src/components/Logos.tsx b/ui/src/components/Logos.tsx index 13e9e5c..7c607ba 100644 --- a/ui/src/components/Logos.tsx +++ b/ui/src/components/Logos.tsx @@ -1,15 +1,7 @@ -import reactLogo from '../assets/react.svg'; -import viteLogo from '/vite.svg'; import agoricLogo from '/agoric.svg'; const Logos = () => (
- - Vite logo - - - React logo - Agoric logo diff --git a/ui/src/components/Trade.tsx b/ui/src/components/Trade.tsx index 9ce8b87..76abbf3 100644 --- a/ui/src/components/Trade.tsx +++ b/ui/src/components/Trade.tsx @@ -1,16 +1,21 @@ -import { FormEvent, useState } from 'react'; +import { FormEvent, useEffect, useState } from 'react'; import { stringifyAmountValue } from '@agoric/ui-components'; import scrollIcon from '../assets/scroll.png'; import istIcon from '../assets/IST.svg'; import mapIcon from '../assets/map.png'; import potionIcon from '../assets/potionBlue.png'; +import netflixLogo from '../assets/netflix.svg'; +import disneyLogo from '../assets/disney.svg'; +import hboLogo from '../assets/hbomax.svg'; +import primeLogo from '../assets/amazon.svg'; +import { Wallet } from '../App'; +import { subscribeLatest } from '@agoric/notifier'; const { entries, values } = Object; const sum = (xs: bigint[]) => xs.reduce((acc, next) => acc + next, 0n); const terms = { - price: 250000n, - maxItems: 3n, + price: 10000000n, }; const nameToIcon = { scroll: scrollIcon, @@ -26,6 +31,20 @@ const parseValue = (numeral: string, purse: Purse): bigint => { return BigInt(num); }; +const SERVICES = { + NETFLIX: 'Netflix', + AMAZON: 'Amazon', + HBO: 'HboMax', + DISNEY: 'Disney', +}; + +const serviceNameToIconMap = { + [SERVICES.NETFLIX]: netflixLogo, + [SERVICES.AMAZON]: primeLogo, + [SERVICES.DISNEY]: disneyLogo, + [SERVICES.HBO]: hboLogo, +}; + const Item = ({ icon, coinIcon, @@ -62,75 +81,99 @@ const Item = ({
); -type TradeProps = { - makeOffer: (giveValue: bigint, wantChoices: Record) => void; +type SubscriptionProps = { + makeOffer: (giveValue: bigint, wantChoice: string, offerType: string, watchUpdates: Function) => void; istPurse: Purse; walletConnected: boolean; }; +const watchUpdates = async (wallet: Wallet, offerType: string, serviceType: string) => { + const iterator = subscribeLatest(wallet?.walletUpdatesNotifier); + let flag = false; + for await (const update of iterator) { + if (offerType === "VIEW_SUBSCRIPTION" && !flag && update.status.offerArgs.serviceType === serviceType && update.status.offerArgs.offerType === 'VIEW_SUBSCRIPTION') { + flag = true; + alert(update.status.result); + } + } +}; + // TODO: IST displayInfo is available in vbankAsset or boardAux -const Trade = ({ makeOffer, istPurse, walletConnected }: TradeProps) => { - const [giveValue, setGiveValue] = useState(terms.price); - const [choices, setChoices] = useState({ map: 1n, scroll: 2n }); - const changeChoice = (ev: FormEvent) => { - if (!ev.target) return; - const elt = ev.target as HTMLInputElement; - const title = elt.title as ItemName; - if (!title) return; - const qty = BigInt(elt.value); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { [title]: _old, ...rest }: ItemChoices = choices; - const newChoices = qty > 0 ? { ...rest, [title]: qty } : rest; - setChoices(newChoices); - }; +const Subscribe = ({ + makeOffer, + istPurse, + walletConnected, +}: SubscriptionProps) => { + const [choice, setChoice] = useState(''); + const [selectClass, setSelectClass] = useState({ + [SERVICES.NETFLIX]: '', + [SERVICES.AMAZON]: '', + [SERVICES.DISNEY]: '', + [SERVICES.HBO]: '', + }); + return ( <>
-

Want: Choose up to 3 items

+

Pick a Provider

- {entries(nameToIcon).map(([title, icon]) => ( - - ))} +
+ {Object.entries(SERVICES).map(([_, service]) => { + return ( +
{ + setChoice(service); + setSelectClass({ + [SERVICES.NETFLIX]: '', + [SERVICES.AMAZON]: '', + [SERVICES.DISNEY]: '', + [SERVICES.HBO]: '', + [service]: 'selected', + }); + }} + // className={selectClass[service]} + > +
+ +
+
+ ); + })} +
-
-
-

Give: Offer at least 0.25 IST

-
- - setGiveValue(parseValue(ev?.target?.value, istPurse)) - } - inputClassName={giveValue >= terms.price ? 'ok' : 'error'} - inputStep="0.01" - /> +
+ *Subscribe to any service for 10 IST
+
{walletConnected && ( - + )} + {walletConnected && ( + )}
@@ -138,4 +181,4 @@ const Trade = ({ makeOffer, istPurse, walletConnected }: TradeProps) => { ); }; -export { Trade }; +export { Subscribe }; diff --git a/ui/src/netflix.svg b/ui/src/netflix.svg new file mode 100644 index 0000000..e2736b8 --- /dev/null +++ b/ui/src/netflix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 5f27201..52c75fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45,6 +45,11 @@ resolved "https://registry.yarnpkg.com/@agoric/assert/-/assert-0.6.1-u11wf.0.tgz#742ae27103547b41cdbb3f17c4f09922a2d639e2" integrity sha512-z/uq9ZkWWsBwMYLWg/X4AxEWwKv7HYU+0dCM98SZW8REK5BPhF/Vy9u0AuFLP8kwPdpp7WroYOSIVZ6xhLz0TQ== +"@agoric/assert@^0.6.1-u16.0": + version "0.6.1-u16.0" + resolved "https://registry.yarnpkg.com/@agoric/assert/-/assert-0.6.1-u16.0.tgz#7a03d7ca250af202d77729781c670b4812f86475" + integrity sha512-hIVL6Fx2D0w0MfNARFFvsfIGh88XePNPpfFmmZNJ+cDxrgKhe3Ua327JsngiU3uAmwaq0rCw/UnBO9RoeCYavw== + "@agoric/babel-generator@^7.17.4", "@agoric/babel-generator@^7.17.6": version "7.17.6" resolved "https://registry.yarnpkg.com/@agoric/babel-generator/-/babel-generator-7.17.6.tgz#75ff4629468a481d670b4154bcfade11af6de674" @@ -809,6 +814,15 @@ "@agoric/store" "^0.9.3-u13.0" "@endo/nat" "4.1.27" +"@agoric/time@^0.3.3-u16.0": + version "0.3.3-u16.0" + resolved "https://registry.yarnpkg.com/@agoric/time/-/time-0.3.3-u16.0.tgz#51ea9e72a9882e722fc4b82fb49aeca12bd6d620" + integrity sha512-4y1BcaJc+wCpzKsBnLvcVJu9kc0mp/2dGecHtaxd+qVnNxugWVCL6VspFpEKo5rVDzQBZsBdh4XvOKX+mMXI9A== + dependencies: + "@agoric/assert" "^0.6.1-u16.0" + "@endo/nat" "^5.0.7" + "@endo/patterns" "^1.4.0" + "@agoric/ui-components@^0.9.0": version "0.9.0" resolved "https://registry.yarnpkg.com/@agoric/ui-components/-/ui-components-0.9.0.tgz#0177f71d6752836f326d5309f302052861b5e23a" @@ -1067,13 +1081,21 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@7.18.6", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: "@babel/highlight" "^7.18.6" +"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + "@babel/compat-data@^7.22.9": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.3.tgz#3febd552541e62b5e883a25eb3effd7c7379db11" @@ -1245,6 +1267,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -1273,7 +1300,7 @@ "@babel/traverse" "^7.24.1" "@babel/types" "^7.24.0" -"@babel/highlight@7.22.5", "@babel/highlight@^7.18.6": +"@babel/highlight@^7.18.6": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== @@ -1282,6 +1309,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.17.3", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.3", "@babel/parser@^7.7.0": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.3.tgz#0ce0be31a4ca4f1884b5786057cadcb6c3be58f9" @@ -1753,7 +1790,12 @@ resolved "https://registry.yarnpkg.com/@endo/base64/-/base64-0.2.31.tgz#92378462cd791e0258a2291d44d2cfd15415cf32" integrity sha512-7IndkaZ7buIuFw8oBovNZV7epuyFWs0gdusSJ/zrx6fMXRqX0ycSTtxr6M5xADQGss1I9fqP3vteVLiNFlyIbw== -"@endo/bundle-source@2.5.2-upstream-rollup", "@endo/bundle-source@^2.5.1", "@endo/bundle-source@^2.8.0": +"@endo/base64@^0.2.35": + version "0.2.35" + resolved "https://registry.yarnpkg.com/@endo/base64/-/base64-0.2.35.tgz#7d18203d5807748388c935df7eb79c7672a0b64e" + integrity sha512-rsAicKvgNq/ar+9b3ElXRXglMiJcg1IErz3lx1HFYZUzfWp8r/Dibi3TEjYpSBmtOeYN9CeWH8CBluN0uFqdag== + +"@endo/bundle-source@2.5.2-upstream-rollup": version "2.5.2-upstream-rollup" resolved "https://registry.yarnpkg.com/@endo/bundle-source/-/bundle-source-2.5.2-upstream-rollup.tgz#89fdc6b1b6625ca8c484c12e7762f04cd711ca9f" integrity sha512-UoQlCMZ8jnQA6ulKYII+plWdyK0/XAj1clHPnAW1ILEthQWN1h9WeQT26mIWowGp+sX8CIyiRSVRQN/0pC35Fw== @@ -1772,6 +1814,26 @@ rollup "^2.79.1" source-map "^0.7.3" +"@endo/bundle-source@^2.5.1", "@endo/bundle-source@^2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@endo/bundle-source/-/bundle-source-2.8.0.tgz#56f25b3d9c74d3d0bede5c526647aaf02c0a8f94" + integrity sha512-nDiM3u/LKWq5xAnJ+zm35HC6kMKF3IG6Y5V0385slFHZVT8mXzRJ5ztEqRsVzvVeITfz3ZRFOaFer6v4V8Lkjg== + dependencies: + "@agoric/babel-generator" "^7.17.4" + "@babel/parser" "^7.17.3" + "@babel/traverse" "^7.17.3" + "@endo/base64" "^0.2.35" + "@endo/compartment-mapper" "^0.9.2" + "@endo/init" "^0.5.60" + "@endo/promise-kit" "^0.2.60" + "@endo/where" "^0.3.5" + "@rollup/plugin-commonjs" "^19.0.0" + "@rollup/plugin-node-resolve" "^13.0.0" + acorn "^8.2.4" + jessie.js "^0.3.2" + rollup "^2.79.1" + source-map "^0.7.3" + "@endo/captp@3.1.1", "@endo/captp@^3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@endo/captp/-/captp-3.1.1.tgz#538cdb7deec694cfce1015e1ccb387270172642d" @@ -1790,11 +1852,20 @@ "@endo/base64" "^0.2.31" "@endo/compartment-mapper" "^0.8.4" -"@endo/cjs-module-analyzer@^0.2.31": +"@endo/cjs-module-analyzer@^0.2.31", "@endo/cjs-module-analyzer@^0.2.35": version "0.2.35" resolved "https://registry.yarnpkg.com/@endo/cjs-module-analyzer/-/cjs-module-analyzer-0.2.35.tgz#0de39d2306bba5671e121efa091bf6cb9990f11e" integrity sha512-Ldr1auybH9AzrR/WV6bzP4aLRpv8CCl98mv0IAui4uQmmFOPOGchshyBfpiDF5XMKM6wh7z0VgmvmydQ5/7AHQ== +"@endo/common@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/common/-/common-1.2.5.tgz#4f7a64d756dbb9a88bf8b0bef942f7943e2cd7e6" + integrity sha512-bl9s95aYe0xCJy5IbuFxhizzFQHa/wiQa5FIZK6Rm8uV5g7iS/wdfCJOdNKicxAsJWTPx96AwAmLlgEV8NdUJg== + dependencies: + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/promise-kit" "^1.1.5" + "@endo/compartment-mapper@0.8.4", "@endo/compartment-mapper@^0.8.4": version "0.8.4" resolved "https://registry.yarnpkg.com/@endo/compartment-mapper/-/compartment-mapper-0.8.4.tgz#afae6a4dfc64dff7082e90d7f215a072fb0a9b85" @@ -1805,11 +1876,38 @@ "@endo/zip" "^0.2.31" ses "^0.18.4" +"@endo/compartment-mapper@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@endo/compartment-mapper/-/compartment-mapper-0.9.2.tgz#48bfa610179cc5521c745c7b2d1eb5fab52ed29a" + integrity sha512-zsAyTf87zBsE1yZ2CBzEGhcGZGGv5m93/CXZHQhut53o4DWwhuS/WTQ4cBoVFSGKWz63JbbA/7qa4fcOnv5dDw== + dependencies: + "@endo/cjs-module-analyzer" "^0.2.35" + "@endo/static-module-record" "^0.8.2" + "@endo/zip" "^0.2.35" + ses "^0.18.8" + +"@endo/env-options@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@endo/env-options/-/env-options-0.1.4.tgz#e516bc3864f00b154944e444fb8996a9a0c23a45" + integrity sha512-Ol8ct0aW8VK1ZaqntnUJfrYT59P6Xn36XPbHzkqQhsYkpudKDn5ILYEwGmSO/Ff+XJjv/pReNI0lhOyyrDa9mg== + "@endo/env-options@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@endo/env-options/-/env-options-1.1.1.tgz#eee630f8eff01580ec49e0dedcb1b6cef05d89a4" integrity sha512-uCwlJ8Vkndx/VBBo36BdYHdxSoQPy7ZZpwyJNfv86Rh4B1IZfqzCRPf0u0mPgJdzOr7lShQey60SuYwoMSZ9Xg== +"@endo/env-options@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@endo/env-options/-/env-options-1.1.6.tgz#f4e2dcb22f19f33c0431303c7387c7f5b54c757f" + integrity sha512-Uqy94PwLTco90Yfign43muvDtjsYTbL6Ck4W5sSWQUqJiFOL+YP8kiBOoGyQynDsGTY0MCQvMxEPfphaJKnzlQ== + +"@endo/errors@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/errors/-/errors-1.2.5.tgz#158bc584b9e648e4ca2978a240b57cb45df05c03" + integrity sha512-iZ8Kv0DoE70Z4GDoXZQK3mS3BzDnA1kSeDdE97I02ESWe9tR30TGCHW++CqbCt/lZ6bG/RBq1a6JNuOae+WKlw== + dependencies: + ses "^1.8.0" + "@endo/eslint-plugin@^0.5.2": version "0.5.2" resolved "https://registry.yarnpkg.com/@endo/eslint-plugin/-/eslint-plugin-0.5.2.tgz#835d22e9ff17d9935f7f565e50a21ef07aa92ca2" @@ -1820,11 +1918,25 @@ tsutils "~3.21.0" typescript "~5.2.2" -"@endo/eventual-send@0.17.2", "@endo/eventual-send@^0.17.2", "@endo/eventual-send@^0.17.5": +"@endo/eventual-send@0.17.2", "@endo/eventual-send@^0.17.2": version "0.17.2" resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-0.17.2.tgz#c8710d557c2f57723be05fe99e941cd893acc5d2" integrity sha512-nux02l2yYXXUeUA2PigOO1K0gbVVMYx3prfYrW/G7Ny6PiDLtOyaeMWwKQwFTgJV2yAkOfvycr4LC1+tm7hu/Q== +"@endo/eventual-send@^0.17.5", "@endo/eventual-send@^0.17.6": + version "0.17.6" + resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-0.17.6.tgz#86719e4e3ff76991c49f6680309dc77dff65fe55" + integrity sha512-73cKY2uiWdzMJn7i284NJyD3K0UKjpksBg/EA2GT8YJa0TgeBczFQIm81vC08itK5gHuDDH2vC5COSGR6hxKIg== + dependencies: + "@endo/env-options" "^0.1.4" + +"@endo/eventual-send@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-1.2.5.tgz#f6aef45f6f8d30c42a57512315aa43a4215f425b" + integrity sha512-Ssbwyih2+paHduMiEpdFPJiViBMa4gc9OPNPSklrI5eyBAcGXKLr4/LySbDH9+PVRAnr69tzQsdx4HCM3GPXEA== + dependencies: + "@endo/env-options" "^1.1.6" + "@endo/exo@0.2.2", "@endo/exo@^0.2.2": version "0.2.2" resolved "https://registry.yarnpkg.com/@endo/exo/-/exo-0.2.2.tgz#eeebe3eeb40dcf9b409fddf8d5ff73821b470515" @@ -1833,7 +1945,7 @@ "@endo/far" "^0.2.18" "@endo/patterns" "^0.2.2" -"@endo/far@0.2.18", "@endo/far@^0.2.18", "@endo/far@^0.2.22", "@endo/far@^0.2.3": +"@endo/far@0.2.18", "@endo/far@^0.2.18", "@endo/far@^0.2.3": version "0.2.18" resolved "https://registry.yarnpkg.com/@endo/far/-/far-0.2.18.tgz#8d8ca8ac1f7c4b57871e55c2c2f06c8e4fcf3839" integrity sha512-NJPz5x11AOsFgxZNSIW4+llQtSUNQtcYCrvxpMwhofti3hncMjhIiUUrMVggw99pdHNmXEBr0gl16H3n/1X0sw== @@ -1841,6 +1953,14 @@ "@endo/eventual-send" "^0.17.2" "@endo/pass-style" "^0.1.3" +"@endo/far@^0.2.22": + version "0.2.22" + resolved "https://registry.yarnpkg.com/@endo/far/-/far-0.2.22.tgz#fda187289a903ee3f9d6dcc5664ee7fef1994b1f" + integrity sha512-LFOicqyHslKOSk/H5EfGOcw347ftDSwYHARPasnrG4UJOEkcU1ZG5bN/BmfONtcidB776gWZKrV/tNl4WLIlyw== + dependencies: + "@endo/eventual-send" "^0.17.6" + "@endo/pass-style" "^0.1.7" + "@endo/import-bundle@0.3.4", "@endo/import-bundle@^0.3.4": version "0.3.4" resolved "https://registry.yarnpkg.com/@endo/import-bundle/-/import-bundle-0.3.4.tgz#dd93dca2aa595f669365f05d03affd4465837919" @@ -1849,7 +1969,7 @@ "@endo/base64" "^0.2.31" "@endo/compartment-mapper" "^0.8.4" -"@endo/init@0.5.56", "@endo/init@^0.5.56", "@endo/init@^0.5.60": +"@endo/init@0.5.56", "@endo/init@^0.5.56": version "0.5.56" resolved "https://registry.yarnpkg.com/@endo/init/-/init-0.5.56.tgz#c241de519434309f362dc676e76ee36c93240151" integrity sha512-BKA7O2uy9uaGw9dB9X515SIaTumaO58HD30AXkJllW6bmLM/BxxFM3GCgS127x0Wot1ni32Y0DxkwxdEXFXJEQ== @@ -1859,6 +1979,16 @@ "@endo/lockdown" "^0.1.28" "@endo/promise-kit" "^0.2.56" +"@endo/init@^0.5.60": + version "0.5.60" + resolved "https://registry.yarnpkg.com/@endo/init/-/init-0.5.60.tgz#e78051b13cd4a04c72d5ec1d2a6011b7f987f7ff" + integrity sha512-AbAvs6Nk01fyJ+PaW0RzwemIWyomjzDf8ZEhVa3jCOhr8kBBsTnJdX0v7XkbZ/Y8NQxlrFaW0fPqlJK6aMWTlQ== + dependencies: + "@endo/base64" "^0.2.35" + "@endo/eventual-send" "^0.17.6" + "@endo/lockdown" "^0.1.32" + "@endo/promise-kit" "^0.2.60" + "@endo/lockdown@0.1.28", "@endo/lockdown@^0.1.28": version "0.1.28" resolved "https://registry.yarnpkg.com/@endo/lockdown/-/lockdown-0.1.28.tgz#43f23dcbb12b6ebd3ad2a3dc8c6bb3609dd9e95f" @@ -1866,7 +1996,14 @@ dependencies: ses "^0.18.4" -"@endo/marshal@0.8.5", "@endo/marshal@^0.8.5", "@endo/marshal@^0.8.9": +"@endo/lockdown@^0.1.32": + version "0.1.32" + resolved "https://registry.yarnpkg.com/@endo/lockdown/-/lockdown-0.1.32.tgz#2d13a9ca336d5dce243a3cf919c543b55973153c" + integrity sha512-AN696XS3robsopxVg7gc/6c9TXPGosGmKfcM0g9SNnD1rqgo1EakS4wf7f3AbICU9iJdo0e4V5JjzWPnjqoR0g== + dependencies: + ses "^0.18.8" + +"@endo/marshal@0.8.5", "@endo/marshal@^0.8.5": version "0.8.5" resolved "https://registry.yarnpkg.com/@endo/marshal/-/marshal-0.8.5.tgz#c1a10ed4d9b37ee7444d314d8dec9a9a96728d64" integrity sha512-oj2Ag/TlkoMPv8m00fjoa1uWPgDwm5w8nYUU0DPqaCLfTNGRe8a8s7kYDPbv+sQdiQbkZ1RgUQjdyr/O2Mvs+A== @@ -1876,11 +2013,43 @@ "@endo/pass-style" "^0.1.3" "@endo/promise-kit" "^0.2.56" +"@endo/marshal@^0.8.9": + version "0.8.9" + resolved "https://registry.yarnpkg.com/@endo/marshal/-/marshal-0.8.9.tgz#f6fcaf23ecad828f6d086657f1d1590ea8ef3840" + integrity sha512-wzYlY5/JFzY/wAVxZ6h0BxlRaAS/9KKnhircKO/tGw5bZYHFvLeSeMCBZ4VCSZg5aNgDlhuvB0S6iCwS5MYqcg== + dependencies: + "@endo/eventual-send" "^0.17.6" + "@endo/nat" "^4.1.31" + "@endo/pass-style" "^0.1.7" + "@endo/promise-kit" "^0.2.60" + +"@endo/marshal@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@endo/marshal/-/marshal-1.5.3.tgz#0eadff5442169561ab40748207a0b703b0db2c42" + integrity sha512-gRd3nVebI1CecJcaIaGY0AbDfVe/0E8N7MZ0+dOoOnk1LcqcEY8Cq9vYxIcDRkXm/buAq4cdsfxY5khAVyOr1g== + dependencies: + "@endo/common" "^1.2.5" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/nat" "^5.0.10" + "@endo/pass-style" "^1.4.3" + "@endo/promise-kit" "^1.1.5" + "@endo/nat@4.1.27", "@endo/nat@^4.1.27": version "4.1.27" resolved "https://registry.yarnpkg.com/@endo/nat/-/nat-4.1.27.tgz#8f1a398b39f994b0769070a3fb36d3397bf86794" integrity sha512-mKRdIc4NvrxZ1qPBcYZH6zaj0RsRwADaCcfPNRnGWcHC9dY8DmZDDcgqNdSBFLiEto1RnXeoKAEGxk6hn253Ow== +"@endo/nat@^4.1.31": + version "4.1.31" + resolved "https://registry.yarnpkg.com/@endo/nat/-/nat-4.1.31.tgz#ca738f472481a572f47749b41529b3261ebb4c1e" + integrity sha512-tz0PnEmzX9BAtKEawYndsx+XC6f+2CKErtrpbpOuX3uct5VNLdw6q6cArSYtnHbxRHR0YaHUdeG0W6okmup4bg== + +"@endo/nat@^5.0.10", "@endo/nat@^5.0.7": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@endo/nat/-/nat-5.0.10.tgz#2c843bd2ddb1587c5aaf5c489d58e1f946f52bb4" + integrity sha512-yo+wss3Ng8QXHrmjgp5AmlJ5r8nf0AdGMZjpH0C1sOvbvw9RF2v6B/RGkO0i4dANgdAyHGK9WMYTV6w9/IA2eg== + "@endo/netstring@0.3.26", "@endo/netstring@^0.3.26": version "0.3.26" resolved "https://registry.yarnpkg.com/@endo/netstring/-/netstring-0.3.26.tgz#7da8338cb372772894e1ebcc0728b23666fa2c89" @@ -1898,7 +2067,26 @@ "@endo/promise-kit" "^0.2.56" "@fast-check/ava" "^1.1.3" -"@endo/patterns@0.2.2", "@endo/patterns@^0.2.2", "@endo/patterns@^0.2.5": +"@endo/pass-style@^0.1.7": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@endo/pass-style/-/pass-style-0.1.7.tgz#ea22568e8b86fb2d1a14a5fc042374cc0d8e310b" + integrity sha512-dlB62Ptjcy/+iachy7qzAdgIwaU60rE+XLummLRpE2tDSJF2jSFJlVwa/QuGw1KKO7Rt4vog/51sKev3EbJZQg== + dependencies: + "@endo/promise-kit" "^0.2.60" + "@fast-check/ava" "^1.1.5" + +"@endo/pass-style@^1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@endo/pass-style/-/pass-style-1.4.3.tgz#9449ce2bc297c5bcaf81fe0c4e29692b61586b52" + integrity sha512-3AGJIrflbVkvSGqSK4EAO9H2ihJ58BmzK8pp4Us5e7AJ9MH0yp5JIkYXnYI32vBUE0fJyfe2mRU06NnXJ4SX4A== + dependencies: + "@endo/env-options" "^1.1.6" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/promise-kit" "^1.1.5" + "@fast-check/ava" "^1.1.5" + +"@endo/patterns@0.2.2", "@endo/patterns@^0.2.2": version "0.2.2" resolved "https://registry.yarnpkg.com/@endo/patterns/-/patterns-0.2.2.tgz#d4c4d63bf450477ed9a9cf194b4a8daa56fcb4f4" integrity sha512-rbS4BLRohZQhB+0aEPBoxmzOfOie9nAu8Qx55Fxe8xFQKS4k9acafeIYmKh9nvslEJISYQmogy5Lewm5mgdSjg== @@ -1907,6 +2095,26 @@ "@endo/marshal" "^0.8.5" "@endo/promise-kit" "^0.2.56" +"@endo/patterns@^0.2.5": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@endo/patterns/-/patterns-0.2.6.tgz#abbbc3743ee313ffc6167d783d5fc78de74125fe" + integrity sha512-FbayXMv9sY4qP5vSaPhq9RSJmsTykImbCy0FN1YmZzaChGwOfSPOJw4898xVLDK5Xi6f+6zV02uXjuMTuZt6UA== + dependencies: + "@endo/eventual-send" "^0.17.6" + "@endo/marshal" "^0.8.9" + "@endo/promise-kit" "^0.2.60" + +"@endo/patterns@^1.4.0": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@endo/patterns/-/patterns-1.4.3.tgz#4f97c789421abc3112ed5535e535ebab24fae705" + integrity sha512-G7jy4YRRuU4ahPGW03mjqqKn7sTy20jXJTTAB/xZonaPxCVPY+4giYT2SVPC125NjvEAo2rcsW/qJtGW2GiC0A== + dependencies: + "@endo/common" "^1.2.5" + "@endo/errors" "^1.2.5" + "@endo/eventual-send" "^1.2.5" + "@endo/marshal" "^1.5.3" + "@endo/promise-kit" "^1.1.5" + "@endo/promise-kit@0.2.56", "@endo/promise-kit@^0.2.56": version "0.2.56" resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-0.2.56.tgz#24ed3cf87af1eec65f4635643b7e67617b909e71" @@ -1914,13 +2122,34 @@ dependencies: ses "^0.18.4" -"@endo/ses-ava@0.2.40", "@endo/ses-ava@^0.2.44": +"@endo/promise-kit@^0.2.60": + version "0.2.60" + resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-0.2.60.tgz#8012ada06970c7eaf965cd856563b34a1790e163" + integrity sha512-6Zp9BqBbc3ywaG+iLRrQRmO/VLKrMnvsbgOKKPMpjEC3sUlksYA09uaH3GrKZgoGChF8m9bXK8eFW39z7wJNUw== + dependencies: + ses "^0.18.8" + +"@endo/promise-kit@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-1.1.5.tgz#75f369ae967ab5ffb47f187059deea0ea50994c3" + integrity sha512-a/+z4U625idhLtTtD5s68Uk5mukcM0899rxMpc9fXhFW3S+OFw3rbZYID4MwcKNTC7TaBR1fTpW74Fj4YBsvNg== + dependencies: + ses "^1.8.0" + +"@endo/ses-ava@0.2.40": version "0.2.40" resolved "https://registry.yarnpkg.com/@endo/ses-ava/-/ses-ava-0.2.40.tgz#8a6c1f668131ecbe4d06339cac2a8346253089b8" integrity sha512-YIiAPuUfjS5dzyqeiV36FASv4YiSdkRzdxXbntNTBdOvdDymbT37SMkG0mUxD5YZRQuKMTu9xQyaGYSRqf8zaw== dependencies: ses "^0.18.4" +"@endo/ses-ava@^0.2.44": + version "0.2.44" + resolved "https://registry.yarnpkg.com/@endo/ses-ava/-/ses-ava-0.2.44.tgz#b97b0d5a457b30b73c74b19091d67840984cf47e" + integrity sha512-Pp0os/ZN7r0L94eCxWFYhSWt+DIdIASIVlY4oYCwMLxLa28cuswCjRQvPKLINBpZezogCKKptEWJTyHhGWpVQw== + dependencies: + ses "^0.18.8" + "@endo/static-module-record@^0.7.19": version "0.7.20" resolved "https://registry.yarnpkg.com/@endo/static-module-record/-/static-module-record-0.7.20.tgz#5d9583aaa8042b8a6de58c72f765e5a28e880489" @@ -1932,6 +2161,17 @@ "@babel/types" "^7.17.0" ses "^0.18.5" +"@endo/static-module-record@^0.8.2": + version "0.8.2" + resolved "https://registry.yarnpkg.com/@endo/static-module-record/-/static-module-record-0.8.2.tgz#25f66d555d1a075e5258520405410fd01fc2d1f7" + integrity sha512-wHJLX/hU/MoSFvnFN9sZ/49DYPlbASHlVQrJszeKH3xIpBtl3SG4JdRswO6RQgLREQJD/HV/ZN5V8x2bCpMu4Q== + dependencies: + "@agoric/babel-generator" "^7.17.6" + "@babel/parser" "^7.17.3" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + ses "^0.18.8" + "@endo/stream-node@0.2.26", "@endo/stream-node@^0.2.26": version "0.2.26" resolved "https://registry.yarnpkg.com/@endo/stream-node/-/stream-node-0.2.26.tgz#bf3c6ce6c506cde4468a64d220b8df4224638e16" @@ -1950,11 +2190,21 @@ "@endo/promise-kit" "^0.2.56" ses "^0.18.4" +"@endo/where@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@endo/where/-/where-0.3.5.tgz#df7661ec38ab6a327ef050aa88b50555876c39ef" + integrity sha512-y9agS7UWpSY9YSAAYwtn6sAE7zfU2BmYGOUJpw859WcmRt5ufCRi2XAXDcvIugAUPTsSVPqJj6FO3uZNVRmXPw== + "@endo/zip@0.2.31", "@endo/zip@^0.2.31": version "0.2.31" resolved "https://registry.yarnpkg.com/@endo/zip/-/zip-0.2.31.tgz#371b1a9ca8b3216ad8a3564e97e3d747be42a657" integrity sha512-rNCZtQzPm6Q8kW69gyeU0hUwKZtwuR8cX1+URgpDuUuaMUbKWBaqURKOmrqKVtE5fkqCE7pSrHvGH02DMDbDHQ== +"@endo/zip@^0.2.35": + version "0.2.35" + resolved "https://registry.yarnpkg.com/@endo/zip/-/zip-0.2.35.tgz#37a7f9266ca9c9167de5e42b55b0d9c979598d87" + integrity sha512-UM+mMZjBtJf33lXj38xXIEIe1B5wrgg/nT9CHrC8s+Pj/h63eMpQmcJzjL2vMKrvq3Tsj+TDzmQhtYcbrFACqQ== + "@es-joy/jsdoccomment@~0.41.0": version "0.41.0" resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz#4a2f7db42209c0425c71a1476ef1bdb6dcd836f6" @@ -2228,6 +2478,13 @@ dependencies: fast-check "^3.0.0" +"@fast-check/ava@^1.1.5": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@fast-check/ava/-/ava-1.2.1.tgz#4f6621d039e855cbd3ee40512f442f82913c5a31" + integrity sha512-d7O8CjYV2e+JFnN67Yofw+tt16fJI7kuX1K7OZCNxqQL5XNrkipWBmAmW9sPxYVjaItPBPvTPp7nORsO9KuBgg== + dependencies: + fast-check "^3.0.0" + "@foundry-rs/easy-foundryup@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@foundry-rs/easy-foundryup/-/easy-foundryup-0.1.3.tgz#f5281aff6b3a98f277bdafcb4330e71f80979ed4" @@ -4570,7 +4827,7 @@ chalk@5.0.1: resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w== -chalk@^2.0.0: +chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -11081,13 +11338,27 @@ serve@^14.2.1: serve-handler "6.1.5" update-check "1.5.4" -ses@1.3.0, ses@^0.18.4, ses@^0.18.5: +ses@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ses/-/ses-1.3.0.tgz#4de8a2e740e5ff9e3cdbc4fd4a3574075c493f40" integrity sha512-TURVgXm/fs38N4iJfhU9NjUiNvnU7Z/G7gVjM17jD+nrChRzMmR57fbvAzbQeGCS8Cm0m1fBs0jYCqmU6GZ7Tg== dependencies: "@endo/env-options" "^1.1.1" +ses@^0.18.4, ses@^0.18.5, ses@^0.18.8: + version "0.18.8" + resolved "https://registry.yarnpkg.com/ses/-/ses-0.18.8.tgz#88036511ac3b3c07e4d82dd8cfc6e5f3788205b6" + integrity sha512-kOH1AhJc6gWDXKURKeU1w7iFUdImAegAljVvBg5EUBgNqjH4bxcEsGVUadVEPtA2PVRMyQp1fiSMDwEZkQNj1g== + dependencies: + "@endo/env-options" "^0.1.4" + +ses@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ses/-/ses-1.8.0.tgz#8031ba3ce5bd55ced0e7a805c9cc906b9f5e29da" + integrity sha512-pis9agyAy7s9lDApaYY9OSktkzc10gkBggSbhHXwTf3cWL9H8xA7oKiXIfT/uVNf8dzZN3o2TtPYjer9/axIhw== + dependencies: + "@endo/env-options" "^1.1.6" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"