Skip to content

Support Groupless Address #235

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

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20
20.18.0
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
},
"resolutions": {
"@babel/preset-react": "7.17.12",
"@babel/plugin-transform-react-jsx": "7.17.12"
"@babel/plugin-transform-react-jsx": "7.17.12",
"@types/react": "18.2.55",
"@types/react-dom": "18.2.19",
"@types/styled-components": "5.1.34"
},
"workspaces": [
"packages/*"
Expand Down
7 changes: 4 additions & 3 deletions packages/dapp/.project.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"fullNodeVersion": "v3.6.2",
"fullNodeVersion": "v3.12.2",
"compilerOptionsUsed": {
"ignoreUnusedConstantsWarnings": false,
"ignoreUnusedVariablesWarnings": false,
"ignoreUnusedFieldsWarnings": false,
"ignoreUnusedPrivateFunctionsWarnings": false,
"ignoreUpdateFieldsCheckWarnings": false,
"ignoreCheckExternalCallerWarnings": false,
"ignoreUnusedFunctionReturnWarnings": false
"ignoreUnusedFunctionReturnWarnings": false,
"skipAbstractContractCheck": false
},
"infos": {
"Destroy": {
Expand All @@ -17,7 +18,7 @@
"codeHashDebug": ""
},
"IFungibleToken": {
"sourceFile": "../../../../../../.npm/_npx/f1b120e1b513c04c/node_modules/@alephium/web3/std/fungible_token_interface.ral",
"sourceFile": "../../../node_modules/@alephium/web3/std/fungible_token_interface.ral",
"sourceCodeHash": "62910bf11e1eeb6cb2fd468626ff606a9b06306b2b81590c3b10f6deb5966bde",
"bytecodeDebugPatch": "",
"codeHashDebug": ""
Expand Down
26 changes: 26 additions & 0 deletions packages/dapp/alephium.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Configuration } from '@alephium/cli'

const configuration: Configuration = {
networks: {
devnet: {
nodeUrl: 'http://127.0.0.1:22973',
// here we could configure which address groups to deploy the contract
privateKeys: ['a642942e67258589cd2b1822c631506632db5a12aabcf413604e785300d762a5'],
settings: undefined
},

testnet: {
nodeUrl: process.env.NODE_URL as string,
privateKeys: process.env.PRIVATE_KEYS === undefined ? [] : process.env.PRIVATE_KEYS.split(','),
settings: undefined
},

mainnet: {
nodeUrl: process.env.NODE_URL as string,
privateKeys: process.env.PRIVATE_KEYS === undefined ? [] : process.env.PRIVATE_KEYS.split(','),
settings: undefined
}
}
}

export default configuration
2 changes: 1 addition & 1 deletion packages/dapp/artifacts/Destroy.ral.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v3.6.2",
"version": "v3.12.2",
"name": "Destroy",
"bytecodeTemplate": "01010300000005{1}0d0c{0}0105",
"fieldsSig": {
Expand Down
2 changes: 1 addition & 1 deletion packages/dapp/artifacts/ShinyToken.ral.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v3.6.2",
"version": "v3.12.2",
"name": "ShinyToken",
"bytecode": "050609121b40244041404f010000000102ce0002010000000102ce0102010000000102ce0202010000000102ce0302010202020008d36ee15a7b1600b11601ab160013c3038d7ea4c68000a8010201010003d320f98f621600b0",
"codeHash": "9bdc139154d4e611dd391a5b262cc081d2519b9a3ccc95df943a98a9e3c67661",
Expand Down
2 changes: 1 addition & 1 deletion packages/dapp/artifacts/Transfer.ral.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "v3.6.2",
"version": "v3.12.2",
"name": "Transfer",
"bytecodeTemplate": "01010300000006{1}{2}0e0c{0}0104",
"fieldsSig": {
Expand Down
57 changes: 34 additions & 23 deletions packages/dapp/artifacts/ts/ShinyToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,38 @@

import {
Address,
Asset,
CallContractParams,
CallContractResult,
Contract,
ContractState,
TestContractResult,
HexString,
ContractEvent,
ContractFactory,
ContractInstance,
ContractState,
EventSubscribeOptions,
EventSubscription,
CallContractParams,
CallContractResult,
HexString,
Narrow,
SignExecuteContractMethodParams,
SignExecuteScriptTxResult,
TestContractParams,
ContractEvent,
subscribeContractEvent,
subscribeContractEvents,
testMethod,
callMethod,
multicallMethods,
fetchContractState,
Asset,
ContractInstance,
getContractEventsCurrentCount,
TestContractParamsWithoutMaps,
TestContractResult,
TestContractResultWithoutMaps,
SignExecuteContractMethodParams,
SignExecuteScriptTxResult,
signExecuteMethod,
addStdIdToFields,
callMethod,
encodeContractFields,
fetchContractState,
getContractEventsCurrentCount,
multicallMethods,
signExecuteMethod,
subscribeContractEvent,
subscribeContractEvents,
testMethod,
} from "@alephium/web3";

import { default as ShinyTokenContractJson } from "../ShinyToken.ral.json";
import { getContractByCodeHash } from "./contracts";
import { getContractByCodeHash, registerContract } from "./contracts";

// Custom types for the contract
export namespace ShinyTokenTypes {
Expand Down Expand Up @@ -205,6 +207,7 @@ export const ShinyToken = new Factory(
[]
)
);
registerContract(ShinyToken);

// Use this class to interact with the blockchain
export class ShinyTokenInstance extends ContractInstance {
Expand Down Expand Up @@ -318,14 +321,22 @@ export class ShinyTokenInstance extends ContractInstance {
},
};

async multicall<Calls extends ShinyTokenTypes.MultiCallParams>(
calls: Calls
): Promise<ShinyTokenTypes.MultiCallResults<Calls>>;
async multicall<Callss extends ShinyTokenTypes.MultiCallParams[]>(
...callss: Callss
): Promise<ShinyTokenTypes.MulticallReturnType<Callss>> {
return (await multicallMethods(
callss: Narrow<Callss>
): Promise<ShinyTokenTypes.MulticallReturnType<Callss>>;
async multicall<
Callss extends
| ShinyTokenTypes.MultiCallParams
| ShinyTokenTypes.MultiCallParams[]
>(callss: Callss): Promise<unknown> {
return await multicallMethods(
ShinyToken,
this,
callss,
getContractByCodeHash
)) as ShinyTokenTypes.MulticallReturnType<Callss>;
);
}
}
16 changes: 12 additions & 4 deletions packages/dapp/artifacts/ts/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
/* eslint-disable */

import { Contract, ContractFactory } from "@alephium/web3";
import { ShinyToken } from ".";

let contracts: ContractFactory<any>[] | undefined = undefined;
export function getContractByCodeHash(codeHash: string): Contract {

export function getAllContracts(): ContractFactory<any>[] {
return contracts ?? [];
}

export function registerContract(factory: ContractFactory<any>) {
if (contracts === undefined) {
contracts = [ShinyToken];
contracts = [factory];
} else {
contracts.push(factory);
}
const c = contracts.find((c) => c.contract.hasCodeHash(codeHash));
}
export function getContractByCodeHash(codeHash: string): Contract {
const c = contracts?.find((c) => c.contract.hasCodeHash(codeHash));
if (c === undefined) {
throw new Error("Unknown code with code hash: " + codeHash);
}
Expand Down
1 change: 1 addition & 0 deletions packages/dapp/artifacts/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
/* eslint-disable */

export * from "./ShinyToken";
export * from "./contracts";
export * from "./scripts";
5 changes: 3 additions & 2 deletions packages/dapp/artifacts/ts/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import {
ExecutableScript,
ExecuteScriptParams,
ExecuteScriptResult,
HexString,
Script,
SignerProvider,
HexString,
} from "@alephium/web3";
import { getContractByCodeHash } from "./contracts";

import { default as DestroyScriptJson } from "../Destroy.ral.json";
import { default as TransferScriptJson } from "../Transfer.ral.json";
import { getContractByCodeHash } from "./contracts";

export const Destroy = new ExecutableScript<{
shinyToken: HexString;
Expand Down
6 changes: 3 additions & 3 deletions packages/dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
"lint": "next lint"
},
"dependencies": {
"@alephium/get-extension-wallet": "^1.8.2",
"@alephium/web3": "^1.8.2",
"@alephium/get-extension-wallet": "^v2.0.0",
"@alephium/web3": "^v2.0.0",
"ethers": "^5.5.1",
"next": "^13.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@alephium/cli": "^1.8.2",
"@alephium/cli": "^v2.0.0",
"@types/node": "18.11.18",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
Expand Down
54 changes: 39 additions & 15 deletions packages/dapp/src/components/TokenDapp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
signUnsignedTx,
} from "../services/wallet.service"
import styles from "../styles/Home.module.css"
import { SubscribeOptions, subscribeToTxStatus, TxStatusSubscription, TxStatus, web3, MessageHasher, prettifyAttoAlphAmount, isHexString } from "@alephium/web3"
import { SubscribeOptions, subscribeToTxStatus, TxStatusSubscription, TxStatus, web3, MessageHasher, prettifyAttoAlphAmount, isHexString, isGrouplessAddress, TOTAL_NUMBER_OF_GROUPS } from "@alephium/web3"

type Status = "idle" | "approve" | "pending" | "success" | "failure"

Expand All @@ -36,14 +36,16 @@ export const TokenDapp: FC<{
const [transactionStatus, setTransactionStatus] = useState<Status>("idle")
const [transactionError, setTransactionError] = useState("")
const [addTokenError, setAddTokenError] = useState("")
const [transferTokenAddress, setTransferTokenAddress] = useState("")
const [destroyTokenAddress, setDestroyTokenAddress] = useState("")
const [transferTokenId, setTransferTokenId] = useState("")
const [destroyTokenId, setDestroyTokenId] = useState("")
const [tokenBalances, setTokenBalances] = useState<TokenBalance[]>([])
const [alphBalance, setAlphBalance] = useState<{ balance: string, lockedBalance: string } | undefined>()
const [mintedToken, setMintedToken] = useState<string | undefined>()
const [transferingMintedToken, setTransferingMintedToken] = useState<boolean>(false)
const [selectedTokenBalance, setSelectedTokenBalance] = useState<{ value: TokenBalance, label: string } | undefined>()
const [alephium, setAlephium] = useState<AlephiumWindowObject | undefined>(undefined)
const [selectedGroup, setSelectedGroup] = useState<number>(0)
const isGroupless = isGrouplessAddress(address)
const [withdrawTransferTo, setWithdrawTransferTo] = useState<string>("")
const [withdrawType, setWithdrawType] = useState<"withdraw-only" | "withdraw-and-transfer">("withdraw-only")

Expand Down Expand Up @@ -152,7 +154,12 @@ export const TokenDapp: FC<{
setTransactionStatus("approve")

console.log("mint", mintAmount)
const result = await mintToken(mintAmount, network)
let result
if (isGroupless) {
result = await mintToken(mintAmount, network, selectedGroup)
} else {
result = await mintToken(mintAmount, network)
}
console.log(result)

setMintedToken(result.contractInstance.address)
Expand All @@ -170,7 +177,7 @@ export const TokenDapp: FC<{
setTransactionStatus("approve")

console.log("transfer", { transferTo, transferAmount })
const result = await transferToken(transferTokenAddress, transferTo, transferAmount, network)
const result = await transferToken(transferTokenId, transferTo, transferAmount, network)
console.log(result)

setLastTransactionHash(result.txId)
Expand All @@ -186,7 +193,7 @@ export const TokenDapp: FC<{
e.preventDefault()
setTransactionStatus("approve")

const destroyTokenContractResult = await destroyTokenContract(destroyTokenAddress)
const destroyTokenContractResult = await destroyTokenContract(destroyTokenId)
setLastTransactionHash(destroyTokenContractResult.txId)

setTransactionStatus("pending")
Expand Down Expand Up @@ -300,7 +307,7 @@ export const TokenDapp: FC<{
<Select
value={selectedTokenBalance}
onChange={
(selected) => {
(selected: any) => {
selected && setSelectedTokenBalance(selected)
}
}
Expand Down Expand Up @@ -420,20 +427,37 @@ export const TokenDapp: FC<{
onChange={(e) => setMintAmount(e.target.value)}
/>

{isGroupless && (
<>
<label htmlFor="group-select">Select Group</label>
<select
id="group-select"
value={selectedGroup}
onChange={(e) => setSelectedGroup(Number(e.target.value))}
>
{Array.from({ length: TOTAL_NUMBER_OF_GROUPS }, (_, i) => i).map((group) => (
<option key={group} value={group}>
Group {group}
</option>
))}
</select>
</>
)}

<input type="submit" />
</form>
)
}
<form onSubmit={handleTransferSubmit}>
<h2 className={styles.title}>Transfer token</h2>

<label htmlFor="transfer-token-address">Token Id</label>
<label htmlFor="transfer-token-id">Token Id</label>
<input
type="text"
id="transfer-to"
id="transfer-token-id"
name="fname"
value={transferTokenAddress}
onChange={(e) => setTransferTokenAddress(e.target.value)}
value={transferTokenId}
onChange={(e) => setTransferTokenId(e.target.value)}
/>

<label htmlFor="transfer-to">To</label>
Expand All @@ -459,13 +483,13 @@ export const TokenDapp: FC<{
<form onSubmit={handleDestroyTokenSubmit}>
<h2 className={styles.title}>Destroy token contract</h2>

<label htmlFor="destroy-token-address">Token Address</label>
<label htmlFor="destroy-token-id">Token Id</label>
<input
type="text"
id="destroy-token-address"
id="destroy-token-id"
name="fname"
value={destroyTokenAddress}
onChange={(e) => setDestroyTokenAddress(e.target.value)}
value={destroyTokenId}
onChange={(e) => setDestroyTokenId(e.target.value)}
/>
<input type="submit" disabled={buttonsDisabled} value="Destroy" />
</form>
Expand Down
Loading