Last active
June 9, 2021 10:55
-
-
Save e00dan/84f2a5afcb636d680cc564a4ab63a340 to your computer and use it in GitHub Desktop.
deposit-sudt.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
DeploymentConfig, | |
deploymentConfig, | |
} from "../modules/deployment-config"; | |
import { HexString, Script, Hash, utils } from "@ckb-lumos/base"; | |
import { Indexer } from "@ckb-lumos/indexer"; | |
import { | |
TransactionSkeleton, | |
parseAddress, | |
sealTransaction, | |
generateAddress, | |
} from "@ckb-lumos/helpers"; | |
import { | |
generateDepositionLock, | |
DepositionLockArgs, | |
getDepositionLockArgs, | |
serializeArgs, | |
getRollupTypeHash, | |
} from "../modules/deposition"; | |
import { common, sudt } from "@ckb-lumos/common-scripts"; | |
import { key, Keychain } from "@ckb-lumos/hd"; | |
import { RPC } from "ckb-js-toolkit"; | |
import commander from "commander"; | |
import { | |
privateKeyToCkbAddress, | |
privateKeyToEthAddress, | |
} from "../modules/utils"; | |
import { initConfigAndSync, waitForDeposit, waitTxCommitted } from "./common"; | |
import { Godwoken } from "@godwoken-examples/godwoken"; | |
import { | |
getBalanceByScriptHash, | |
ethAddressToScriptHash, | |
} from "../modules/godwoken"; | |
import { Buffer } from 'buffer'; | |
async function sendTx( | |
godwoken: Godwoken, | |
deploymentConfig: DeploymentConfig, | |
fromAddress: string, | |
amount: string, | |
layer2LockArgs: HexString, | |
indexer: Indexer, | |
privateKey: HexString, | |
ckbUrl: string, | |
sudtToken: HexString, | |
capacity?: bigint | |
): Promise<[Hash, Hash]> { | |
let txSkeleton = TransactionSkeleton({ cellProvider: indexer }); | |
const ownerLock: Script = parseAddress(fromAddress); | |
const ownerLockHash: Hash = utils.computeScriptHash(ownerLock); | |
const layer2Lock: Script = { | |
code_hash: deploymentConfig.eth_account_lock.code_hash, | |
hash_type: deploymentConfig.eth_account_lock.hash_type as "data" | "type", | |
args: getRollupTypeHash() + layer2LockArgs.slice(2), | |
}; | |
const depositionLockArgs: DepositionLockArgs = getDepositionLockArgs( | |
ownerLockHash, | |
layer2Lock | |
); | |
console.log( | |
`Layer 2 lock script hash: ${utils.computeScriptHash( | |
depositionLockArgs.layer2_lock | |
)}` | |
); | |
console.log("↑ Using this script hash to get user account id ↑"); | |
const serializedArgs: HexString = serializeArgs(depositionLockArgs); | |
const depositionLock: Script = generateDepositionLock( | |
deploymentConfig, | |
serializedArgs | |
); | |
const toAddress: string = generateAddress(depositionLock); | |
txSkeleton = await sudt.transfer( | |
txSkeleton, | |
[fromAddress], | |
sudtToken, | |
toAddress, | |
BigInt(amount), | |
undefined, | |
capacity, | |
undefined, | |
{ | |
splitChangeCell: true, | |
} | |
); | |
const sudtScriptHash = utils.computeScriptHash( | |
txSkeleton.get("outputs").get(0)!.cell_output.type! | |
); | |
console.log(`Layer 1 sudt script hash:`, sudtScriptHash); | |
const scriptHash = await godwoken.getScriptHash(1); | |
const script = await godwoken.getScript(scriptHash); | |
const layer2SudtScript = { | |
code_hash: script.code_hash, | |
hash_type: script.hash_type, | |
args: getRollupTypeHash() + sudtScriptHash.slice(2), | |
}; | |
console.log("layer 2 sudt script:", layer2SudtScript); | |
const layer2SudtScriptHash = utils.computeScriptHash(layer2SudtScript); | |
console.log(`Layer 2 sudt script hash:`, layer2SudtScriptHash); | |
console.log("↑ Using this script hash to get sudt account id ↑"); | |
txSkeleton = await common.payFeeByFeeRate( | |
txSkeleton, | |
[fromAddress], | |
BigInt(1000) | |
); | |
txSkeleton = common.prepareSigningEntries(txSkeleton); | |
const message: HexString = txSkeleton.get("signingEntries").get(0)!.message; | |
const content: HexString = key.signRecoverable(message, privateKey); | |
const tx = sealTransaction(txSkeleton, [content]); | |
const rpc = new RPC(ckbUrl); | |
const txHash: Hash = await rpc.send_transaction(tx); | |
return [txHash, layer2SudtScriptHash]; | |
} | |
export const run = async (program: commander.Command) => { | |
const ckbRpc = new RPC(program.rpc); | |
const indexerPath = program.indexerPath; | |
const indexer = await initConfigAndSync(program.rpc, indexerPath); | |
let privateKey: string = program.privateKey; | |
let ckbAddress = privateKeyToCkbAddress(privateKey); | |
let ckbAddressDescription = ''; | |
const useBip44 = program.bip44; | |
if (useBip44) { | |
if (!program.chainCode) { | |
throw new Error('BIP44 chain code is required. Please supply -cc <chainCode> option.'); | |
} | |
const chainCode = Buffer.from(program.chainCode.slice(2), 'hex'); | |
const path = program.bipPath; | |
const keychain = new Keychain(Buffer.from(privateKey.slice(2), "hex"), chainCode); | |
const derived = keychain.derivePath(path); | |
const childPrivateKey = '0x' + derived.privateKey.toString('hex'); | |
ckbAddress = privateKeyToCkbAddress(childPrivateKey); | |
ckbAddressDescription = ` (BIP44 path ${path})`; | |
} | |
console.log(`using ckb address: ${ckbAddress}${ckbAddressDescription}`) | |
const ethAddress = program.ethAddress || privateKeyToEthAddress(privateKey); | |
console.log("using eth address:", ethAddress); | |
const capacity: bigint = BigInt(program.capacity); | |
if (capacity < BigInt(40000000000)) { | |
throw new Error("capacity can't less than 400 CKB"); | |
} | |
const godwokenRpc = program.parent.godwokenRpc; | |
const godwoken = new Godwoken( | |
godwokenRpc, | |
program.parent.prefixWithGw !== false | |
); | |
try { | |
const [txHash, layer2SudtScriptHash] = await sendTx( | |
godwoken, | |
deploymentConfig, | |
ckbAddress, | |
program.amount, | |
ethAddress.toLowerCase(), | |
indexer, | |
privateKey, | |
program.rpc, | |
program.sudtScriptArgs, | |
capacity | |
); | |
console.log("txHash:", txHash); | |
console.log("--------- wait for tx deposition ----------"); | |
await waitTxCommitted(txHash, ckbRpc); | |
const accountScriptHash = ethAddressToScriptHash(ethAddress); | |
const currentBalance = await getBalanceByScriptHash( | |
godwoken, | |
1, | |
accountScriptHash | |
); | |
await waitForDeposit( | |
godwoken, | |
accountScriptHash, | |
currentBalance, | |
layer2SudtScriptHash | |
); | |
process.exit(0); | |
} catch (e) { | |
console.error(e); | |
process.exit(1); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment