Skip to content

Commit

Permalink
Merge pull request #1868 from mintlayer/feature/wasm-lib-extended-pub…
Browse files Browse the repository at this point in the history
…lic-key

Add extended public key functions to WASM lib
  • Loading branch information
OBorce authored Feb 5, 2025
2 parents 6d15675 + bf41f13 commit a646f4a
Show file tree
Hide file tree
Showing 3 changed files with 409 additions and 62 deletions.
50 changes: 48 additions & 2 deletions wasm-wrappers/WASM-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ derivation path: 44'/mintlayer_coin_type'/0'
### Function: `make_receiving_address`

From an extended private key create a receiving private key for a given key index
derivation path: 44'/mintlayer_coin_type'/0'/0/key_index
derivation path: current_derivation_path/0/key_index

### Function: `make_change_address`

From an extended private key create a change private key for a given key index
derivation path: 44'/mintlayer_coin_type'/0'/1/key_index
derivation path: current_derivation_path/1/key_index

### Function: `pubkey_to_pubkeyhash_address`

Expand All @@ -33,6 +33,20 @@ return the address public key hash from that public key as an address

Given a private key, as bytes, return the bytes of the corresponding public key

### Function: `extended_public_key_from_extended_private_key`

Return the extended public key from an extended private key

### Function: `make_receiving_address_public_key`

From an extended public key create a receiving public key for a given key index
derivation path: current_derivation_path/0/key_index

### Function: `make_change_address_public_key`

From an extended public key create a change public key for a given key index
derivation path: current_derivation_path/1/key_index

### Function: `sign_message_for_spending`

Given a message and a private key, sign the message with the given private key
Expand Down Expand Up @@ -312,6 +326,34 @@ It is recommended to use a strict `Transaction` size and set the second paramete
Calculate the "effective balance" of a pool, given the total pool balance and pledge by the pool owner/staker.
The effective balance is how the influence of a pool is calculated due to its balance.

### Function: `encode_input_for_mint_tokens`

Given a token_id, an amount of tokens to mint and nonce return an encoded mint tokens input

### Function: `encode_input_for_unmint_tokens`

Given a token_id and nonce return an encoded unmint tokens input

### Function: `encode_input_for_lock_token_supply`

Given a token_id and nonce return an encoded lock_token_supply input

### Function: `encode_input_for_freeze_token`

Given a token_id, is token unfreezable and nonce return an encoded freeze token input

### Function: `encode_input_for_unfreeze_token`

Given a token_id and nonce return an encoded unfreeze token input

### Function: `encode_input_for_change_token_authority`

Given a token_id, new authority destination and nonce return an encoded change token authority input

### Function: `encode_input_for_change_token_metadata_uri`

Given a token_id, new metadata uri and nonce return an encoded change token metadata uri input

### Function: `encode_create_order_output`

Given ask and give amounts and a conclude key create output that creates an order.
Expand All @@ -336,6 +378,10 @@ The network, for which an operation to be done. Mainnet, testnet, etc.

Indicates whether a token can be frozen

### Enum: `TokenUnfreezable`

Indicates whether a token can be unfrozen once frozen

### Enum: `TotalSupply`

The token supply of a specific token, set on issuance
Expand Down
160 changes: 149 additions & 11 deletions wasm-wrappers/js-bindings/wasm_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import {
make_receiving_address,
make_change_address,
pubkey_to_pubkeyhash_address,
make_receiving_address_public_key,
make_change_address_public_key,
extended_public_key_from_extended_private_key,
Network,
encode_input_for_utxo,
encode_output_coin_burn,
Expand Down Expand Up @@ -53,6 +56,14 @@ import {
make_transaction_intent_message_to_sign,
encode_signed_transaction_intent,
verify_transaction_intent,
encode_input_for_mint_tokens,
encode_input_for_unmint_tokens,
encode_input_for_lock_token_supply,
encode_input_for_freeze_token,
TokenUnfreezable,
encode_input_for_unfreeze_token,
encode_input_for_change_token_authority,
encode_input_for_change_token_metadata_uri,
} from "../pkg/wasm_wrappers.js";

function assert_eq_arrays(arr1, arr2) {
Expand Down Expand Up @@ -167,18 +178,20 @@ export async function run_test() {
const mnemonic =
"walk exile faculty near leg neutral license matrix maple invite cupboard hat opinion excess coffee leopard latin regret document core limb crew dizzy movie";
{
const account_pubkey = make_default_account_privkey(
const account_private_key = make_default_account_privkey(
mnemonic,
Network.Mainnet
);
console.log(`acc pubkey = ${account_pubkey}`);
console.log(`acc private key = ${account_private_key}`);

const receiving_privkey = make_receiving_address(account_pubkey, 0);
const extended_public_key = extended_public_key_from_extended_private_key(account_private_key);

const receiving_privkey = make_receiving_address(account_private_key, 0);
console.log(`receiving privkey = ${receiving_privkey}`);

// test bad key index
try {
make_receiving_address(account_pubkey, 1 << 31);
make_receiving_address(account_private_key, 1 << 31);
throw new Error("Invalid key index worked somehow!");
} catch (e) {
if (!e.includes("Invalid key index, MSB bit set")) {
Expand All @@ -188,6 +201,9 @@ export async function run_test() {
}

const receiving_pubkey = public_key_from_private_key(receiving_privkey);
const receiving_pubkey2 = make_receiving_address_public_key(extended_public_key, 0);
assert_eq_arrays(receiving_pubkey, receiving_pubkey2);

const address = pubkey_to_pubkeyhash_address(
receiving_pubkey,
Network.Mainnet
Expand All @@ -197,12 +213,12 @@ export async function run_test() {
throw new Error("Incorrect address generated");
}

const change_privkey = make_change_address(account_pubkey, 0);
console.log(`receiving privkey = ${change_privkey}`);
const change_privkey = make_change_address(account_private_key, 0);
console.log(`change privkey = ${change_privkey}`);

// test bad key index
try {
make_change_address(account_pubkey, 1 << 31);
make_change_address(account_private_key, 1 << 31);
throw new Error("Invalid key index worked somehow!");
} catch (e) {
if (!e.includes("Invalid key index, MSB bit set")) {
Expand All @@ -212,6 +228,9 @@ export async function run_test() {
}

const change_pubkey = public_key_from_private_key(change_privkey);
const change_pubkey2 = make_change_address_public_key(extended_public_key, 0);
assert_eq_arrays(change_pubkey, change_pubkey2);

const caddress = pubkey_to_pubkeyhash_address(
change_pubkey,
Network.Mainnet
Expand All @@ -224,13 +243,13 @@ export async function run_test() {

{
// Test generating an address for Testnet
const account_pubkey = make_default_account_privkey(
const account_private_key = make_default_account_privkey(
mnemonic,
Network.Testnet
);
console.log(`acc pubkey = ${account_pubkey}`);
console.log(`acc private key = ${account_private_key}`);

const receiving_privkey = make_receiving_address(account_pubkey, 0);
const receiving_privkey = make_receiving_address(account_private_key, 0);
console.log(`receiving privkey = ${receiving_privkey}`);

const receiving_pubkey = public_key_from_private_key(receiving_privkey);
Expand Down Expand Up @@ -790,6 +809,125 @@ export async function run_test() {
);
console.log("htlc with tokens encoding ok");

const mint_tokens_input = encode_input_for_mint_tokens(
token_id,
Amount.from_atoms("100"),
BigInt(1),
Network.Testnet
);
const expected_mint_tokens_input = [
2, 4, 0, 162, 208, 145, 194, 165, 27,
14, 118, 31, 139, 199, 254, 11, 190, 108,
15, 64, 180, 50, 106, 211, 26, 107, 242,
121, 29, 55, 172, 185, 5, 196, 119, 145,
1
];

assert_eq_arrays(mint_tokens_input, expected_mint_tokens_input);
console.log("mint tokens encoding ok");

const unmint_tokens_input = encode_input_for_unmint_tokens(
token_id,
BigInt(2),
Network.Testnet
);
const expected_unmint_tokens_input = [
2, 8, 1, 162, 208, 145, 194, 165,
27, 14, 118, 31, 139, 199, 254, 11,
190, 108, 15, 64, 180, 50, 106, 211,
26, 107, 242, 121, 29, 55, 172, 185,
5, 196, 119
];

assert_eq_arrays(unmint_tokens_input, expected_unmint_tokens_input);
console.log("unmint tokens encoding ok");

const lock_token_supply_input = encode_input_for_lock_token_supply(
token_id,
BigInt(2),
Network.Testnet
);
const expected_lock_token_supply_input = [
2, 8, 2, 162, 208, 145, 194, 165,
27, 14, 118, 31, 139, 199, 254, 11,
190, 108, 15, 64, 180, 50, 106, 211,
26, 107, 242, 121, 29, 55, 172, 185,
5, 196, 119
];

assert_eq_arrays(lock_token_supply_input, expected_lock_token_supply_input);
console.log("lock token supply encoding ok");

const freeze_token_input = encode_input_for_freeze_token(
token_id,
TokenUnfreezable.Yes,
BigInt(2),
Network.Testnet
);
const expected_freeze_token_input = [
2, 8, 3, 162, 208, 145, 194, 165,
27, 14, 118, 31, 139, 199, 254, 11,
190, 108, 15, 64, 180, 50, 106, 211,
26, 107, 242, 121, 29, 55, 172, 185,
5, 196, 119, 1
];

assert_eq_arrays(freeze_token_input, expected_freeze_token_input);
console.log("freeze token encoding ok");

const unfreeze_token_input = encode_input_for_unfreeze_token(
token_id,
BigInt(2),
Network.Testnet
);
const expected_unfreeze_token_input = [
2, 8, 4, 162, 208, 145, 194, 165,
27, 14, 118, 31, 139, 199, 254, 11,
190, 108, 15, 64, 180, 50, 106, 211,
26, 107, 242, 121, 29, 55, 172, 185,
5, 196, 119
];

assert_eq_arrays(unfreeze_token_input, expected_unfreeze_token_input);
console.log("unfreeze token encoding ok");

const change_token_authority_input = encode_input_for_change_token_authority(
token_id,
address,
BigInt(2),
Network.Testnet
);
const expected_change_token_authority_input = [
2, 8, 5, 162, 208, 145, 194, 165, 27, 14, 118,
31, 139, 199, 254, 11, 190, 108, 15, 64, 180, 50,
106, 211, 26, 107, 242, 121, 29, 55, 172, 185, 5,
196, 119, 1, 91, 58, 110, 176, 100, 207, 6, 194,
41, 193, 30, 91, 4, 195, 202, 103, 207, 80, 217,
178
];

assert_eq_arrays(change_token_authority_input, expected_change_token_authority_input);
console.log("change token authority encoding ok");

const change_token_metadata_uri = encode_input_for_change_token_metadata_uri(
token_id,
address,
BigInt(2),
Network.Testnet
);
const expected_change_token_metadata_uri = [
2, 8, 8, 162, 208, 145, 194, 165, 27, 14, 118, 31,
139, 199, 254, 11, 190, 108, 15, 64, 180, 50, 106, 211,
26, 107, 242, 121, 29, 55, 172, 185, 5, 196, 119, 176,
116, 109, 116, 49, 113, 57, 100, 110, 53, 109, 52, 115,
118, 110, 56, 115, 100, 115, 51, 102, 99, 121, 48, 57,
107, 112, 120, 114, 101, 102, 110, 117, 55, 53, 120, 101,
107, 103, 114, 53, 119, 97, 51, 110
];

assert_eq_arrays(change_token_metadata_uri, expected_change_token_metadata_uri);
console.log("change token metadata uri encoding ok");

const order_output = encode_create_order_output(
Amount.from_atoms("40000"),
undefined,
Expand Down Expand Up @@ -1328,7 +1466,7 @@ function test_signed_transaction_intent() {
const message = make_transaction_intent_message_to_sign("the intent", tx_id);
const expected_message = new TextEncoder().encode(
"<tx_id:dfc2bb0cc4c7f3ed3fe682a48ee9f78bcd4962e55e7bc239bd340ec22aff8657;intent:the intent>");
assert_eq_arrays(message, expected_message);
assert_eq_arrays(message, expected_message);

try {
const invalid_signatures = "invalid signatures";
Expand Down
Loading

0 comments on commit a646f4a

Please sign in to comment.