Skip to content

Commit

Permalink
feat(common-scripts): supports inject from registered locks in dao.wi…
Browse files Browse the repository at this point in the history
…thdraw
  • Loading branch information
homura committed Jan 3, 2024
1 parent cd04929 commit abe910d
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 87 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-years-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ckb-lumos/common-scripts": minor
---

feat: support registered lock in dao operations
13 changes: 9 additions & 4 deletions packages/common-scripts/src/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ function _checkFromInfoSince(fromInfo: FromInfo, config: Config): void {
}
}

interface WithdrawOptions {
export interface WithdrawOptions {
config?: Config;
/**
* enable using non-system script in inputs
Expand Down Expand Up @@ -306,9 +306,7 @@ async function withdraw(
txSkeleton,
fromInput,
undefined,
{
config,
}
{ config }
);
} else if (isSecp256k1Blake160MultisigScript(fromLockScript, config)) {
txSkeleton = await secp256k1Blake160Multisig.setupInputCell(

Check warning on line 312 in packages/common-scripts/src/dao.ts

View workflow job for this annotation

GitHub Actions / lint-staged

Caution: `secp256k1Blake160Multisig` also has a named export `setupInputCell`. Check if you meant to write `import {setupInputCell} from './secp256k1_blake160_multisig'` instead

Check warning on line 312 in packages/common-scripts/src/dao.ts

View workflow job for this annotation

GitHub Actions / lint-staged

Caution: `secp256k1Blake160Multisig` also has a named export `setupInputCell`. Check if you meant to write `import {setupInputCell} from './secp256k1_blake160_multisig'` instead
Expand All @@ -317,6 +315,13 @@ async function withdraw(
fromInfo || generateAddress(fromLockScript, { config }),
{ config }
);
} else if (enableNonSystemScript) {
txSkeleton = await common.setupInputCell(

Check warning on line 319 in packages/common-scripts/src/dao.ts

View workflow job for this annotation

GitHub Actions / lint-staged

Caution: `common` also has a named export `setupInputCell`. Check if you meant to write `import {setupInputCell} from './common'` instead

Check warning on line 319 in packages/common-scripts/src/dao.ts

View workflow job for this annotation

GitHub Actions / lint-staged

Caution: `common` also has a named export `setupInputCell`. Check if you meant to write `import {setupInputCell} from './common'` instead
txSkeleton,
fromInput,
fromInfo || encodeToAddress(fromLockScript, { config }),
{ config }
);
}

const targetOutputIndex: number = txSkeleton.get("outputs").size - 1;
Expand Down
142 changes: 142 additions & 0 deletions packages/common-scripts/tests/dao-with-custom-lock.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import test, { afterEach, beforeEach } from "ava";
import { registerCustomLockScriptInfos } from "../src/common";
import { TestCellCollector } from "./helper";
import {
encodeToAddress,
TransactionSkeleton,
TransactionSkeletonType,
} from "@ckb-lumos/helpers";
import { Cell, Script } from "@ckb-lumos/base";
import { BI, parseUnit } from "@ckb-lumos/bi";
import { CellProvider } from "./cell_provider";
import { dao } from "../src";
import { Config, predefined } from "@ckb-lumos/config-manager";
import { hexify } from "@ckb-lumos/codec/lib/bytes";
import { Uint64 } from "@ckb-lumos/codec/lib/number";
import { randomBytes } from "node:crypto";

const { LINA } = predefined;

const nonSystemLockCodeHash = "0x" + "aa".repeat(32);

beforeEach(() => {
registerCustomLockScriptInfos([
{
codeHash: nonSystemLockCodeHash,
hashType: "type",
lockScriptInfo: {
CellCollector: TestCellCollector,
async setupInputCell(
txSkeleton: TransactionSkeletonType,
inputCell: Cell
): Promise<TransactionSkeletonType> {
txSkeleton = txSkeleton.update("inputs", (inputs) =>
inputs.push(inputCell)
);

txSkeleton = txSkeleton.update("outputs", (outputs) =>
outputs.push(inputCell)
);

return txSkeleton;
},
prepareSigningEntries(txSkeleton) {
return txSkeleton;
},
},
},
]);
});

// reset custom lock script infos
afterEach(() => {
registerCustomLockScriptInfos([]);
});

test("deposit from the non-system script", async (t) => {
const fromScript: Script = {
codeHash: nonSystemLockCodeHash,
hashType: "type",
args: "0x",
};

const toScript: Script = {
codeHash: "0x" + "bb".repeat(32),
hashType: "type",
args: "0x",
};
const nonSystemLockCell = {
cellOutput: {
capacity: parseUnit("5000000", "ckb").toHexString(),
lock: fromScript,
},
data: "0x",
};
let txSkeleton = TransactionSkeleton({
cellProvider: new CellProvider([nonSystemLockCell]),
});

txSkeleton = await dao.deposit(
txSkeleton,
encodeToAddress(fromScript),
encodeToAddress(toScript),
parseUnit("10000", "ckb"),
{ enableNonSystemScript: true }
);

t.deepEqual(txSkeleton.get("inputs").get(0), nonSystemLockCell);
t.is(txSkeleton.get("outputs").size, 2);
t.deepEqual(txSkeleton.get("outputs").get(0)?.cellOutput, {
capacity: parseUnit("10000", "ckb").toHexString(),
lock: toScript,
type: generateDaoTypeScript(LINA),
});
t.deepEqual(txSkeleton.get("outputs").get(1)?.cellOutput, {
capacity: BI.from(nonSystemLockCell.cellOutput.capacity)
.sub(parseUnit("10000", "ckb"))
.toHexString(),
lock: fromScript,
type: undefined,
});
});

test("withdraw with registered lock script", async (t) => {
const fromScript: Script = {
codeHash: nonSystemLockCodeHash,
hashType: "type",
args: "0x",
};

const nonSystemLockCell: Cell = {
cellOutput: {
capacity: parseUnit("5000000", "ckb").toHexString(),
lock: fromScript,
type: generateDaoTypeScript(LINA),
},
data: hexify(Uint64.pack(0)),
blockHash: hexify(randomBytes(32)),
blockNumber: "0x123456",
outPoint: { txHash: hexify(randomBytes(32)), index: "0x0" },
};
let txSkeleton = TransactionSkeleton({
cellProvider: new CellProvider([nonSystemLockCell]),
});

txSkeleton = await dao.withdraw(txSkeleton, nonSystemLockCell, undefined, {
enableNonSystemScript: true,
});

t.deepEqual(txSkeleton.inputs.get(-1), nonSystemLockCell);
t.deepEqual(txSkeleton.outputs.get(-1), {
...nonSystemLockCell,
data: hexify(Uint64.pack(0x123456)),
});
});

const generateDaoTypeScript = (config: Config): Script => {
return {
codeHash: config.SCRIPTS.DAO!.CODE_HASH,
hashType: config.SCRIPTS.DAO!.HASH_TYPE,
args: "0x",
};
};
84 changes: 1 addition & 83 deletions packages/common-scripts/tests/dao.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import test from "ava";
import { CellProvider } from "./cell_provider";
import {
encodeToAddress,
TransactionSkeleton,
TransactionSkeletonType,
} from "@ckb-lumos/helpers";
Expand All @@ -17,9 +16,7 @@ import {
bobSecpDaoDepositInput,
bobSecpDaoWithdrawInput,
} from "./inputs";
import { BI, parseUnit } from "@ckb-lumos/bi";
import { registerCustomLockScriptInfos } from "../src/common";
import { TestCellCollector } from "./helper";
import { BI } from "@ckb-lumos/bi";

const cellProvider = new CellProvider(inputs());
let txSkeleton: TransactionSkeletonType = TransactionSkeleton({ cellProvider });
Expand Down Expand Up @@ -77,85 +74,6 @@ test("deposit secp256k1_blake160", async (t) => {
);
});

test("deposit from the non-system script", async (t) => {
const nonSystemLockCodeHash = "0x" + "aa".repeat(32);

registerCustomLockScriptInfos([
{
codeHash: nonSystemLockCodeHash,
hashType: "type",
lockScriptInfo: {
CellCollector: TestCellCollector,
async setupInputCell(
txSkeleton: TransactionSkeletonType,
inputCell: Cell
): Promise<TransactionSkeletonType> {
txSkeleton = txSkeleton.update("inputs", (inputs) =>
inputs.push(inputCell)
);

txSkeleton = txSkeleton.update("outputs", (outputs) =>
outputs.push(inputCell)
);

return txSkeleton;
},
prepareSigningEntries(txSkeleton) {
return txSkeleton;
},
},
},
]);

const fromScript: Script = {
codeHash: nonSystemLockCodeHash,
hashType: "type",
args: "0x",
};

const toScript: Script = {
codeHash: "0x" + "bb".repeat(32),
hashType: "type",
args: "0x",
};
const nonSystemLockCell = {
cellOutput: {
capacity: parseUnit("5000000", "ckb").toHexString(),
lock: fromScript,
},
data: "0x",
};
let txSkeleton = TransactionSkeleton({
cellProvider: new CellProvider([nonSystemLockCell]),
});

txSkeleton = await dao.deposit(
txSkeleton,
encodeToAddress(fromScript),
encodeToAddress(toScript),
parseUnit("10000", "ckb"),
{ enableNonSystemScript: true }
);

t.deepEqual(txSkeleton.get("inputs").get(0), nonSystemLockCell);
t.is(txSkeleton.get("outputs").size, 2);
t.deepEqual(txSkeleton.get("outputs").get(0)?.cellOutput, {
capacity: parseUnit("10000", "ckb").toHexString(),
lock: toScript,
type: generateDaoTypeScript(LINA),
});
t.deepEqual(txSkeleton.get("outputs").get(1)?.cellOutput, {
capacity: BI.from(nonSystemLockCell.cellOutput.capacity)
.sub(parseUnit("10000", "ckb"))
.toHexString(),
lock: fromScript,
type: undefined,
});

// reset custom lock script infos
registerCustomLockScriptInfos([]);
});

test("withdraw secp256k1_blake160", async (t) => {
txSkeleton = await dao.deposit(
txSkeleton,
Expand Down

0 comments on commit abe910d

Please sign in to comment.