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

CIP-0102 | Reference Implementation #848

Merged
merged 25 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e94fac5
spec outline & todo
SamDelaney Oct 9, 2023
c7142b0
spec final pass
SamDelaney Dec 5, 2023
98826c1
timelocked MP & always-fails validator
SamDelaney Dec 6, 2023
347aadf
offchain utils for env, wallet generation
SamDelaney Dec 9, 2023
1f675f5
print-utxos util
SamDelaney Dec 16, 2023
82bd0eb
WIP - initial offchain for mint & read
SamDelaney Jan 17, 2024
0a8a0e1
minor cleanup
SamDelaney Feb 27, 2024
01a05c3
fix asset txs query
SamDelaney Mar 7, 2024
c248735
organization, polish & minor logic improvements
SamDelaney Mar 14, 2024
2b0a8fd
reducible validator & common file
SamDelaney Mar 21, 2024
212d323
WIP: reducible tests
SamDelaney Apr 18, 2024
b7eb1d1
restructure directory
SamDelaney Apr 26, 2024
4deb697
Merge branch 'cip102-refimpl' of https://github.com/ikigai-github/CIP…
SamDelaney Apr 26, 2024
cad9a9e
mock frontend action routing
SamDelaney Apr 27, 2024
eff35b4
barebones offchain README
SamDelaney Apr 27, 2024
b7762e1
type system improvements
SamDelaney May 17, 2024
03a6bd6
initial reducible validator tests
SamDelaney May 20, 2024
a4d30b5
add token test & remove traces
SamDelaney May 21, 2024
80a79d0
WIP: building out the listing contract
SamDelaney Jun 6, 2024
8b7d85a
fix compile errors for simple_listing
SamDelaney Jun 12, 2024
75fe37b
WIP: bugfixes & optimizations
SamDelaney Jun 26, 2024
665500f
simple listing endpoint tests
SamDelaney Jun 26, 2024
4fa9091
update TODO.md
SamDelaney Jun 26, 2024
657a2ba
move reference implementation to new repo
SamDelaney Jun 28, 2024
c3370bc
remove .vscode settings artifact
SamDelaney Jun 28, 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
9 changes: 9 additions & 0 deletions CIP-0102/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"deno.cacheOnSave": true,
"deno.codeLens.test": false,
"deno.codeLens.referencesAllFunctions": false,
"deno.codeLens.references": false,
"deno.codeLens.implementations": false,
"deno.enable": false,
"deno.unstable": false
}
59 changes: 59 additions & 0 deletions CIP-0102/ref_impl/Spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Minting a CIP 102 compliant NFT with royalties

## Timelocked Minting Policy
- Checks
- Owner has signed tx
- Tx validity window is before MP deadline

## Validators

### Always Fails
- Checks nothing
- Returns false or throws error

### Reducible
- Checks
- tx is signed by recipient
- amount sent to recipient is < previous amount
- all other recipients remain the same
- amount
- address

## Offchain
- Constructs well formed CIP-68 & CIP-102 Datums
- Sends reference NFT & datum to arbitrary address
- Sends royalty NFT & datum to
- arbitrary address
- always-fails script
- reducible validator

# Reading a CIP 102 NFT’s royalties off chain

- Querying the datum
- Check if datum is required
- Request datum
- Fail depending on whether datum is required
- Parsing the datum


# Reading and validating against CIP 102 NFT royalties on chain

A simple listing contract which locks a CIP 102 NFT & a datum with a price & seller and must pay out royalties according to that price to be withdrawn.

## Onchain

- Royalty datum
- If empty, check if royalty is required
- Parse reference datum
- Fail if royalty field > 1
- If not, check if royalties are being paid correctly
- Fail if not
- Listing datum
- Confirm the amount is getting paid to the seller, minus royalties

## Offchain

- Find & read the requested listing datum
- Find & read the associated royalty datum using the approach above
- Calculate payments
- Construct & Submit tx
9 changes: 9 additions & 0 deletions CIP-0102/ref_impl/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- [x] Create Specification
- [x] Select Onchain Language
- [x] Minting a CIP 102 compliant NFT with royalties
- [x] Timelocked MP
- [x] Always-Fails Validator
- [x] Reducible Validator
- [x] Reading a CIP 102 NFT’s royalties off chain
- [x] Reading and validating against CIP 102 NFT royalties on chain
- [ ] Final Cleanup
5 changes: 5 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PUBLIC_CARDANO_NETWORK=Preprod
BLOCKFROST_URL=https://cardano-preprod.blockfrost.io/api/v0
BLOCKFROST_PROJECT_KEY=PLACEHOLDER
WALLET_ADDRESS=PLACEHOLDER
WALLET_PRIVATE_KEY=PLACEHOLDER
2 changes: 2 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
.vscode
56 changes: 56 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Using the CIP-102 Offchain Library

## Importing
The contents of this library are available to be imported from `index.ts` and will eventually be published to a public package manager (or two). I will add instructions here when I do.

In the meantime, you can clone or copy the contents of the `/lib/` folder wherever you need it.

## Direct Use

If you want to interact with the library directly without setting up your own project, you can run the code directly with the mock frontend defined in `scripts/mock-frontend.ts`

### Setup

- Make sure you have [Deno](https://deno.com/) installed.

- Create a Blockfrost project if you don't already have one. These are free up to a certain number of queries.

- Create a `.env` file in the parent directory with the structure defined in `.env.example`:
- Fill in the `PUBLIC_CARDANO_NETWORK` variable with "Preview", "Preprod" or "Mainnet" depending on which network you want to use.
- Fill in the corresponding `BLOCKFROST_URL`.
- Fill in the

- Set up your wallet by filling in the `WALLET_ADDRESS` and `WALLET_PRIVATE_KEY` variables.
- I recommend using `deno task generate-wallet` to generate a new wallet for testing this specifically. Once generated you can send the minimal funds you need for testing to the wallet from your hot wallet or from a testnet faucet.

To verify your setup worked, or if you want to check the contents of the wallet you have connected, I've included a handy `deno task print-utxos` script.

You should see something like this:
```
addr_test1vqhjcudw5m5pmehwtwduts2ayz2rlpm7vjq0ql6exsz6czq2gr7h8
[
{
txHash: "6b369bac955857261566812acde749t9d438032ac6633a004cceeb2c4dc5b287",
outputIndex: 7,
assets: { lovelace: 9980876490n },
address: "addr_test1vqhjcudw5m5pmehwtwduts2ayz2rlpm7vjq0ql6exsz6czq2gr7h8",
datumHash: undefined,
datum: undefined,
scriptRef: undefined
}
]
```

### Reading Royalties
You can query the royalty information for a given collection with the following query:

`deno task get-royalties [policyId]`

This does not return CIP-27 royalties.

### Minting CIP-102 Compliant NFTs
You can mint a collection with multiple CIP-68 nfts & a royalty policy with

`deno task mint-collection`

Instead of using the command line, this takes its parameters from the `mock_` prefixed consts at the start of the `testTimelockedMint` function in `mock-frontend.ts`.
11 changes: 11 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/conversion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const CIP102_ROYALTY_TOKEN_NAME = '001f4d70526f79616c7479'; // (500)Royalty

// convert from percentage to onchain royalty value
export function toOnchainRoyalty(percentage: number): number {
return Math.floor(1 / (percentage / 1000));
}

// convert from onchain royalty value to percentage
export function fromOnchainRoyalty(value: number): number {
return Math.trunc((10 / value) * 1000) / 10;
}
8 changes: 8 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"tasks": {
"generate-wallet": "deno run --allow-net --allow-read --allow-env --allow-write scripts/generate-wallet.js",
"print-utxos": "deno run --allow-net --allow-read --allow-env --allow-write scripts/print-utxos.ts",
"mint-collection": "deno run --allow-net --allow-read --allow-env --allow-write scripts/mock-frontend.ts mint-collection",
"get-royalties": "deno run --allow-net --allow-read --allow-env --allow-write scripts/mock-frontend.ts get-royalties"
}
}
116 changes: 116 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions CIP-0102/ref_impl/offchain-reference/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./lib/mint.ts"
export * from "./lib/read.ts"
export * from "./lib/types.ts"
Loading