Skip to content

Commit

Permalink
feat(core): support ACP addresses for private key signer
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanssen0 committed Sep 2, 2024
1 parent f5b5938 commit 2164efd
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-adults-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ckb-ccc/core": patch
---

feat(core): Support ACP addresses for private key signer
4 changes: 2 additions & 2 deletions packages/core/src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export abstract class Client {
return res;
}

async *findCellsOnChin(
async *findCellsOnChain(
key: ClientIndexerSearchKeyLike,
order?: "asc" | "desc",
limit = 10,
Expand Down Expand Up @@ -236,7 +236,7 @@ export abstract class Client {
yield cell;
}

for await (const cell of this.findCellsOnChin(key, order, limit)) {
for await (const cell of this.findCellsOnChain(key, order, limit)) {
if (
(await this.cache.isUnusable(cell.outPoint)) ||
foundedOutPoints.some((founded) => founded.eq(cell.outPoint))
Expand Down
22 changes: 13 additions & 9 deletions packages/core/src/signer/ckb/signerCkbPrivateKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,21 @@ export class SignerCkbPrivateKey extends SignerCkbPublicKey {

async signOnlyTransaction(txLike: TransactionLike): Promise<Transaction> {
const tx = Transaction.from(txLike);
const { script } = await this.getRecommendedAddressObj();
const info = await tx.getSignHashInfo(script, this.client);
if (!info) {
return tx;
}

const signature = await this._signMessage(info.message);
for (const { script } of await this.getAddressObjs()) {
const info = await tx.getSignHashInfo(script, this.client);
if (!info) {
return tx;
}

const signature = await this._signMessage(info.message);

const witness =
tx.getWitnessArgsAt(info.position) ?? WitnessArgs.from({});
witness.lock = signature;
tx.setWitnessArgsAt(info.position, witness);
}

const witness = tx.getWitnessArgsAt(info.position) ?? WitnessArgs.from({});
witness.lock = signature;
tx.setWitnessArgsAt(info.position, witness);
return tx;
}
}
57 changes: 49 additions & 8 deletions packages/core/src/signer/ckb/signerCkbPublicKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address } from "../../address/index.js";
import { bytesFrom } from "../../bytes/index.js";
import { Transaction, TransactionLike } from "../../ckb/index.js";
import { Script, Transaction, TransactionLike } from "../../ckb/index.js";
import { Client, KnownScript } from "../../client/index.js";
import { hashCkb } from "../../hasher/index.js";
import { Hex, HexLike, hexFrom } from "../../hex/index.js";
Expand Down Expand Up @@ -43,24 +43,65 @@ export class SignerCkbPublicKey extends Signer {
return this.publicKey;
}

async getRecommendedAddressObj(_preference?: unknown): Promise<Address> {
return Address.fromKnownScript(
this.client,
KnownScript.Secp256k1Blake160,
bytesFrom(hashCkb(this.publicKey)).slice(0, 20),
);
}

async getAddressObjs(): Promise<Address[]> {
return [
await Address.fromKnownScript(
const recommended = await this.getRecommendedAddressObj();

const addresses: Address[] = [];
let count = 0;
for await (const cell of this.client.findCells({
script: await Script.fromKnownScript(
this.client,
KnownScript.Secp256k1Blake160,
bytesFrom(hashCkb(this.publicKey)).slice(0, 20),
KnownScript.AnyoneCanPay,
recommended.script.args,
),
];
scriptType: "lock",
scriptSearchMode: "prefix",
withData: false,
})) {
if (count >= 10) {
break;
}
count += 1;

if (addresses.some(({ script }) => script.eq(cell.cellOutput.lock))) {
continue;
}

addresses.push(
Address.from({
prefix: this.client.addressPrefix,
script: cell.cellOutput.lock,
}),
);
}

return [recommended, ...addresses];
}

async prepareTransaction(txLike: TransactionLike): Promise<Transaction> {
const tx = Transaction.from(txLike);
const { script } = await this.getRecommendedAddressObj();
const addresses = await this.getAddressObjs();
await tx.addCellDepsOfKnownScripts(
this.client,
KnownScript.Secp256k1Blake160,
);
await tx.prepareSighashAllWitness(script, 65, this.client);
if (addresses.length > 1) {
await tx.addCellDepsOfKnownScripts(this.client, KnownScript.AnyoneCanPay);
}

await Promise.all(
addresses.map(({ script }) =>
tx.prepareSighashAllWitness(script, 65, this.client),
),
);
return tx;
}
}

0 comments on commit 2164efd

Please sign in to comment.