implement erc721 withdraw
MODIFY
src/interfaces/contract_init_param.ts
src/interfaces/contract_init_param.ts
export interface IContractInitParam {
address: string;
isParent: boolean;
+ /**
+ * used to get the predicate
+ *
+ * @type {string}
+ * @memberof IContractInitParam
+ */
name: string;
bridgeType?: string;
}
\ No newline at end of file

MODIFY
src/plasma/erc20.ts
src/plasma/erc20.ts
@@ -3,41 +3,26 @@ import { Log_Event_Signature } from "../enums";
import { BaseContract } from "../abstracts";
import { IPlasmaContracts, ITransactionOption } from "../interfaces";
import { BaseToken, Converter, promiseResolve, Web3SideChainClient } from "../utils";
-import { Erc20Predicate } from "./erc20_predicate";
-
-
-
-
-export class ERC20 extends BaseToken {
-
- private predicate_: BaseContract;
+import { ErcPredicate } from "./erc20_predicate";
+import { PlasmaToken } from "./plasma_token";
+export class ERC20 extends PlasmaToken {
constructor(
tokenAddress: string,
isParent: boolean,
client: Web3SideChainClient,
- private contracts_: IPlasmaContracts
+ contracts: IPlasmaContracts
) {
super({
isParent,
address: tokenAddress,
name: 'ChildERC20'
- }, client);
+ }, client, contracts);
}
getPredicate(): Promise<BaseContract> {
- if (this.predicate_) {
- return promiseResolve(this.predicate_);
- }
- return this.contracts_.registry.getContract().then(contract => {
- return contract.method("erc20Predicate").read<string>();
- }).then(predicateAddress => {
- return new Erc20Predicate(this.client, predicateAddress).getContract();
- }).then(contract => {
- this.predicate_ = contract;
- return contract;
- });
+ return this['getPredicate_']("erc721Predicate", "ERC721Predicate");
}
getBalance(userAddress: string, option: ITransactionOption = {}) {
@@ -123,14 +108,9 @@ export class ERC20 extends BaseToken {
return this.withdrawChallenge_(burnTxHash, true, option);
}
- withdrawExit(option?: ITransactionOption) {
- return this.contracts_.withdrawManager.withdrawExit(
- this.contractParam.address, option
- );
- }
-
transfer(to: string, amount: TYPE_AMOUNT, option?: ITransactionOption) {
- return this['transfer_'](to, amount, option);
+ return this['transferERC20_'](to, amount, option);
}
+
}
\ No newline at end of file

MODIFY
src/plasma/erc20_predicate.ts
src/plasma/erc20_predicate.ts
import { BaseToken, Web3SideChainClient } from "../utils";
-export class Erc20Predicate extends BaseToken {
+export class ErcPredicate extends BaseToken {
- constructor(client: Web3SideChainClient, address: string) {
+ constructor(client: Web3SideChainClient, address: string, contractName: string) {
super(
{
isParent: true,
address: address,
- name: "ERC20Predicate"
+ name: contractName // "ERC20Predicate"
},
client
);

MODIFY
src/plasma/erc721.ts
src/plasma/erc721.ts
-import { BaseToken, Web3SideChainClient } from "../utils";
-import { ITransactionOption } from "../interfaces";
-import { DepositManager } from "./deposit_manager";
+import { BaseToken, Converter, Web3SideChainClient } from "../utils";
+import { IPlasmaContracts, ITransactionOption } from "../interfaces";
+import { PlasmaToken } from "./plasma_token";
+import { Log_Event_Signature } from "../enums";
-export class ERC721 extends BaseToken {
+export class ERC721 extends PlasmaToken {
constructor(
tokenAddress: string,
isParent: boolean,
client: Web3SideChainClient,
- public depositManager: DepositManager
+ contracts: IPlasmaContracts
+
) {
super({
isParent,
address: tokenAddress,
name: 'ChildERC721'
- }, client);
+ }, client, contracts);
}
/**
@@ -64,7 +66,7 @@ export class ERC721 extends BaseToken {
const method = contract.method(
"safeTransferFrom",
userAddress,
- this.depositManager.address,
+ this.contracts_.depositManager.address,
tokenId,
);
@@ -72,20 +74,54 @@ export class ERC721 extends BaseToken {
});
}
- /**
- * WRITE
- * returns burn hash
- *
- * @param tokenId
- * @param options
- */
- startWithdrawForNFT(tokenId: number, options: ITransactionOption = {}) {
+ withdrawStart(tokenId: string | number, options: ITransactionOption = {}) {
return this.getContract().then(contract => {
const method = contract.method(
"withdraw",
- tokenId,
+ Converter.toHex(tokenId),
);
return this.processWrite(method, options);
});
}
+
+ getPredicate() {
+ return this['getPredicate_'](
+ "erc20Predicate", "ERC20Predicate"
+ );
+ }
+
+ private withdrawChallenge_(burnTxHash: string, isFast: boolean, option: ITransactionOption) {
+ return Promise.all([
+ this.getPredicate(),
+ this.contracts_.exitManager.buildPayloadForExit(
+ burnTxHash,
+ Log_Event_Signature.PlasmaErc721WithdrawEventSig,
+ isFast
+ )
+ ]).then(result => {
+ const [predicate, payload] = result;
+ const method = predicate.method(
+ "startExitWithBurntTokens",
+ payload
+ );
+ return this.processWrite(method, option);
+ });
+ }
+
+ withdrawChallenge(burnTxHash: string, option?: ITransactionOption) {
+ return this.withdrawChallenge_(burnTxHash, false, option);
+ }
+
+ withdrawChallengeFaster(burnTxHash: string, option?: ITransactionOption) {
+ return this.withdrawChallenge_(burnTxHash, true, option);
+ }
+
+ transfer(from: string, to: string, tokenId: string, option?: ITransactionOption) {
+ return this.transferERC721_(
+ from,
+ to,
+ tokenId,
+ option
+ );
+ }
}

MODIFY
src/plasma/index.ts
src/plasma/index.ts
@@ -19,7 +19,7 @@ export class PlasmaClient {
registry: RegistryContract;
rootChain: RootChain;
- private getContracts_() {
+ private getContracts__() {
return {
depositManager: this.depositManager,
exitManager: this.exitManager,
@@ -33,7 +33,7 @@ export class PlasmaClient {
tokenAddress,
isParent,
this.client_,
- this.getContracts_()
+ this.getContracts__()
);
}
@@ -42,7 +42,7 @@ export class PlasmaClient {
tokenAddress,
isParent,
this.client_,
- this.depositManager
+ this.getContracts__()
);
}
@@ -98,7 +98,7 @@ export class PlasmaClient {
}
ether(isParent?) {
- return new Ether(isParent, this.client_, this.getContracts_());
+ return new Ether(isParent, this.client_, this.getContracts__());
}
withdrawExit(tokens: string | string[], option?: ITransactionOption) {

ADD
src/plasma/plasma_token.ts
+import { BaseContract } from "../abstracts";
+import { IContractInitParam, IPlasmaContracts, ITransactionOption } from "../interfaces";
+import { BaseToken, promiseResolve, Web3SideChainClient } from "../utils";
+import { ErcPredicate } from "./erc20_predicate";
+
+export class PlasmaToken extends BaseToken {
+
+ private predicate_: BaseContract;
+
+
+ constructor(
+ contractParam_: IContractInitParam,
+ client: Web3SideChainClient,
+ protected contracts_: IPlasmaContracts
+ ) {
+ super(contractParam_, client);
+ }
+
+ private getPredicate_(methodName: string, contractName: string): Promise<BaseContract> {
+ if (this.predicate_) {
+ return promiseResolve(this.predicate_);
+ }
+ return this.contracts_.registry.getContract().then(contract => {
+ return contract.method(
+ methodName
+ ).read<string>();
+ }).then(predicateAddress => {
+ return new ErcPredicate(
+ this.client,
+ predicateAddress,
+ contractName
+ ).getContract();
+ }).then(contract => {
+ this.predicate_ = contract;
+ return contract;
+ });
+ }
+
+ withdrawExit(option?: ITransactionOption) {
+ return this.contracts_.withdrawManager.withdrawExit(
+ this.contractParam.address, option
+ );
+ }
+
+}
\ No newline at end of file

MODIFY
src/utils/base_token.ts
src/utils/base_token.ts
@@ -193,7 +193,7 @@ export class BaseToken {
}
}
- private transfer_(to: string, amount: TYPE_AMOUNT, option?: ITransactionOption) {
+ protected transferERC20_(to: string, amount: TYPE_AMOUNT, option?: ITransactionOption) {
return this.getContract().then(contract => {
const method = contract.method(
"transfer",
@@ -206,4 +206,18 @@ export class BaseToken {
});
}
+ protected transferERC721_(from: string, to: string, tokenId: string, option: ITransactionOption) {
+ return this.getContract().then(contract => {
+ const method = contract.method(
+ "transferFrom",
+ from,
+ to,
+ tokenId
+ );
+ return this.processWrite(
+ method, option
+ );
+ });
+ }
+
}
\ No newline at end of file

MODIFY
test/debug.js
test/debug.js
@@ -37,20 +37,20 @@ const execute = async () => {
const goerliERC720Token = client.erc721(plasma.parent.erc721, true);
- const balance = await goerliERC720Token.getTokenIdByIndex(
- from, 0
- );
- return console.log("balance", balance);
+ // const balance = await mumbaiERC720Token.getBalance(
+ // from
+ // );
+ // return console.log("balance", balance);
- const tx = await goerliERC720Token.safeDeposit(104, from);
- // const tx = await goerliERC720Token.withdrawChallenge('0x454f159823351b24ce0e675e7b308cc8c7ba39e175059a4d2b8f9507c17b5133');
- console.log("txHash", await tx.getTransactionHash());
- console.log("txReceipt", await tx.getReceipt());
+ // const tx = await goerliERC720Token.safeDeposit(104, from);
+ // // const tx = await goerliERC720Token.withdrawChallenge('0x454f159823351b24ce0e675e7b308cc8c7ba39e175059a4d2b8f9507c17b5133');
+ // console.log("txHash", await tx.getTransactionHash());
+ // console.log("txReceipt", await tx.getReceipt());
//txhash to plasma exit - 0x63aa095e0d6ee8698399b871daa202eb5522933e2d94c5929cf0fb86b6b0c628
const tokenId = '60399350241383852757821046101235634991156913804166740995010931519407953501076'
- // const tx = await mumbaiERC720Token.withdrawStart(32);
+ const tx = await mumbaiERC720Token.withdrawStart(104);
// console.log("tx", tx);
// const tx = await mumbaiERC720Token.withdrawStart(
// 10,
@@ -60,8 +60,8 @@ const execute = async () => {
// // gas: 100
// }
// );
- // console.log("txHash", await tx.getTransactionHash());
- // console.log("txReceipt", await tx.getReceipt());
+ console.log("txHash", await tx.getTransactionHash());
+ console.log("txReceipt", await tx.getReceipt());
}
execute().then(_ => {

implement erc721 withdraw