Skip to content
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

WIP: exercise to create a new token #38

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
76f37d0
docs: Updates to the description of dapp-agoric-basics in ReadMe.md
amessbee May 10, 2024
14050a5
docs: added detailed instruction to start contracts and UI.
amessbee May 10, 2024
2835527
docs: added a separate subsection for Testing with instructions
amessbee May 10, 2024
81f1f40
docs: Cleaned Contributing subsection and removed confusing links.
amessbee May 10, 2024
c882a79
docs: Added text related to dependencies on node version and vite
amessbee May 13, 2024
346f021
docs: Remove vite dependency comment
amessbee May 13, 2024
d192f04
WIP: toy code for cate token
amessbee May 13, 2024
e81b0ea
WIP: toy code for cate token
amessbee May 13, 2024
1f80e7c
WIP: toy code for cate token
amessbee May 13, 2024
58321eb
fix: zcf is being used now
amessbee May 15, 2024
1741446
fix: startContract is now accessible in proposal
amessbee May 15, 2024
022209e
fix: removed unused from test-cateCoin.js
amessbee May 15, 2024
a0ecc68
fix: removed unused from test-cateCoin.js
amessbee May 15, 2024
b2b173f
fix: added error handling
amessbee May 15, 2024
ea1a300
fix: added error handling
amessbee May 15, 2024
16f9331
fix: added error handling
amessbee May 15, 2024
d385a8f
fix: fixed error handling
amessbee May 15, 2024
2f92c41
fix: fixed for unit test
amessbee May 15, 2024
ccfb1be
fix: fixed for unit test
amessbee May 15, 2024
c0baa27
fix: unit test errors fixed
amessbee May 16, 2024
189dec1
fix: linter import order error fix
amessbee May 16, 2024
c8a5955
fix: lint warnings fix
amessbee May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 28 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
# Agoric Dapp Starter: Agoric Basics

This is a simple app for the [Agoric smart contract platform](https://docs.agoric.com/).

<img alt="Vite + React + Agoric page with Connect Wallet button"
style="border: 1px solid" width="300"
src="https://docs.agoric.com/assets/img/new_002_small2.2dfb7462.png" />

The contract lets you make an offer to give a small amount of [IST](https://inter.trade/) in exchange for
a few NFTs.
This is a basic Agoric Dapp that contains three smart contracts `postal-service`, `sell-concert-tickets`, and `swaparoo` demonstrating different scenarios which can be implemented easily using Agoric SDK. There is also a UI for `sell-concert-tickets` contract that a user can use to buy three different types of concert tickets and pay through a wallet extension in the browser.

## Getting started

See [Your First Agoric Dapp](https://docs.agoric.com/guides/getting-started/) tutorial.

## Contributing: Development, Testing

The UI is a React app started with the [vite](https://vitejs.dev/) `react-ts` template.
On top of that, we add

- Watching [blockchain state queries](https://docs.agoric.com/guides/getting-started/contract-rpc.html#querying-vstorage)
- [Signing and sending offers](https://docs.agoric.com/guides/getting-started/contract-rpc.html#signing-and-broadcasting-offers)

See [CONTRIBUTING](./CONTRIBUTING.md) for more on testing.
Make sure all the required dependecies are already installed (including node, nvm, docker, Keplr, and that your node version is set to `18.x.x` by running `nvm use 18.20.2`. See [a tutorial here](https://docs.agoric.com/guides/getting-started/) on how to install these dependecies.). Here are the steps to run `dapp-agoric-basics`:
- run `yarn install` in the `agoric-basics` directory, to install dependencies of the Dapp.
- run `yarn start:docker` to start Agoric blockchain from the container.
- run `yarn docker:logs` to to make sure blocks are being produced by viewing the Docker logs; once your logs resemble the following, stop the logs by pressing `ctrl+c`.
```
demo-agd-1 | 2023-12-27T04:08:06.384Z block-manager: block 1003 begin
demo-agd-1 | 2023-12-27T04:08:06.386Z block-manager: block 1003 commit
demo-agd-1 | 2023-12-27T04:08:07.396Z block-manager: block 1004 begin
demo-agd-1 | 2023-12-27T04:08:07.398Z block-manager: block 1004 commit
demo-agd-1 | 2023-12-27T04:08:08.405Z block-manager: block 1005 begin
demo-agd-1 | 2023-12-27T04:08:08.407Z block-manager: block 1005 commit
```
- run `yarn start:contract` to start the contracts.
- run `yarn start:ui` to start `sell-concert-tickets` contract UI.
- open a browser and navigate to `localhost:5173` to interact with the contract via UI.

To follow more detailed tutorial, go [here](https://docs.agoric.com/guides/getting-started/tutorial-dapp-agoric-basics.html).

## Testing

To perform unit tests:
-run the command `yarn test` in the root directory.
To perform end to end test
-run the command `yarn test:e2e` in the root directory.

## Contributing
See [CONTRIBUTING](./CONTRIBUTING.md) for more on contributions.
7 changes: 6 additions & 1 deletion contract/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ vote:
instance-q:
agd query vstorage data published.agoricNames.instance -o json

start-contract: start-contract-mint start-contract-swap start-contract-pay
start-contract: start-contract-mint start-contract-swap start-contract-pay start-contract-cate

start-contract-cate:
yarn node scripts/deploy-contract.js \
--install src/cateCoin.contract.js \
--eval src/cateCoin.proposal.js

start-contract-mint:
yarn node scripts/deploy-contract.js \
Expand Down
6 changes: 5 additions & 1 deletion contract/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { permit as postalServicePermit } from './src/postal-service.proposal.js'
import { permit as swapPermit } from './src/swaparoo.proposal.js';
import { permit as sellPermit } from './src/sell-concert-tickets.proposal.js';
import { permit as boardAuxPermit } from './src/platform-goals/board-aux.core.js';

import { permit as catePermit} from './src/cateCoin.proposal.js'
/**
* @param {*} opts
* @returns {import('rollup').RollupOptions}
Expand Down Expand Up @@ -89,5 +89,9 @@ const config = [
name: 'postal-service',
permit: postalServicePermit,
}),
config1({
name: 'cateCoin',
permit: catePermit,
}),
];
export default config;
100 changes: 100 additions & 0 deletions contract/src/cateCoin.contract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { AmountMath, makeIssuerKit } from '@agoric/ertp';
import { Far } from '@endo/far';

import '@agoric/zoe/exported.js';

export const start = async zcf => {
// Step 0: get an issuer kit
const {
issuer: cateIssuer,
mint: cateMint,
brand: cateBrand,
} = makeIssuerKit('cateCoin');
let currSupply = AmountMath.make(cateBrand, 0n);
const maxSupply = AmountMath.make(cateBrand, 1000_000n);
let creatorPurse;
let isInitialized = 0;

const getIssuer = () => cateIssuer;
console.log('Name of the contract : ', zcf.name);

const createInitialCoins = (myPurse, amount) => {
try {
if (isInitialized === 1) {
throw new Error('Fail - already initialized');
}

console.log('creating first coins');
isInitialized = 1;
creatorPurse = myPurse;

const cateAmount = AmountMath.make(cateBrand, amount);
if (AmountMath.isGTE(cateAmount, maxSupply)) {
throw new Error('Fail - amount exceeds maxSupply');
}

const catePayment = cateMint.mintPayment(cateAmount);
creatorPurse.deposit(catePayment);
currSupply = amount;

const currentAmount = creatorPurse.getCurrentAmount();
console.log(
'Current Amount in my purse after deposit is : ',
currentAmount,
);
return 'success';
} catch (error) {
console.error('Error in createInitialCoins:', error);
return error.message;
}
};

const mintCateCoins = (myPurse, amount) => {
try {
if (creatorPurse !== myPurse) {
throw new Error('Fail - Only creator can mint new tokens');
}
if (currSupply + amount > maxSupply) {
throw new Error('Fail - reached max supply');
}

const cateAmount = AmountMath.make(cateBrand, amount);
const catePayment = cateMint.mintPayment(cateAmount);
creatorPurse.deposit(catePayment);
currSupply += amount;

return 'success';
} catch (error) {
console.error('Error in mintCateCoins:', error);
return error.message;
}
};

const transferCateCoins = (fromPurse, toPurse, amount) => {
try {
const cateAmount = AmountMath.make(cateBrand, amount);
if (!AmountMath.isGTE(fromPurse.getCurrentAmount(), cateAmount)) {
throw new Error('Fail - not enough funds in sender account');
}

const catePayment = fromPurse.withdraw(cateAmount);
toPurse.deposit(catePayment);
return 'success';
} catch (error) {
console.error('Error in transferCateCoins:', error);
return error.message;
}
};

return {
creatorFacet: Far('Creator Facet', {
mintCateCoins,
transferCateCoins,
getIssuer,
createInitialCoins,
}),
publicFacet: Far('Public Facet', { transferCateCoins }),
};
};

harden(start);
80 changes: 80 additions & 0 deletions contract/src/cateCoin.proposal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
installContract,
startContract,
} from './platform-goals/start-contract.js';
import { allValues } from './objectTools.js';

// const { Fail } = assert;

const contractName = 'cateCoin';

/**
* Core eval script to start contract
*
* @param {BootstrapPowers} permittedPowers
* @param {*} config
*/

export const startCateCoin = async (powers, config) => {
console.log('core eval for', contractName);
// const {
// bundleID = Fail`no bundleID`,
// } = config?.options?.[contractName] ?? {};
const bundleID = config?.options?.[contractName] ?? {};
const installation = await installContract(powers, {
name: contractName,
bundleID,
});
try {
const ist = await allValues({
brand: powers.brand.consume.IST,
issuer: powers.issuer.consume.IST,
});

const terms = undefined;

await startContract(powers, {
name: contractName,
startArgs: {
installation,
issuerKeywordRecord: { Price: ist.issuer },
terms,
},
issuerNames: ['Ticket'],
});

console.log(contractName, '(re)started');
} catch (error) {
console.error(`Error starting ${contractName} contract:`, error);
throw error; // Rethrow the error after logging it
}
};

// Define a manifest object describing the contract's capabilities and permissions
export const manifest = /** @type {const} */ ({
[startCateCoin.name]: {
// Define entry for the postalService contract
consume: {
// Resources consumed by the contract
agoricNames: true, // Needs access to the agoricNames registry
namesByAddress: true, // Needs access to the namesByAddress registry
namesByAddressAdmin: true, // Needs administrative access to the namesByAddress registry
startUpgradable: true, // Allows upgrades to the contract
zoe: true, // Needs access to the Zoe service for contract execution
},
installation: {
// Capabilities provided by the contract during installation
consume: { [contractName]: true },
produce: { [contractName]: true },
},
instance: {
// Capabilities provided by the contract instance
produce: { [contractName]: true }, // Produces a "postalService" instance
},
},
});

// Define the permit object based on the manifest
export const permit = Object.values(manifest)[0];

export const main = startCateCoin;
Loading