Skip to content
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"test": "echo \"Error: no test specified\" && exit 1",
"test:start": "npx ts-node scripts/start.ts",
"test:deploy":"npx ts-node scripts/deploy.ts",
"test:claim_ckb": "npx ts-node scripts/claim_ckb.ts",
"test:e2e": "jest tests/*.data.test.ts",
"test:stop": "npx ts-node scripts/stop.ts"
},
Expand Down
49 changes: 49 additions & 0 deletions scripts/claim_ckb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {getSecp256k1Account} from "../src/utils";
import {CKB_RPC_URL, MNEMONIC, MNEMONIC2} from "../src/constants";
import {RPC} from "@ckb-lumos/rpc";
import {Indexer} from "@ckb-lumos/ckb-indexer";
import {E2EProvider} from "../src/e2eProvider";
import {FileFaucetQueue} from "../src/faucetQueue";
import {AddressType} from "@ckb-lumos/hd";

async function main() {
console.log("---main---")
const rpc = new RPC(CKB_RPC_URL);
const indexer = new Indexer(CKB_RPC_URL);

const e2eProvider = new E2EProvider({
indexer,
rpc,
faucetQueue: FileFaucetQueue.getInstance(),
});
await e2eProvider.loadLocalConfig();

for (let i = 0; i < 500; i++) {
console.log(i)
let account = getSecp256k1Account(MNEMONIC, AddressType.Receiving, i)

await e2eProvider.claimCKB({
claimer: account.address
});

account = getSecp256k1Account(MNEMONIC, AddressType.Change, i)
await e2eProvider.claimCKB({
claimer: account.address
});

account = getSecp256k1Account(MNEMONIC2, AddressType.Receiving, i)

await e2eProvider.claimCKB({
claimer: account.address
});

account = getSecp256k1Account(MNEMONIC2, AddressType.Change, i)
await e2eProvider.claimCKB({
claimer: account.address
});

}

}

main();
2 changes: 1 addition & 1 deletion scripts/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function main() {
});
console.log("modify epoch_duration_target");
const specs_dev_path = 'specs/dev.toml';
const modify_epoch_duration_target_command = `sed -ie 's/epoch_duration_target = 14400/epoch_duration_target = 8/g' ${specs_dev_path}`;
const modify_epoch_duration_target_command = `sed -ie 's/epoch_duration_target = 14400/epoch_duration_target = 80/g' ${specs_dev_path}`;
const child = spawn(modify_epoch_duration_target_command, {shell: true, cwd: CKB_CWD});
child.on('close', (code) => {
if (code === 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const CKB_TEST_NET_RPC_URL = "https://testnet.ckbapp.dev/";
export const LUMOS_CONFIG_PATH = "lumos.json"

export const MNEMONIC = "brush scan basic know movie next time soccer speak loop balcony describe"
export const MNEMONIC2 = "equip slim poem depth struggle tonight define stool brave sustain spy cabbage"

// from docker/ckb/dev.toml [[genesis.system_cells]]
initializeConfig(predefined.AGGRON4);

Expand Down
70 changes: 48 additions & 22 deletions src/e2eProvider.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {
HexString,
Address,
utils,
Cell,
TransactionWithStatus,
Block,
Script, HashType, OutPoint, values, blockchain, CellDep
HexString,
Address,
utils,
Cell,
TransactionWithStatus,
Block,
Script, HashType, OutPoint, Output,

} from "@ckb-lumos/base";
import {
helpers,
Expand All @@ -20,6 +21,7 @@ import {
import {common, dao, deploy, MultisigScript, parseFromInfo} from "@ckb-lumos/common-scripts";
import {bytes} from "@ckb-lumos/codec";
import {Buffer} from 'buffer';
import {helpers} from "@ckb-lumos/lumos";

import {
TransactionSkeleton,
Expand Down Expand Up @@ -528,14 +530,18 @@ export class E2EProvider {
}


public async sendAndSignTxSkeleton(txSkeleton: TransactionSkeletonType, fee: number = 1000, account: Account) {
txSkeleton = await common.payFeeByFeeRate(txSkeleton, [account.address], fee);
txSkeleton = common.prepareSigningEntries(txSkeleton);
const message = txSkeleton.get("signingEntries").get(0)?.message;
const Sig = key.signRecoverable(message!, account.privKey);
const tx = sealTransaction(txSkeleton, [Sig]);
return this.rpc.sendTransaction(tx, "passthrough");
}
public async sendAndSignTxSkeleton(txSkeleton: TransactionSkeletonType, fee: number = 1000, account: Account) {
txSkeleton = await common.payFeeByFeeRate(txSkeleton, [account.address], fee);
txSkeleton = common.prepareSigningEntries(txSkeleton);
let sigs = []
for (let i = 0; i < txSkeleton.get("signingEntries").size; i++) {
let message = txSkeleton.get("signingEntries").get(i)?.message;
let Sig = key.signRecoverable(message!, account.privKey);
sigs.push(Sig)
}
let tx = sealTransaction(txSkeleton, sigs);
return this.rpc.sendTransaction(tx, "passthrough");
}

public async deployContract(options: {
account: Account,
Expand Down Expand Up @@ -624,6 +630,26 @@ export class E2EProvider {
writeFileSync(decPath, buffer)
}

public async getTransactionDetail(txHash: string) {
let transaction = await this.rpc.getTransaction(txHash)
let ret = `${txHash}\n`
for (let i = 0; i < transaction.transaction.inputs.length; i++) {
let input = transaction.transaction.inputs[i]
let cell = await this.getCellByTransactionHashAndIdx(input.previousOutput.txHash, BI.from(input.previousOutput.index).toNumber())
ret += `inputIdx:${i} address:${helpers.encodeToAddress(cell.lock)} cap:${BI.from(cell.capacity).toNumber()}\n`
}
ret += "\n"
transaction.transaction.outputs.forEach((output, idx) => {
ret += `outIdx:${idx} address:${helpers.encodeToAddress(output.lock)} cap:${BI.from(output.capacity).toNumber()}\n`
})
return ret
}

async getCellByTransactionHashAndIdx(hash: string, idx: number): Promise<Output> {
return await this.rpc.getTransaction(hash)
.then((tx) => tx.transaction.outputs[idx])
}

}

export function hexToUint8Array(hexInput: Buffer) {
Expand All @@ -645,11 +671,11 @@ export function hexToUint8Array(hexInput: Buffer) {


function checkFileExists(filePath: string): boolean {
try {
// 使用 fs.accessSync 来检查文件是否存在
fs.accessSync(filePath, fs.constants.F_OK);
return true;
} catch (error) {
return false;
}
try {
// 使用 fs.accessSync 来检查文件是否存在
fs.accessSync(filePath, fs.constants.F_OK);
return true;
} catch (error) {
return false;
}
}
44 changes: 40 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,45 @@ export const randomSecp256k1Account = (privKey?: string): Account => {
};
};

export const randomAnyOneCanPayAccount = (privKey?: string): Account => {
const _privKey = (() => {
if (privKey) {
return privKey;
}

return generateRandomPrivateKey();
})();

const pubKey = key.privateToPublic(_privKey);
const args = key.publicKeyToBlake160(pubKey);
const template = getConfig().SCRIPTS["ANYONE_CAN_PAY"]!;
const lockScript = {
codeHash: template.CODE_HASH,
hashType: template.HASH_TYPE,
args: args,
};

const address = encodeToAddress(lockScript);

return {
lockScript,
address,
pubKey,
privKey: _privKey,
};
};


export const getSecp256k1Account = (mm: string, type: AddressType, index: number): Account => {
const seed = mnemonic.mnemonicToSeedSync(mm)
const extendedPrivateKey = ExtendedPrivateKey.fromSeed(seed)
let priv = extendedPrivateKey.privateKeyInfo(AddressType.Change, index)
return randomSecp256k1Account(priv.privateKey)
const seed = mnemonic.mnemonicToSeedSync(mm)
const extendedPrivateKey = ExtendedPrivateKey.fromSeed(seed)
let priv = extendedPrivateKey.privateKeyInfo(type, index)
return randomSecp256k1Account(priv.privateKey)
}

export const getAnyOneCanPayAccount = (mm: string, type: AddressType, index: number): Account => {
const seed = mnemonic.mnemonicToSeedSync(mm)
const extendedPrivateKey = ExtendedPrivateKey.fromSeed(seed)
let priv = extendedPrivateKey.privateKeyInfo(type, index)
return randomAnyOneCanPayAccount(priv.privateKey)
}
Loading