Skip to content

Commit

Permalink
feat: add xudt issue token template (#34)
Browse files Browse the repository at this point in the history
* wip: add xudt issue token template

* chore: fix lint

* wip: add check issued token button

* wip: add some notes

* chore: update transfer template name
  • Loading branch information
RetricSu authored Mar 4, 2024
1 parent 5173414 commit d687a84
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 101 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ ckb/devnet/data/
data/
dist/
.vscode
templates/*/ckb.ts
templates/*/config.json
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: all omnilock anyone-can-pay spore
.PHONY: all omnilock anyone-can-pay xudt spore

all: omnilock anyone-can-pay xudt spore

Expand Down
11 changes: 9 additions & 2 deletions docs/develop.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
## Development

### Add templates
### Add Dapp templates

TODO
Assuming you are trying to add a new template named `my-awesome-template` into `offckb`:

1. add your typescript project inside the `templates` folder: `templates/my-awesome-template`
2. copy `templates/ckb.ts` and `templates/config.json` into your project
- `cp templates/ckb.ts templates/my-awesome-template`
- `cp templates/config.json templates/my-awesome-template`
3. finish your `my-awesome-template` with `ckb.ts` and `config.json`
4. done

### Update built-in scripts

Expand Down
15 changes: 7 additions & 8 deletions src/cfg/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@ export async function selectTemplate() {
message: 'Select a dapp template',
choices: [
{
name: 'Transfer CKB',
name: 'View and Transfer Balance',
value: 'transfer',
description: 'a simple dapp to check CKB balance and transfer CKB from address to address',
description: 'a simple dapp to check CKB balance and transfer CKB',
},
new Separator(),
{
name: 'Issue Token With XUDT scripts(coming)',
name: 'Issue Token via XUDT scripts',
value: 'xudt',
description: 'a simple dapp to issue your own token with XUDT scripts(coming)',
disabled: true,
description: 'a simple dapp to issue your own token via XUDT scripts',
},
new Separator(),
{
name: 'Issue Token With Max Supply via Omnilock And XUDT scripts(coming)',
name: 'Issue Token With Max Supply Limit via Omnilock And XUDT scripts(coming)',
value: 'xudt',
description: 'a simple dapp to issue your own token with XUDT scripts',
description: 'a simple dapp to issue your own token with max supply limit via XUDT scripts',
disabled: true,
},
{
Expand Down
2 changes: 1 addition & 1 deletion templates/transfer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Transfer CKB</title>
<title>View and Transfer Balance</title>
</head>
<body>
<div id="root"></div>
Expand Down
2 changes: 1 addition & 1 deletion templates/transfer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function App() {

return (
<div>
<h1>Transfer CKB between addresses</h1>
<h1>View and Transfer Balance</h1>
<label htmlFor="private-key">Private Key: </label>&nbsp;
<input id="private-key" type="text" onChange={onInputPrivKey} />
<ul>
Expand Down
2 changes: 1 addition & 1 deletion templates/xudt/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>happy coding with offckb</title>
<title>Issue Custom Token</title>
</head>
<body>
<div id="root"></div>
Expand Down
69 changes: 60 additions & 9 deletions templates/xudt/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import { Script } from '@ckb-lumos/lumos';
import { capacityOf, generateAccountFromPrivateKey, transfer } from './lib';
import { Cell, Script } from '@ckb-lumos/lumos';
import {
capacityOf,
computeLockScriptHashFromPrivateKey,
generateAccountFromPrivateKey,
issueToken,
queryIssuedTokenCells,
readTokenAmount,
} from './lib';

const app = document.getElementById('root');
ReactDOM.render(<App />, app);
Expand All @@ -12,8 +19,8 @@ export function App() {
const [fromLock, setFromLock] = useState<Script>();
const [balance, setBalance] = useState('0');

const [toAddr, setToAddr] = useState('');
const [amount, setAmount] = useState('');
const [cells, setCells] = useState<Cell[]>([]);

useEffect(() => {
const updateFromInfo = async () => {
Expand All @@ -29,27 +36,71 @@ export function App() {
}
}, [privKey]);

const onInputPrivKey = (e: React.ChangeEvent<HTMLInputElement>) => {
// Regular expression to match a valid private key with "0x" prefix
const priv = e.target.value;
const privateKeyRegex = /^0x[0-9a-fA-F]{64}$/;

const isValid = privateKeyRegex.test(priv);
if (isValid) {
setPrivKey(priv);
} else {
alert(
`Invalid private key: must start with 0x and 32 bytes length. Ensure you're using a valid private key from the offckb accounts list.`,
);
}
};

const enabledIssue = +amount > 0 && +balance > 6100000000;
const enabledCheck = privKey.length > 0;
return (
<div>
<h1>
Issue Custom Token{' '}
<small>
<a href="https://github.com/XuJiandong/rfcs/blob/xudt/rfcs/0052-extensible-udt/0052-extensible-udt.md#xudt-witness">
{'(xUDT specs)'}
</a>
</small>
</h1>
<p></p>
<label htmlFor="private-key">Private Key: </label>&nbsp;
<input id="private-key" type="text" onChange={(e) => setPrivKey(e.target.value)} />
<input id="private-key" type="text" onChange={onInputPrivKey} />
<ul>
<li>CKB Address: {fromAddr}</li>
<li>
Current lock script:
<pre>{JSON.stringify(fromLock, null, 2)}</pre>
</li>

<li>Total capacity: {balance}</li>
<li>Total capacity: {(+balance).toLocaleString()}</li>
</ul>
<label htmlFor="to-address">Transfer to Address: </label>&nbsp;
<input id="to-address" type="text" onChange={(e) => setToAddr(e.target.value)} />
<br />
<label htmlFor="amount">Amount</label>
<label htmlFor="amount">Token Amount</label>
&nbsp;
<input id="amount" type="text" onChange={(e) => setAmount(e.target.value)} />
<br />
<button onClick={() => transfer({ amount, from: fromAddr, to: toAddr, privKey }).catch(alert)}>Transfer</button>
<button disabled={!enabledIssue} onClick={() => issueToken(privKey, amount).catch(alert)}>
Issue token
</button>
<br />
<br />
<hr />
<p>after issued token, click the below button to check it</p>
<button disabled={!enabledCheck} onClick={() => queryIssuedTokenCells(privKey).then(setCells).catch(alert)}>
Check issued token
</button>
{cells.length > 0 && <h3>Result: all the cells which hosted this issued token</h3>}
{cells.map((cell, index) => (
<div key={index}>
<p>Cell #{index}</p>
<p>token amount: {readTokenAmount(cell.data).toNumber()}</p>
<p>issuer lockScript Hash: {computeLockScriptHashFromPrivateKey(privKey)}</p>
<p>token xudt args: {cell.cellOutput.type.args}</p>
<p>token holder's lockScript args: {cell.cellOutput.lock.args}</p>
<hr />
</div>
))}
</div>
);
}
Loading

0 comments on commit d687a84

Please sign in to comment.