diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0750c8a..cbcff8a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,17 +7,28 @@ yarn test ``` ``` -$ yarn test -yarn run v1.22.19 +yarn run v1.22.21 $ ava --verbose - ✔ bundle-source › bundleSource() bundles the contract for use with zoe (3.3s) - ... +start proposal module evaluating +bundles/ add: assetContract from /home/connolly/projects/dapp-offer-up/contract/src/offer-up.contract.js + ✔ bundle-source › bundleSource() bundles the contract for use with zoe (1s) + ℹ 7fffb45de65f0c887401d4a5c5185ad87d41e3842d6eb2e10559a06c747358fe0dc5ef41fd4c04457c5e9bb27ed85e48ea1ff8bdeac524063b7743205f4817e6 + ℹ Object @Alleged: BundleInstallation {} +bundles/ bundled 85 files in bundle-assetContract.js at 2024-01-23T02:30:57.437Z +startOfferUpContract()... ✔ contract › Install the contract ℹ Object @Alleged: BundleInstallation {} - ✔ contract › Start the contract (1.3s) - ... - ✔ contract › Alice trades: give some play money, want some game places (1.3s) + ✔ contract › Start the contract (901ms) + ℹ terms: { + tradePrice: { + brand: Object @Alleged: PlayMoney brand {}, + value: 5n, + }, + } + ℹ Object @Alleged: InstanceHandle {} +CoreEval script: started contract Object [Alleged: InstanceHandle] {} + ✔ contract › Alice trades: give some play money, want items (939ms) ℹ Object @Alleged: InstanceHandle {} ℹ Alice gives { Price: { @@ -25,28 +36,74 @@ $ ava --verbose value: 5n, }, } - ℹ Alice payout brand Object @Alleged: Place brand {} + ℹ Alice payout brand Object @Alleged: Item brand {} ℹ Alice payout value Object @copyBag { payload: [ [ - 'Park Place', + 'scroll', 1n, ], [ - 'Boardwalk', + 'map', 1n, ], ], } - ✔ contract › Trade in IST rather than play money (8.5s) - ... - ✔ contract › use the code that will go on chain to start the contract (8.5s) - ... - +CoreEval script: share via agoricNames: Object [Alleged: Item brand] {} +offerUp (re)started +----- OfferUp.2 2 trade give { Price: { brand: Object [Alleged: PlayMoney brand] {}, value: 5n } } want Object [copyBag] { payload: [ [ 'scroll', 1n ], [ 'map', 1n ] ] } +bundles/ add: centralSupply from /home/connolly/projects/dapp-offer-up/node_modules/@agoric/vats/src/centralSupply.js +bundles/ bundled 132 files in bundle-centralSupply.js at 2024-01-23T02:30:59.505Z +----- OfferUp.2 2 trade give { + Price: { brand: Object [Alleged: ZDEFAULT brand] {}, value: 250000n } +} want Object [copyBag] { payload: [ [ 'scroll', 1n ], [ 'map', 1n ] ] } + ✔ contract › Trade in IST rather than play money (2.5s) + ℹ Alice gives { + Price: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 250000n, + }, + } + ℹ Alice payout brand Object @Alleged: Item brand {} + ℹ Alice payout value Object @copyBag { + payload: [ + [ + 'scroll', + 1n, + ], + [ + 'map', + 1n, + ], + ], + } + ✔ contract › use the code that will go on chain to start the contract (2.5s) + ℹ Alice gives { + Price: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 250000n, + }, + } + ℹ Alice payout brand Object @Alleged: Item brand {} + ℹ Alice payout value Object @copyBag { + payload: [ + [ + 'scroll', + 1n, + ], + [ + 'map', + 1n, + ], + ], + } +----- OfferUp.2 2 trade give { + Price: { brand: Object [Alleged: ZDEFAULT brand] {}, value: 250000n } +} want Object [copyBag] { payload: [ [ 'scroll', 1n ], [ 'map', 1n ] ] } ─ 6 tests passed -Done in 12.74s. +Done in 4.74s. ``` Any `Error#1: changed ...` diagnostics are benign reports of updated files diff --git a/README.md b/README.md index 97bda7e..76a9e67 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Agoric App Starter: Simple Game +# Agoric Dapp Starter: Offer Up This is a simple app for the [Agoric smart contract platform](https://docs.agoric.com/). diff --git a/_agstate/agoric-servers/package.json b/_agstate/agoric-servers/package.json index f96752b..72c4137 100644 --- a/_agstate/agoric-servers/package.json +++ b/_agstate/agoric-servers/package.json @@ -1,7 +1,7 @@ { - "name": "game-places-agservers", + "name": "offer-up-agservers", "version": "0.0.1", - "description": "Agoric server instances for dapp-game-places", + "description": "Agoric server instances for dapp-offer-up", "private": true, "type": "module", "scripts": { diff --git a/api/package.json b/api/package.json index 9c426da..d771975 100644 --- a/api/package.json +++ b/api/package.json @@ -1,5 +1,5 @@ { "$note": "@agoric/create-dapp@0.1.0 expects an api/package.json", - "name": "game-places-api", + "name": "offer-up-api", "version": "0.1.0" } diff --git a/contract/.gitignore b/contract/.gitignore index ca37d93..eb994f6 100644 --- a/contract/.gitignore +++ b/contract/.gitignore @@ -1,3 +1,3 @@ -start-game1-permit.json -start-game1.js +start-offer-up-permit.json +start-offer-up.js bundles/ diff --git a/contract/Makefile b/contract/Makefile index bcbd4a9..f2b8506 100644 --- a/contract/Makefile +++ b/contract/Makefile @@ -103,7 +103,9 @@ print-key: /root/.agoric/user1.key @agd keys show user1 -a --keyring-backend="test" @echo -start-contract: start-game1.js start-game1-permit.json install-bundles +SCRIPT=start-offer-up.js +PERMIT=start-offer-up-permit.json +start-contract: $(SCRIPT) $(PERMIT) install-bundles scripts/propose-start-contract.sh install-bundles: bundles/bundle-list @@ -111,9 +113,9 @@ install-bundles: bundles/bundle-list build-proposal: bundles/bundle-list -bundles/bundle-list start-game1.js start-game1-permit.json: +bundles/bundle-list $(SCRIPT) $(PERMIT): ./scripts/build-proposal.sh clean: - @rm -rf start-game1.js start-game1-permit.json bundles/ + @rm -rf $(SCRIPT) $(PERMIT) bundles/ diff --git a/contract/package.json b/contract/package.json index 7f2a044..1b473e8 100644 --- a/contract/package.json +++ b/contract/package.json @@ -1,8 +1,8 @@ { - "name": "game-places-contract", + "name": "offer-up-contract", "version": "0.1.0", "private": true, - "description": "Game Asset Contract", + "description": "Offer Up Contract", "type": "module", "scripts": { "start:docker": "docker compose up -d", @@ -11,7 +11,7 @@ "docker:make": "docker compose exec agd make -C /workspace/contract", "make:help": "make list", "start": "yarn docker:make clean start-contract print-key", - "build": "agoric run scripts/build-game1-start.js", + "build": "agoric run scripts/build-contract-deployer.js", "test": "ava --verbose", "lint": "eslint '**/*.js'", "lint:fix": "eslint --fix '**/*.js'" @@ -60,14 +60,14 @@ "keywords": [], "repository": { "type": "git", - "url": "git+https://github.com/agoric-labs/dapp-join-game" + "url": "git+https://github.com/Agoric/dapp-offer-up" }, "author": "Agoric", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/agoric-labs/dapp-join-game/issues" + "url": "https://github.com/Agoric/dapp-offer-up/issues" }, - "homepage": "https://github.com/agoric-labs/dapp-join-game#readme", + "homepage": "https://github.com/Agoric/dapp-offer-up#readme", "eslintConfig": { "parserOptions": { "sourceType": "module", diff --git a/contract/scripts/build-contract-deployer.js b/contract/scripts/build-contract-deployer.js new file mode 100644 index 0000000..1986482 --- /dev/null +++ b/contract/scripts/build-contract-deployer.js @@ -0,0 +1,36 @@ +/** + * @file Permission Contract Deployment builder + * + * Usage: + * agoric run build-contract-deployer.js + */ + +import { makeHelpers } from '@agoric/deploy-script-support'; +import { getManifestForOfferUp } from '../src/offer-up-proposal.js'; + +/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */ +export const offerUpProposalBuilder = async ({ publishRef, install }) => { + return harden({ + sourceSpec: '../src/offer-up-proposal.js', + getManifestCall: [ + getManifestForOfferUp.name, + { + offerUpRef: publishRef( + install( + '../src/offer-up.contract.js', + '../bundles/bundle-offer-up.js', + { + persist: true, + }, + ), + ), + }, + ], + }); +}; + +/** @type {DeployScriptFunction} */ +export default async (homeP, endowments) => { + const { writeCoreProposal } = await makeHelpers(homeP, endowments); + await writeCoreProposal('start-offer-up', offerUpProposalBuilder); +}; diff --git a/contract/scripts/build-game1-start.js b/contract/scripts/build-game1-start.js deleted file mode 100644 index 29f5f45..0000000 --- a/contract/scripts/build-game1-start.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file Proposal Builder: Start Game with non-vbank Place NFT asset - * - * Usage: - * agoric run build-game1-start.js - */ - -import { makeHelpers } from '@agoric/deploy-script-support'; -import { getManifestForGame1 } from '../src/start-game1-proposal.js'; - -/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */ -export const game1ProposalBuilder = async ({ publishRef, install }) => { - return harden({ - sourceSpec: '../src/start-game1-proposal.js', - getManifestCall: [ - getManifestForGame1.name, - { - game1Ref: publishRef( - install( - '../src/gameAssetContract.js', - '../bundles/bundle-game1.js', - { persist: true }, - ), - ), - }, - ], - }); -}; - -/** @type {DeployScriptFunction} */ -export default async (homeP, endowments) => { - const { writeCoreProposal } = await makeHelpers(homeP, endowments); - await writeCoreProposal('start-game1', game1ProposalBuilder); -}; diff --git a/contract/scripts/build-proposal.sh b/contract/scripts/build-proposal.sh index b38ede1..68bdcad 100755 --- a/contract/scripts/build-proposal.sh +++ b/contract/scripts/build-proposal.sh @@ -4,7 +4,7 @@ cd /workspace/contract mkdir -p bundles -(agoric run ./scripts/build-game1-start.js )>/tmp/,run.log +(agoric run ./scripts/build-contract-deployer.js )>/tmp/,run.log ./scripts/parseProposals.mjs bundles/bundle-list diff --git a/contract/scripts/propose-start-contract.sh b/contract/scripts/propose-start-contract.sh index d1a9271..84099ef 100755 --- a/contract/scripts/propose-start-contract.sh +++ b/contract/scripts/propose-start-contract.sh @@ -3,8 +3,8 @@ set -xueo pipefail cd /workspace/contract -SCRIPT=start-game1.js -PERMIT=start-game1-permit.json +SCRIPT=start-offer-up.js +PERMIT=start-offer-up-permit.json ls -sh "$SCRIPT" "$PERMIT" PROPOSAL=$(agd query gov proposals --output json | jq -c '.proposals | length | .+1') @@ -12,7 +12,7 @@ PROPOSAL=$(agd query gov proposals --output json | jq -c '.proposals | length | make fund-acct agd tx gov submit-proposal swingset-core-eval "$PERMIT" "$SCRIPT" \ - --title="Start Game Place Contract" --description="Evaluate $SCRIPT" \ + --title="Start Offer Up Contract" --description="Evaluate $SCRIPT" \ --deposit=10000000ubld --gas=auto --gas-adjustment=1.2 \ --from user1 --chain-id agoriclocal --keyring-backend=test \ --yes -b block diff --git a/contract/src/gameAssetContract.js b/contract/src/gameAssetContract.js deleted file mode 100644 index 90c0cfc..0000000 --- a/contract/src/gameAssetContract.js +++ /dev/null @@ -1,70 +0,0 @@ -/** @file Contract to mint and sell Place NFTs for a hypothetical game. */ -// @ts-check - -import { Far } from '@endo/far'; -import { M, getCopyBagEntries } from '@endo/patterns'; -import { AmountMath, AssetKind } from '@agoric/ertp/src/amountMath.js'; -import { AmountShape } from '@agoric/ertp/src/typeGuards.js'; -// Use the deprecated atomicRearrange API -// for compatibility with mainnet1B. -import '@agoric/zoe/exported.js'; - -import { makeTracer } from './debug.js'; - -const { Fail, quote: q } = assert; - -const trace = makeTracer('Game', true); - -/** @param {Amount<'copyBag'>} amt */ -const bagValueSize = amt => { - /** @type {[unknown, bigint][]} */ - const entries = getCopyBagEntries(amt.value); // XXX getCopyBagEntries returns any??? - const total = entries.reduce((acc, [_place, qty]) => acc + qty, 0n); - return total; -}; - -/** - * @param {ZCF<{joinPrice: Amount}>} zcf - */ -export const start = async zcf => { - const { joinPrice } = zcf.getTerms(); - - const { zcfSeat: gameSeat } = zcf.makeEmptySeatKit(); - const mint = await zcf.makeZCFMint('Place', AssetKind.COPY_BAG); - - const joinShape = harden({ - give: { Price: AmountShape }, - want: { Places: AmountShape }, - exit: M.any(), - }); - - /** @param {ZCFSeat} playerSeat */ - const joinHook = playerSeat => { - const { give, want } = playerSeat.getProposal(); - trace('join', 'give', give, 'want', want.Places.value); - - AmountMath.isGTE(give.Price, joinPrice) || - Fail`${q(give.Price)} below joinPrice of ${q(joinPrice)}}`; - - bagValueSize(want.Places) <= 3n || Fail`only 3 places allowed when joining`; - - // We use the deprecated stage/reallocate API - // so that we can test this with the version of zoe on mainnet1B. - // using atomicRearrange bloated the contract from ~1MB to ~3BM - playerSeat.decrementBy(gameSeat.incrementBy(give)); - const tmp = mint.mintGains(want); - playerSeat.incrementBy(tmp.decrementBy(want)); - zcf.reallocate(playerSeat, tmp, gameSeat); - - playerSeat.exit(true); - return 'welcome to the game'; - }; - - const publicFacet = Far('API', { - makeJoinInvitation: () => - zcf.makeInvitation(joinHook, 'join', undefined, joinShape), - }); - - return harden({ publicFacet }); -}; -harden(start); diff --git a/contract/src/start-game1-proposal.js b/contract/src/offer-up-proposal.js similarity index 63% rename from contract/src/start-game1-proposal.js rename to contract/src/offer-up-proposal.js index 53c113e..d35e1e3 100644 --- a/contract/src/start-game1-proposal.js +++ b/contract/src/offer-up-proposal.js @@ -3,7 +3,7 @@ import { E } from '@endo/far'; import { makeMarshal } from '@endo/marshal'; import { AmountMath } from '@agoric/ertp/src/amountMath.js'; -console.warn('start-game1-proposal.js module evaluating'); +console.warn('start proposal module evaluating'); const { Fail } = assert; @@ -41,48 +41,47 @@ const publishBrandInfo = async (chainStorage, board, brand) => { * * @param {BootstrapPowers} permittedPowers */ -export const startGameContract = async permittedPowers => { - console.error('startGameContract()...'); +export const startOfferUpContract = async permittedPowers => { + console.error('startOfferUpContract()...'); const { consume: { board, chainStorage, startUpgradable, zoe }, brand: { consume: { IST: istBrandP }, // @ts-expect-error dynamic extension to promise space - produce: { Place: producePlaceBrand }, + produce: { Item: produceItemBrand }, }, issuer: { consume: { IST: istIssuerP }, // @ts-expect-error dynamic extension to promise space - produce: { Place: producePlaceIssuer }, + produce: { Item: produceItemIssuer }, }, installation: { - consume: { game1: game1InstallationP }, + consume: { offerUp: offerUpInstallationP }, }, instance: { // @ts-expect-error dynamic extension to promise space - produce: { game1: produceInstance }, + produce: { offerUp: produceInstance }, }, } = permittedPowers; const istIssuer = await istIssuerP; const istBrand = await istBrandP; - // NOTE: joinPrice could be configurable - const terms = { joinPrice: AmountMath.make(istBrand, 25n * CENT) }; + const terms = { tradePrice: AmountMath.make(istBrand, 25n * CENT) }; // agoricNames gets updated each time; the promise space only once XXXXXXX - const installation = await game1InstallationP; + const installation = await offerUpInstallationP; const { instance } = await E(startUpgradable)({ installation, issuerKeywordRecord: { Price: istIssuer }, - label: 'game1', + label: 'offerUp', terms, }); - console.log('CoreEval script: started game contract', instance); + console.log('CoreEval script: started contract', instance); const { - brands: { Place: brand }, - issuers: { Place: issuer }, + brands: { Item: brand }, + issuers: { Item: issuer }, } = await E(zoe).getTerms(instance); console.log('CoreEval script: share via agoricNames:', brand); @@ -90,38 +89,38 @@ export const startGameContract = async permittedPowers => { produceInstance.reset(); produceInstance.resolve(instance); - producePlaceBrand.reset(); - producePlaceIssuer.reset(); - producePlaceBrand.resolve(brand); - producePlaceIssuer.resolve(issuer); + produceItemBrand.reset(); + produceItemIssuer.reset(); + produceItemBrand.resolve(brand); + produceItemIssuer.resolve(issuer); await publishBrandInfo(chainStorage, board, brand); - console.log('game1 (re)installed'); + console.log('offerUp (re)started'); }; /** @type { import("@agoric/vats/src/core/lib-boot").BootstrapManifest } */ -const gameManifest = { - [startGameContract.name]: { +const offerUpManifest = { + [startOfferUpContract.name]: { consume: { agoricNames: true, - board: true, // to publish boardAux info for game NFT - chainStorage: true, // to publish boardAux info for game NFT + board: true, // to publish boardAux info for NFT brand + 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 }, - installation: { consume: { game1: true } }, - issuer: { consume: { IST: true }, produce: { Place: true } }, - brand: { consume: { IST: true }, produce: { Place: true } }, - instance: { produce: { game1: true } }, + installation: { consume: { offerUp: true } }, + issuer: { consume: { IST: true }, produce: { Item: true } }, + brand: { consume: { IST: true }, produce: { Item: true } }, + instance: { produce: { offerUp: true } }, }, }; -harden(gameManifest); +harden(offerUpManifest); -export const getManifestForGame1 = ({ restoreRef }, { game1Ref }) => { +export const getManifestForOfferUp = ({ restoreRef }, { offerUpRef }) => { return harden({ - manifest: gameManifest, + manifest: offerUpManifest, installations: { - game1: restoreRef(game1Ref), + offerUp: restoreRef(offerUpRef), }, }); }; diff --git a/contract/src/offer-up.contract.js b/contract/src/offer-up.contract.js new file mode 100644 index 0000000..1c4e17e --- /dev/null +++ b/contract/src/offer-up.contract.js @@ -0,0 +1,70 @@ +/** @file Contract to mint and sell Item NFTs. */ +// @ts-check + +import { Far } from '@endo/far'; +import { M, getCopyBagEntries } from '@endo/patterns'; +import { AmountMath, AssetKind } from '@agoric/ertp/src/amountMath.js'; +import { AmountShape } from '@agoric/ertp/src/typeGuards.js'; +// Use the deprecated atomicRearrange API +// for compatibility with mainnet1B. +import '@agoric/zoe/exported.js'; + +import { makeTracer } from './debug.js'; + +const { Fail, quote: q } = assert; + +const trace = makeTracer('OfferUp', true); + +/** @param {Amount<'copyBag'>} amt */ +const bagValueSize = amt => { + /** @type {[unknown, bigint][]} */ + const entries = getCopyBagEntries(amt.value); // XXX getCopyBagEntries returns any??? + const total = entries.reduce((acc, [_, qty]) => acc + qty, 0n); + return total; +}; + +/** + * @param {ZCF<{tradePrice: Amount}>} zcf + */ +export const start = async zcf => { + const { tradePrice } = zcf.getTerms(); + + const { zcfSeat: proceeds } = zcf.makeEmptySeatKit(); + const mint = await zcf.makeZCFMint('Item', AssetKind.COPY_BAG); + + const tradeShape = harden({ + give: { Price: AmountShape }, + want: { Items: AmountShape }, + exit: M.any(), + }); + + /** @param {ZCFSeat} buyerSeat */ + const tradeHandler = buyerSeat => { + const { give, want } = buyerSeat.getProposal(); + trace('trade', 'give', give, 'want', want.Items.value); + + AmountMath.isGTE(give.Price, tradePrice) || + Fail`${q(give.Price)} below required ${q(tradePrice)}}`; + + bagValueSize(want.Items) <= 3n || Fail`only 3 items allowed in a trade`; + + // We use the deprecated stage/reallocate API + // so that we can test this with the version of zoe on mainnet1B. + // using atomicRearrange bloated the contract from ~1MB to ~3BM + buyerSeat.decrementBy(proceeds.incrementBy(give)); + const tmp = mint.mintGains(want); + buyerSeat.incrementBy(tmp.decrementBy(want)); + zcf.reallocate(buyerSeat, tmp, proceeds); + + buyerSeat.exit(true); + return 'trade complete'; + }; + + const publicFacet = Far('API', { + makeTradeInvitation: () => + zcf.makeInvitation(tradeHandler, 'trade', undefined, tradeShape), + }); + + return harden({ publicFacet }); +}; +harden(start); diff --git a/contract/test/test-bundle-source.js b/contract/test/test-bundle-source.js index 5b2ef34..eae1582 100644 --- a/contract/test/test-bundle-source.js +++ b/contract/test/test-bundle-source.js @@ -12,7 +12,7 @@ import { E, passStyleOf } from '@endo/far'; import { makeZoeKitForTest } from '@agoric/zoe/tools/setup-zoe.js'; const myRequire = createRequire(import.meta.url); -const contractPath = myRequire.resolve(`../src/gameAssetContract.js`); +const contractPath = myRequire.resolve(`../src/offer-up.contract.js`); test('bundleSource() bundles the contract for use with zoe', async t => { const bundle = await bundleSource(contractPath); diff --git a/contract/test/test-contract.js b/contract/test/test-contract.js index 44e9581..6dc1f6a 100644 --- a/contract/test/test-contract.js +++ b/contract/test/test-contract.js @@ -1,5 +1,5 @@ /** - * @file Test basic trading using the gameAssetContract. + * @file Test basic trading using the offer up contract. */ // @ts-check @@ -15,12 +15,12 @@ import { makeZoeKitForTest } from '@agoric/zoe/tools/setup-zoe.js'; import { AmountMath, makeIssuerKit } from '@agoric/ertp'; import { makeStableFaucet } from './mintStable.js'; -import { startGameContract } from '../src/start-game1-proposal.js'; +import { startOfferUpContract } from '../src/offer-up-proposal.js'; -/** @typedef {typeof import('../src/gameAssetContract.js').start} GameContractFn */ +/** @typedef {typeof import('../src/offer-up.contract.js').start} AssetContractFn */ const myRequire = createRequire(import.meta.url); -const contractPath = myRequire.resolve(`../src/gameAssetContract.js`); +const contractPath = myRequire.resolve(`../src/offer-up.contract.js`); /** @type {import('ava').TestFn>>} */ const test = anyTest; @@ -40,7 +40,7 @@ const makeTestContext = async _t => { const { zoeService: zoe, feeMintAccess } = makeZoeKitForTest(); const bundleCache = await makeNodeBundleCache('bundles/', {}, s => import(s)); - const bundle = await bundleCache.load(contractPath, 'gameAssetContract'); + const bundle = await bundleCache.load(contractPath, 'assetContract'); return { zoe, bundle, bundleCache, feeMintAccess }; }; @@ -63,10 +63,10 @@ test('Start the contract', async t => { const money = makeIssuerKit('PlayMoney'); const issuers = { Price: money.issuer }; - const terms = { joinPrice: AmountMath.make(money.brand, 5n) }; + const terms = { tradePrice: AmountMath.make(money.brand, 5n) }; t.log('terms:', terms); - /** @type {ERef>} */ + /** @type {ERef>} */ const installation = E(zoe).install(bundle); const { instance } = await E(zoe).startInstance(installation, issuers, terms); t.log(instance); @@ -74,54 +74,48 @@ test('Start the contract', async t => { }); /** - * Alice joins the game by paying the price from the contract's terms. + * Alice trades by paying the price from the contract's terms. * * @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 = ['Park Place', 'Boardwalk'], -) => { +const alice = async (t, zoe, instance, purse, choices = ['map', 'scroll']) => { const publicFacet = E(zoe).getPublicFacet(instance); // @ts-expect-error Promise seems to work const terms = await E(zoe).getTerms(instance); - const { issuers, brands, joinPrice } = terms; + const { issuers, brands, tradePrice } = terms; const choiceBag = makeCopyBag(choices.map(name => [name, 1n])); const proposal = { - give: { Price: joinPrice }, - want: { Places: AmountMath.make(brands.Place, choiceBag) }, + give: { Price: tradePrice }, + want: { Items: AmountMath.make(brands.Item, choiceBag) }, }; - const pmt = await E(purse).withdraw(joinPrice); + const pmt = await E(purse).withdraw(tradePrice); t.log('Alice gives', proposal.give); // #endregion makeProposal - const toJoin = E(publicFacet).makeJoinInvitation(); + const toTrade = E(publicFacet).makeTradeInvitation(); - const seat = E(zoe).offer(toJoin, proposal, { Price: pmt }); - const places = await E(seat).getPayout('Places'); + const seat = E(zoe).offer(toTrade, proposal, { Price: pmt }); + const items = await E(seat).getPayout('Items'); - const actual = await E(issuers.Place).getAmountOf(places); + 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.Places); + t.deepEqual(actual, proposal.want.Items); }; -test('Alice trades: give some play money, want some game places', async t => { +test('Alice trades: give some play money, want items', async t => { const { zoe, bundle } = t.context; const money = makeIssuerKit('PlayMoney'); const issuers = { Price: money.issuer }; - const terms = { joinPrice: AmountMath.make(money.brand, 5n) }; + const terms = { tradePrice: AmountMath.make(money.brand, 5n) }; - /** @type {ERef>} */ + /** @type {ERef>} */ const installation = E(zoe).install(bundle); const { instance } = await E(zoe).startInstance(installation, issuers, terms); t.log(instance); @@ -142,15 +136,15 @@ test('Trade in IST rather than play money', async t => { * @param {{ zoe: ZoeService, bundle: {} }} powers */ const startContract = async ({ zoe, bundle }) => { - /** @type {ERef>} */ + /** @type {ERef>} */ const installation = E(zoe).install(bundle); const feeIssuer = await E(zoe).getFeeIssuer(); const feeBrand = await E(feeIssuer).getBrand(); - const joinPrice = AmountMath.make(feeBrand, 25n * CENT); + const tradePrice = AmountMath.make(feeBrand, 25n * CENT); return E(zoe).startInstance( installation, { Price: feeIssuer }, - { joinPrice }, + { tradePrice }, ); }; @@ -203,14 +197,14 @@ test('use the code that will go on chain to start the contract', async t => { consume: { zoe, chainStorage, startUpgradable, board }, brand: { consume: { IST: pFor(feeBrand) }, - produce: { Place: sync.brand }, + produce: { Item: sync.brand }, }, issuer: { consume: { IST: pFor(feeIssuer) }, - produce: { Place: sync.issuer }, + produce: { Item: sync.issuer }, }, - installation: { consume: { game1: sync.installation.promise } }, - instance: { produce: { game1: sync.instance } }, + installation: { consume: { offerUp: sync.installation.promise } }, + instance: { produce: { offerUp: sync.instance } }, }; return powers; }; @@ -225,7 +219,7 @@ test('use the code that will go on chain to start the contract', async t => { // When the BLD staker governance proposal passes, // the startup function gets called. - await startGameContract(powers); + await startOfferUpContract(powers); const instance = await sync.instance.promise; // Now that we have the instance, resume testing as above. diff --git a/package.json b/package.json index abc9e60..73c5df7 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "game-places", + "name": "offer-up", "version": "0.1.0", "license": "Apache-2.0", "private": true, diff --git a/ui/package.json b/ui/package.json index 646211a..f9cdca5 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,5 +1,5 @@ { - "name": "game-places-ui", + "name": "offer-up-ui", "private": true, "version": "0.0.0", "type": "module", diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 25c7af4..6c89745 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -53,7 +53,7 @@ interface Purse { interface AppState { wallet?: Wallet; - gameInstance?: unknown; + offerUpInstance?: unknown; brands?: Record; purses?: Array; } @@ -66,7 +66,7 @@ const setup = async () => { instances => { console.log('got instances', instances); useAppStore.setState({ - gameInstance: instances.find(([name]) => name === 'game1')!.at(1), + offerUpInstance: instances.find(([name]) => name === 'offerUp')!.at(1), }); } ); @@ -94,20 +94,20 @@ const connectWallet = async () => { }; const makeOffer = (giveValue: bigint, wantChoices: Record) => { - const { wallet, gameInstance, brands } = useAppStore.getState(); - if (!gameInstance) throw Error('no contract instance'); - if (!(brands && brands.IST && brands.Place)) + 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 = { Places: { brand: brands.Place, value } }; + const want = { Items: { brand: brands.Item, value } }; const give = { Price: { brand: brands.IST, value: giveValue } }; wallet?.makeOffer( { source: 'contract', - instance: gameInstance, - publicInvitationMaker: 'makeJoinInvitation', + instance: offerUpInstance, + publicInvitationMaker: 'makeTradeInvitation', }, { give, want }, undefined, @@ -149,7 +149,7 @@ function App() { purses, })); const istPurse = purses?.find(p => p.brandPetname === 'IST'); - const placesPurse = purses?.find(p => p.brandPetname === 'Place'); + const itemsPurse = purses?.find(p => p.brandPetname === 'Item'); const tryConnectWallet = () => { connectWallet().catch(err => { @@ -204,9 +204,9 @@ function App() {
Items: - {placesPurse ? ( + {itemsPurse ? (
    - {(placesPurse.currentAmount.value as CopyBag).payload.map( + {(itemsPurse.currentAmount.value as CopyBag).payload.map( ([name, number]) => (
  • {String(number)} {name} @@ -253,7 +253,7 @@ function App() { setChoices(newChoices); }; - const WantPlaces = () => ( + const WantItems = () => ( <> @@ -298,7 +298,7 @@ function App() { const Trade = () => ( <> - + {istPurse && ( <>