Skip to content

Commit

Permalink
feat: added encodeToAddress
Browse files Browse the repository at this point in the history
the `generateAddress` is deprecated , lumos will remove it in the future
  • Loading branch information
homura committed Nov 30, 2021
1 parent 249fc3e commit c2afc82
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 6 deletions.
5 changes: 4 additions & 1 deletion packages/config-manager/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ export interface ScriptConfig {
TX_HASH: string;
INDEX: string;
DEP_TYPE: "dep_group" | "code";
/** Short ID for creating CKB address, not all scripts have short IDs. */
/**
* @deprecated the short address will be removed in the future
* Short ID for creating CKB address, not all scripts have short IDs.
*/
SHORT_ID?: number;
}

Expand Down
92 changes: 88 additions & 4 deletions packages/helpers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ export function locateCellDep(
return null;
}

/**
* @deprecated please migrate to {@link encodeToAddress}, the short format address will be removed in the future
* @param script
* @param param1
* @returns
*/
export function generateAddress(
script: Script,
{ config = undefined }: Options = {}
Expand Down Expand Up @@ -123,8 +129,42 @@ export function generateAddress(
return bech32.encode(config.PREFIX, words, BECH32_LIMIT);
}

export function encodeToAddress(
script: Script,
{ config = undefined }: Options = {}
): Address {
config = config || getConfig();

const data: number[] = [];

const hash_type = (() => {
if (script.hash_type === "data") return 0;
if (script.hash_type === "type") return 1;
if (script.hash_type === "data1") return 2;

throw new Error(`unknown hash_type ${script.hash_type}`);
})();

data.push(0x00);
data.push(...hexToByteArray(script.code_hash));
data.push(hash_type);
data.push(...hexToByteArray(script.args));

return bech32m.encode(config.PREFIX, bech32m.toWords(data), BECH32_LIMIT);
}

/**
* @deprecated please migrate to {@link encodeToAddress}, the short format address will be removed in the future
*/
export const scriptToAddress = generateAddress;

/**
* @deprecated please migrate to {@link encodeToPredefinedAddress}, the short format address will be removed in the future
* @param args
* @param scriptType
* @param options
* @returns
*/
function generatePredefinedAddress(
args: HexString,
scriptType: string,
Expand All @@ -141,13 +181,48 @@ function generatePredefinedAddress(
return generateAddress(script, { config });
}

export function encodeToPredefinedAddress(
args: HexString,
scriptType: string,
{ config = undefined }: Options = {}
) {
config = config || getConfig();
const template = config.SCRIPTS[scriptType]!;
const script: Script = {
code_hash: template.CODE_HASH,
hash_type: template.HASH_TYPE,
args,
};

return encodeToAddress(script, { config });
}

/**
* @deprecated please migrate to {@link encodeToSecp256k1Blake160Address}, the short format address will be removed in the future
* @param args
* @param param1
* @returns
*/
export function generateSecp256k1Blake160Address(
args: HexString,
{ config = undefined }: Options = {}
): Address {
return generatePredefinedAddress(args, "SECP256K1_BLAKE160", { config });
}

export function encodeToSecp256k1Blake160Address(
args: HexString,
{ config = undefined }: Options = {}
): Address {
return encodeToPredefinedAddress(args, "SECP256K1_BLAKE160", { config });
}

/**
* @deprecated
* @param args
* @param param1
* @returns
*/
export function generateSecp256k1Blake160MultisigAddress(
args: HexString,
{ config = undefined }: Options = {}
Expand All @@ -157,6 +232,15 @@ export function generateSecp256k1Blake160MultisigAddress(
});
}

export function encodeToSecp256k1Blake160MultisigAddress(
args: HexString,
{ config = undefined }: Options = {}
) {
return encodeToPredefinedAddress(args, "SECP256K1_BLAKE160_MULTISIG", {
config,
});
}

function trySeries<T extends (...args: unknown[]) => unknown>(
...fns: T[]
): ReturnType<T> {
Expand All @@ -177,17 +261,17 @@ export function parseAddress(
): Script {
config = config || getConfig();
const { prefix, words } = trySeries(
() => bech32.decode(address, BECH32_LIMIT),
() => bech32m.decode(address, BECH32_LIMIT)
() => bech32m.decode(address, BECH32_LIMIT),
() => bech32.decode(address, BECH32_LIMIT)
);
if (prefix !== config.PREFIX) {
throw Error(
`Invalid prefix! Expected: ${config.PREFIX}, actual: ${prefix}`
);
}
const data = trySeries(
() => bech32.fromWords(words),
() => bech32m.fromWords(words)
() => bech32m.fromWords(words),
() => bech32.fromWords(words)
);
switch (data[0]) {
case 0:
Expand Down
83 changes: 82 additions & 1 deletion packages/helpers/tests/generate_address_ckb2021.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import test from "ava";
import { generateAddress } from "../src";
import {
encodeToAddress,
encodeToSecp256k1Blake160Address,
encodeToSecp256k1Blake160MultisigAddress,
generateAddress,
} from "../src";
import { CKB2021, Config, predefined } from "@ckb-lumos/config-manager";
import { Script, HashType } from "@ckb-lumos/base";

Expand Down Expand Up @@ -158,3 +163,79 @@ test("full address test (hash_type = 0x02)", (t) => {
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq4nnw7qkdnnclfkg59uzn8umtfd2kwxceqkkxdwn"
);
});

test("[encodeToAddress] full address test (hash_type = 0x02)", (t) => {
const script: Script = {
code_hash:
"0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
hash_type: "data1",
args: "0xb39bbc0b3673c7d36450bc14cfcdad2d559c6c64",
};

t.is(
encodeToAddress(script, {
config: ConfigFrom("LINA"),
}),
"ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq4nnw7qkdnnclfkg59uzn8umtfd2kwxceqcydzyt"
);

t.is(
encodeToAddress(script, {
config: ConfigFrom("AGGRON4"),
}),
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq4nnw7qkdnnclfkg59uzn8umtfd2kwxceqkkxdwn"
);
});

test("[encodeToAddress] default short address (code_hash_index = 0x00)", (t) => {
const script = ScriptFrom(
"SECP256K1_BLAKE160",
"0xb39bbc0b3673c7d36450bc14cfcdad2d559c6c64"
);

t.is(
encodeToAddress(script.LINA, { config: ConfigFrom("LINA") }),
"ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqdnnw7qkdnnclfkg59uzn8umtfd2kwxceqxwquc4"
);

t.is(
encodeToAddress(script.AGGRON4, { config: ConfigFrom("AGGRON4") }),
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqdnnw7qkdnnclfkg59uzn8umtfd2kwxceqgutnjd"
);
});

test("encode predefined secp256k1 script to address", (t) => {
t.is(
encodeToSecp256k1Blake160Address(
"0xb39bbc0b3673c7d36450bc14cfcdad2d559c6c64",
{ config: ConfigFrom("LINA") }
),
"ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqdnnw7qkdnnclfkg59uzn8umtfd2kwxceqxwquc4"
);

t.is(
encodeToSecp256k1Blake160Address(
"0xb39bbc0b3673c7d36450bc14cfcdad2d559c6c64",
{ config: ConfigFrom("AGGRON4") }
),
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqdnnw7qkdnnclfkg59uzn8umtfd2kwxceqgutnjd"
);
});

test("encode predefined multi_sig secp256k1 script to address", (t) => {
t.is(
encodeToSecp256k1Blake160MultisigAddress(
"0x4fb2be2e5d0c1a3b8694f832350a33c1685d477a",
{ config: ConfigFrom("LINA") }
),
"ckb1qpw9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sq20k2lzuhgvrgacd98cxg6s5v7pdpw5w7s0mu7z2"
);

t.is(
encodeToSecp256k1Blake160MultisigAddress(
"0x4fb2be2e5d0c1a3b8694f832350a33c1685d477a",
{ config: ConfigFrom("AGGRON4") }
),
"ckt1qpw9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sq20k2lzuhgvrgacd98cxg6s5v7pdpw5w7spfh3gj"
);
});

0 comments on commit c2afc82

Please sign in to comment.