From f88093fd5d739aba694d622d267bd9a3d1ea53ec Mon Sep 17 00:00:00 2001 From: Sergey Chystiakov Date: Thu, 27 Aug 2026 22:08:57 +0200 Subject: [PATCH 1/4] feat: transaction hex codec --- packages/sdk/package.json | 1 + packages/sdk/src/transaction.ts | 27 ++++++++++++++++ .../sdk/tests/transaction-builder.test.ts | 32 +++++++++++++++++++ pnpm-lock.yaml | 3 ++ 4 files changed, 63 insertions(+) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 70c8230..6e1237b 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -19,6 +19,7 @@ "license": "ISC", "devDependencies": { "@types/jest": "^29.5.14", + "@types/node":"^20.4.2", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", diff --git a/packages/sdk/src/transaction.ts b/packages/sdk/src/transaction.ts index 65cda1a..faf2d6a 100644 --- a/packages/sdk/src/transaction.ts +++ b/packages/sdk/src/transaction.ts @@ -133,9 +133,36 @@ export class Transaction { } fromHEX(hex: string) { + if (typeof hex !== 'string') { + throw new Error('Transaction hex must be a string'); + } + + if (!hex.length) { + throw new Error('Transaction hex cannot be empty'); + } + + if (!/^[0-9a-fA-F]+$/.test(hex)) { + throw new Error('Transaction hex contains invalid characters'); + } + + if (hex.length % 2 !== 0) { + throw new Error('Transaction hex must have an even number of characters'); + } + return this; } + static fromHEX( + hex: string, + options: { + network?: 'mainnet' | 'testnet'; + } = {}, + ) { + const transaction = new Transaction(options); + + return transaction.fromHEX(hex); + } + getTransactionId() { return this.transactionId; } diff --git a/packages/sdk/tests/transaction-builder.test.ts b/packages/sdk/tests/transaction-builder.test.ts index 3ebe3c9..0011f14 100644 --- a/packages/sdk/tests/transaction-builder.test.ts +++ b/packages/sdk/tests/transaction-builder.test.ts @@ -220,3 +220,35 @@ test('nft transfer produces no token change and a fee', () => { expect(nftOut).toBeDefined(); expect(nftOut.value.amount.atoms).toBe('1'); }); + +test('fromHex restores a coin transfer transaction', () => { + const transaction = new Transaction() + .setNetwork('testnet') + .setChangeAddress(CHANGE_ADDR) + .withUTXO(COIN_UTXO) + .addOutput(new Transaction().transfer(RECIPIENT, '10')) + .build(); + + const hex = transaction.hex(); + + const restored = Transaction.fromHEX(hex); + + expect(restored).toBeDefined(); + expect(restored.hex()).toBe(hex); + + const originalJson = transaction.json(); + const restoredJson = restored.json(); + + expect(restoredJson.id).toBe(originalJson.id); + expect(restoredJson.inputs).toEqual(originalJson.inputs); + expect(restoredJson.outputs).toEqual(originalJson.outputs); + expect(restoredJson.fee).toEqual(originalJson.fee); +}); + +test('fromHex rejects invalid hex', () => { + expect(() => Transaction.fromHEX('deadbeef')).toThrow(); +}); + +test('fromHex rejects malformed hex', () => { + expect(() => Transaction.fromHEX('not-a-hex')).toThrow(); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b52e48a..70106b0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -178,6 +178,9 @@ importers: '@types/jest': specifier: ^29.5.14 version: 29.5.14 + '@types/node': + specifier: ^20.4.2 + version: 20.19.43 jest: specifier: ^29.7.0 version: 29.7.0(@types/node@20.19.43) From dfdf2221648238e706bc49095d2f8e1c5f3225ec Mon Sep 17 00:00:00 2001 From: Sergey Chystiakov Date: Thu, 27 Aug 2026 23:31:06 +0200 Subject: [PATCH 2/4] update wasm --- packages/sdk/jest.setup.ts | 7 + packages/sdk/package.json | 2 +- packages/sdk/src/mintlayer-connect-sdk.ts | 23 +- packages/sdk/src/transaction.ts | 22 +- .../sdk/tests/__mocks__/pkg-node/package.json | 4 +- .../__mocks__/pkg-node/wasm_wrappers.d.ts | 773 +++-- .../tests/__mocks__/pkg-node/wasm_wrappers.js | 3022 ++++++++++------- .../__mocks__/pkg-node/wasm_wrappers_bg.wasm | Bin 2162297 -> 3629673 bytes .../pkg-node/wasm_wrappers_bg.wasm.d.ts | 128 +- .../sdk/tests/transaction-builder.test.ts | 12 + packages/wasm-lib/package.json | 2 +- packages/wasm-lib/wasm_wrappers.d.ts | 979 ++++-- packages/wasm-lib/wasm_wrappers.js | 2858 +++++++++------- packages/wasm-lib/wasm_wrappers_bg.wasm | Bin 2161646 -> 3629673 bytes packages/wasm-lib/wasm_wrappers_bg.wasm.d.ts | 128 +- pnpm-lock.yaml | 9 +- 16 files changed, 4680 insertions(+), 3289 deletions(-) diff --git a/packages/sdk/jest.setup.ts b/packages/sdk/jest.setup.ts index 5fe372a..12d6874 100644 --- a/packages/sdk/jest.setup.ts +++ b/packages/sdk/jest.setup.ts @@ -2,3 +2,10 @@ import fetchMock from 'jest-fetch-mock'; // import 'whatwg-fetch'; globalThis.fetch = fetchMock as any; fetchMock.enableMocks(); + +import { TextDecoder, TextEncoder } from 'util'; + +Object.assign(global, { + TextDecoder, + TextEncoder, +}); diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 6e1237b..c4d891a 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -12,7 +12,7 @@ "docs": "typedoc --options typedoc.js" }, "dependencies": { - "@mintlayer/wasm-lib": "^0.1.0" + "@mintlayer/wasm-lib": "workspace:*" }, "keywords": [], "author": "", diff --git a/packages/sdk/src/mintlayer-connect-sdk.ts b/packages/sdk/src/mintlayer-connect-sdk.ts index 227ec27..4903529 100644 --- a/packages/sdk/src/mintlayer-connect-sdk.ts +++ b/packages/sdk/src/mintlayer-connect-sdk.ts @@ -2609,8 +2609,10 @@ class Client { const transaction_id = get_transaction_id(transaction, true); if (finalOutputs.some((output) => output.type === 'IssueNft')) { + const block_height = 200000n; // TODO: Get the current block height const token_id = get_token_id( mergeUint8Arrays(BINRepresentation.inputs), + block_height, this.network === 'mainnet' ? Network.Mainnet : Network.Testnet, ); const index = finalOutputs.findIndex((output) => output.type === 'IssueNft'); @@ -2675,14 +2677,17 @@ class Client { .filter(({ input }) => input.input_type === 'AccountCommand' || input.input_type === 'Account') .map(({ input }) => { if (input.command === 'ConcludeOrder') { - return encode_input_for_conclude_order(input.order_id, BigInt(input.nonce.toString()), network); + const block_height = 200000n; // TODO: Get the current block height + return encode_input_for_conclude_order(input.order_id, BigInt(input.nonce.toString()), block_height, network); } if (input.command === 'FillOrder') { + const block_height = 200000n; // TODO: Get the current block height return encode_input_for_fill_order( input.order_id, Amount.from_atoms(input.fill_atoms.toString()), input.destination, BigInt(input.nonce.toString()), + BigInt(block_height), network, ); } @@ -4150,7 +4155,7 @@ class Signer { (input, index) => { let address: string | undefined = undefined; - if(input.input.input_type === 'UTXO') { + if (input.input.input_type === 'UTXO') { const utxoInput = input as UtxoInput; address = utxoInput.utxo.destination; } @@ -4168,7 +4173,7 @@ class Signer { throw new Error(`Address not found for input at index ${index}`); } - const addressPrivateKey = this.getPrivateKey(address) + const addressPrivateKey = this.getPrivateKey(address); if (!addressPrivateKey) { throw new Error(`Private key not found for address: ${address}`); @@ -4176,6 +4181,12 @@ class Signer { const transaction = this.hexToUint8Array(tx.HEXRepresentation_unsigned); + const block_height = 200000n; // TODO: Get the current block height + const additional_info = { + pool_info: {}, + order_info: {} + }; + const witness = encode_witness( SignatureHashType.ALL, addressPrivateKey, @@ -4183,9 +4194,11 @@ class Signer { transaction, optUtxos, index, + additional_info, + block_height, network, - ) - return witness + ); + return witness; }, ) diff --git a/packages/sdk/src/transaction.ts b/packages/sdk/src/transaction.ts index faf2d6a..07b22ae 100644 --- a/packages/sdk/src/transaction.ts +++ b/packages/sdk/src/transaction.ts @@ -36,7 +36,11 @@ import { Network, TokenUnfreezable, TotalSupply, + decode_signed_transaction_to_js, } from '@mintlayer/wasm-lib'; + +import * as wasmLib from '@mintlayer/wasm-lib'; + import { mergeUint8Arrays, atomsToDecimal, stringToUint8Array } from './utils'; import { UtxoEntry, UtxoInput } from './types/transaction'; @@ -149,6 +153,16 @@ export class Transaction { throw new Error('Transaction hex must have an even number of characters'); } + const bytes = new Uint8Array(hex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))); + + const network = this.network === 'mainnet' ? 0 : 1; + + const decoded = wasmLib.decode_signed_transaction_to_js(bytes, network); + + this.hexRepresentation = hex; + this.jsonRepresentation = decoded; + this.transactionId = get_transaction_id(bytes, false); + return this; } @@ -444,7 +458,12 @@ export class Transaction { .filter(({ input }) => input.input_type === 'AccountCommand' || input.input_type === 'Account') .map(({ input }) => { if (input.command === 'ConcludeOrder') { - return encode_input_for_conclude_order(input.order_id, BigInt(input.nonce.toString()), network); + return encode_input_for_conclude_order( + input.order_id, + BigInt(input.nonce.toString()), + BigInt(this.currentBlockHeight), + network, + ); } if (input.command === 'FillOrder') { return encode_input_for_fill_order( @@ -452,6 +471,7 @@ export class Transaction { Amount.from_atoms(input.fill_atoms.toString()), input.destination, BigInt(input.nonce.toString()), + BigInt(this.currentBlockHeight), network, ); } diff --git a/packages/sdk/tests/__mocks__/pkg-node/package.json b/packages/sdk/tests/__mocks__/pkg-node/package.json index 4017c72..f39aeac 100644 --- a/packages/sdk/tests/__mocks__/pkg-node/package.json +++ b/packages/sdk/tests/__mocks__/pkg-node/package.json @@ -1,6 +1,6 @@ { "name": "wasm-wrappers", - "version": "1.0.2", + "version": "1.4.0", "license": "MIT", "files": [ "wasm_wrappers_bg.wasm", @@ -9,4 +9,4 @@ ], "main": "wasm_wrappers.js", "types": "wasm_wrappers.d.ts" -} \ No newline at end of file +} diff --git a/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.d.ts b/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.d.ts index 01bb6d1..f0fdff0 100644 --- a/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.d.ts +++ b/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.d.ts @@ -1,271 +1,492 @@ /* tslint:disable */ /* eslint-disable */ /** - * A utxo can either come from a transaction or a block reward. - * Given a source id, whether from a block reward or transaction, this function - * takes a generic id with it, and returns serialized binary data of the id - * with the given source id. + * Additional information for a pool. */ -export function encode_outpoint_source_id(id: Uint8Array, source: SourceId): Uint8Array; +export interface PoolAdditionalInfo { + staker_balance: SimpleAmount; +} + /** - * Generates a new, random private key from entropy + * Additional information for a transaction. */ -export function make_private_key(): Uint8Array; +export interface TxAdditionalInfo { + pool_info: Record; + order_info: Record; +} + /** - * Create the default account's extended private key for a given mnemonic - * derivation path: 44'/mintlayer_coin_type'/0' + * Additional information for an order. */ -export function make_default_account_privkey(mnemonic: string, network: Network): Uint8Array; +export interface OrderAdditionalInfo { + initially_asked: SimpleCurrencyAmount; + initially_given: SimpleCurrencyAmount; + ask_balance: SimpleAmount; + give_balance: SimpleAmount; +} + /** - * From an extended private key create a receiving private key for a given key index - * derivation path: current_derivation_path/0/key_index + * An alternative representation of `Amount`. */ -export function make_receiving_address(private_key_bytes: Uint8Array, key_index: number): Uint8Array; +export interface SimpleAmount { + atoms: string; +} + /** - * From an extended private key create a change private key for a given key index - * derivation path: current_derivation_path/1/key_index + * An amount of coins or some token, */ -export function make_change_address(private_key_bytes: Uint8Array, key_index: number): Uint8Array; +export type SimpleCurrencyAmount = { coins: SimpleAmount } | { tokens: SimpleTokenAmount }; + /** - * Given a public key (as bytes) and a network type (mainnet, testnet, etc), - * return the address public key hash from that public key as an address + * An amount of some token. */ -export function pubkey_to_pubkeyhash_address(public_key_bytes: Uint8Array, network: Network): string; +export interface SimpleTokenAmount { + token_id: string; + amount: SimpleAmount; +} + + /** - * Given a private key, as bytes, return the bytes of the corresponding public key + * Amount type abstraction. The amount type is stored in a string + * since JavaScript number type cannot fit 128-bit integers. + * The amount is given as an integer in units of "atoms". + * Atoms are the smallest, indivisible amount of a coin or token. */ -export function public_key_from_private_key(private_key: Uint8Array): Uint8Array; +export class Amount { + private constructor(); + free(): void; + [Symbol.dispose](): void; + atoms(): string; + static from_atoms(atoms: string): Amount; +} + /** - * Return the extended public key from an extended private key + * Indicates whether a token can be frozen */ -export function extended_public_key_from_extended_private_key(private_key_bytes: Uint8Array): Uint8Array; +export enum FreezableToken { + No = 0, + Yes = 1, +} + /** - * From an extended public key create a receiving public key for a given key index - * derivation path: current_derivation_path/0/key_index + * The network, for which an operation to be done. Mainnet, testnet, etc. */ -export function make_receiving_address_public_key(extended_public_key_bytes: Uint8Array, key_index: number): Uint8Array; +export enum Network { + Mainnet = 0, + Testnet = 1, + Regtest = 2, + Signet = 3, +} + /** - * From an extended public key create a change public key for a given key index - * derivation path: current_derivation_path/1/key_index + * The part of the transaction that will be committed in the signature. Similar to bitcoin's sighash. */ -export function make_change_address_public_key(extended_public_key_bytes: Uint8Array, key_index: number): Uint8Array; +export enum SignatureHashType { + ALL = 0, + NONE = 1, + SINGLE = 2, + ANYONECANPAY = 3, +} + /** - * Given a message and a private key, sign the message with the given private key - * This kind of signature is to be used when signing spend requests, such as transaction - * input witness. + * A utxo can either come from a transaction or a block reward. This enum signifies that. */ -export function sign_message_for_spending(private_key: Uint8Array, message: Uint8Array): Uint8Array; +export enum SourceId { + Transaction = 0, + BlockReward = 1, +} + /** - * Given a digital signature, a public key and a message. Verify that - * the signature is produced by signing the message with the private key - * that derived the given public key. - * Note that this function is used for verifying messages related to spending, - * such as transaction input witness. + * Indicates whether a token can be unfrozen once frozen */ -export function verify_signature_for_spending(public_key: Uint8Array, signature: Uint8Array, message: Uint8Array): boolean; +export enum TokenUnfreezable { + No = 0, + Yes = 1, +} + /** - * Given a message and a private key, create and sign a challenge with the given private key. - * This kind of signature is to be used when signing challenges. + * The token supply of a specific token, set on issuance */ -export function sign_challenge(private_key: Uint8Array, message: Uint8Array): Uint8Array; +export enum TotalSupply { + /** + * Can be issued with no limit, but then can be locked to have a fixed supply. + */ + Lockable = 0, + /** + * Unlimited supply, no limits except for numeric limits due to u128 + */ + Unlimited = 1, + /** + * On issuance, the total number of coins is fixed + */ + Fixed = 2, +} + /** - * Given a signed challenge, an address and a message, verify that - * the signature is produced by signing the message with the private key - * that derived the given public key. - * This function is used for verifying messages-related challenges. - * - * Note: for signatures that were created by `sign_challenge`, the provided address must be - * a 'pubkeyhash' address. - * - * Note: currently this function never returns `false` - it either returns `true` or fails with an error. + * Returns the fee that needs to be paid by a transaction for issuing a data deposit */ -export function verify_challenge(address: string, network: Network, signed_challenge: Uint8Array, message: Uint8Array): boolean; +export function data_deposit_fee(current_block_height: bigint, network: Network): Amount; + /** - * Return the message that has to be signed to produce a signed transaction intent. + * Decodes a partially signed transaction from its binary encoding into a JavaScript object. */ -export function make_transaction_intent_message_to_sign(intent: string, transaction_id: string): Uint8Array; +export function decode_partially_signed_transaction_to_js(transaction: Uint8Array, network: Network): any; + /** - * Return a `SignedTransactionIntent` object as bytes given the message and encoded signatures. + * Decodes a signed transaction from its binary encoding into a JavaScript object. + */ +export function decode_signed_transaction_to_js(transaction: Uint8Array, network: Network): any; + +/** + * 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. + */ +export function effective_pool_balance(network: Network, pledge_amount: Amount, pool_balance: Amount): Amount; + +/** + * Given ask and give amounts and a conclude key create output that creates an order. * - * Note: to produce a valid signed intent one is expected to sign the corresponding message by private keys - * corresponding to each input of the transaction. + * 'ask_token_id': the parameter represents a Token if it's Some and coins otherwise. + * 'give_token_id': the parameter represents a Token if it's Some and coins otherwise. + */ +export function encode_create_order_output(ask_amount: Amount, ask_token_id: string | null | undefined, give_amount: Amount, give_token_id: string | null | undefined, conclude_address: string, network: Network): Uint8Array; + +/** + * Convert the specified string address into a Destination object, encoded as bytes. + */ +export function encode_destination(address: string, network: Network): Uint8Array; + +/** + * Given a token_id, new authority destination and nonce return an encoded change token authority input + */ +export function encode_input_for_change_token_authority(token_id: string, new_authority: string, nonce: bigint, network: Network): Uint8Array; + +/** + * Given a token_id, new metadata uri and nonce return an encoded change token metadata uri input + */ +export function encode_input_for_change_token_metadata_uri(token_id: string, new_metadata_uri: string, nonce: bigint, network: Network): Uint8Array; + +/** + * Given an order id create an input that concludes the order. * - * Parameters: - * `signed_message` - this must have been produced by `make_transaction_intent_message_to_sign`. - * `signatures` - this should be an array of arrays of bytes, each of them representing an individual signature - * of `signed_message` produced by `sign_challenge` using the private key for the corresponding input destination - * of the transaction. The number of signatures must be equal to the number of inputs in the transaction. + * Note: the nonce is only needed before the orders V1 fork activation. After the fork the nonce is + * ignored and any value can be passed for the parameter. */ -export function encode_signed_transaction_intent(signed_message: Uint8Array, signatures: any): Uint8Array; +export function encode_input_for_conclude_order(order_id: string, nonce: bigint, current_block_height: bigint, network: Network): Uint8Array; + /** - * Verify a signed transaction intent. + * Given an order id and an amount in the order's ask currency, create an input that fills the order. * - * Parameters: - * `expected_signed_message` - the message that is supposed to be signed; this must have been - * produced by `make_transaction_intent_message_to_sign`. - * `encoded_signed_intent` - the signed transaction intent produced by `encode_signed_transaction_intent`. - * `input_destinations` - an array of addresses (strings), corresponding to the transaction's input destinations - * (note that this function treats "pub key" and "pub key hash" addresses interchangeably, so it's ok to pass - * one instead of the other). - * `network` - the network being used (needed to decode the addresses). + * Note: + * 1) The nonce is only needed before the orders V1 fork activation. After the fork the nonce is + * ignored and any value can be passed for the parameter. + * 2) FillOrder inputs should not be signed, i.e. use `encode_witness_no_signature` for the inputs + * instead of `encode_witness`). + * Note that in orders v0 FillOrder inputs can technically have a signature, it's just not checked. + * But in orders V1 we actually require that those inputs don't have signatures. + * Also, in orders V1 the provided destination is always ignored. + */ +export function encode_input_for_fill_order(order_id: string, fill_amount: Amount, destination: string, nonce: bigint, current_block_height: bigint, network: Network): Uint8Array; + +/** + * Given an order id create an input that freezes the order. + * + * Note: order freezing is available only after the orders V1 fork activation. */ -export function verify_transaction_intent(expected_signed_message: Uint8Array, encoded_signed_intent: Uint8Array, input_destinations: string[], network: Network): void; +export function encode_input_for_freeze_order(order_id: string, current_block_height: bigint, network: Network): Uint8Array; + /** - * Given a destination address, an amount and a network type (mainnet, testnet, etc), this function - * creates an output of type Transfer, and returns it as bytes. + * Given a token_id, is token unfreezable and nonce return an encoded freeze token input */ -export function encode_output_transfer(amount: Amount, address: string, network: Network): Uint8Array; +export function encode_input_for_freeze_token(token_id: string, is_token_unfreezable: TokenUnfreezable, nonce: bigint, network: Network): Uint8Array; + /** - * Given a destination address, an amount, token ID (in address form) and a network type (mainnet, testnet, etc), this function - * creates an output of type Transfer for tokens, and returns it as bytes. + * Given a token_id and nonce return an encoded lock_token_supply input */ -export function encode_output_token_transfer(amount: Amount, address: string, token_id: string, network: Network): Uint8Array; +export function encode_input_for_lock_token_supply(token_id: string, nonce: bigint, network: Network): Uint8Array; + /** - * Given the current block height and a network type (mainnet, testnet, etc), - * this function returns the number of blocks, after which a pool that decommissioned, - * will have its funds unlocked and available for spending. - * The current block height information is used in case a network upgrade changed the value. + * Given a token_id, an amount of tokens to mint and nonce return an encoded mint tokens input */ -export function staking_pool_spend_maturity_block_count(current_block_height: bigint, network: Network): bigint; +export function encode_input_for_mint_tokens(token_id: string, amount: Amount, nonce: bigint, network: Network): Uint8Array; + +/** + * Given a token_id and nonce return an encoded unfreeze token input + */ +export function encode_input_for_unfreeze_token(token_id: string, nonce: bigint, network: Network): Uint8Array; + +/** + * Given a token_id and nonce return an encoded unmint tokens input + */ +export function encode_input_for_unmint_tokens(token_id: string, nonce: bigint, network: Network): Uint8Array; + +/** + * Given an output source id as bytes, and an output index, together representing a utxo, + * this function returns the input that puts them together, as bytes. + */ +export function encode_input_for_utxo(outpoint_source_id: Uint8Array, output_index: number): Uint8Array; + +/** + * Given a delegation id, an amount and a network type (mainnet, testnet, etc), this function + * creates an input that withdraws from a delegation. + * A nonce is needed because this spends from an account. The nonce must be in sequence for everything in that account. + */ +export function encode_input_for_withdraw_from_delegation(delegation_id: string, amount: Amount, nonce: bigint, network: Network): Uint8Array; + /** * Given a number of blocks, this function returns the output timelock * which is used in locked outputs to lock an output for a given number of blocks * since that output's transaction is included the blockchain */ export function encode_lock_for_block_count(block_count: bigint): Uint8Array; + /** * Given a number of clock seconds, this function returns the output timelock * which is used in locked outputs to lock an output for a given number of seconds * since that output's transaction is included in the blockchain */ export function encode_lock_for_seconds(total_seconds: bigint): Uint8Array; + +/** + * Given a block height, this function returns the output timelock which is used in + * locked outputs to lock an output until that block height is reached. + */ +export function encode_lock_until_height(block_height: bigint): Uint8Array; + /** * Given a timestamp represented by as unix timestamp, i.e., number of seconds since unix epoch, * this function returns the output timelock which is used in locked outputs to lock an output * until the given timestamp */ export function encode_lock_until_time(timestamp_since_epoch_in_seconds: bigint): Uint8Array; + /** - * Given a block height, this function returns the output timelock which is used in - * locked outputs to lock an output until that block height is reached. - */ -export function encode_lock_until_height(block_height: bigint): Uint8Array; -/** - * Given a valid receiving address, and a locking rule as bytes (available in this file), - * and a network type (mainnet, testnet, etc), this function creates an output of type - * LockThenTransfer with the parameters provided. + * Given an arbitrary number of public keys as bytes, number of minimum required signatures, and a network type, this function returns + * the multisig challenge, as bytes. */ -export function encode_output_lock_then_transfer(amount: Amount, address: string, lock: Uint8Array, network: Network): Uint8Array; +export function encode_multisig_challenge(public_keys: Uint8Array, min_required_signatures: number, network: Network): Uint8Array; + /** - * Given a valid receiving address, token ID (in address form), a locking rule as bytes (available in this file), - * and a network type (mainnet, testnet, etc), this function creates an output of type - * LockThenTransfer with the parameters provided. + * A utxo can either come from a transaction or a block reward. + * Given a source id, whether from a block reward or transaction, this function + * takes a generic id with it, and returns serialized binary data of the id + * with the given source id. */ -export function encode_output_token_lock_then_transfer(amount: Amount, address: string, token_id: string, lock: Uint8Array, network: Network): Uint8Array; +export function encode_outpoint_source_id(id: Uint8Array, source: SourceId): Uint8Array; + /** * Given an amount, this function creates an output (as bytes) to burn a given amount of coins */ export function encode_output_coin_burn(amount: Amount): Uint8Array; -/** - * Given an amount, token ID (in address form) and network type (mainnet, testnet, etc), - * this function creates an output (as bytes) to burn a given amount of tokens - */ -export function encode_output_token_burn(amount: Amount, token_id: string, network: Network): Uint8Array; + /** * Given a pool id as string, an owner address and a network type (mainnet, testnet, etc), * this function returns an output (as bytes) to create a delegation to the given pool. * The owner address is the address that is authorized to withdraw from that delegation. */ export function encode_output_create_delegation(pool_id: string, owner_address: string, network: Network): Uint8Array; + +/** + * Given a pool id, staking data as bytes and the network type (mainnet, testnet, etc), + * this function returns an output that creates that staking pool. + * Note that the pool id is mandated to be taken from the hash of the first input. + * It is not arbitrary. + * + * Note: a UTXO of this kind is consumed when decommissioning a pool (provided that the pool + * never staked). + */ +export function encode_output_create_stake_pool(pool_id: string, pool_data: Uint8Array, network: Network): Uint8Array; + +/** + * Given data to be deposited in the blockchain, this function provides the output that deposits this data + */ +export function encode_output_data_deposit(data: Uint8Array): Uint8Array; + /** * Given a delegation id (as string, in address form), an amount and a network type (mainnet, testnet, etc), * this function returns an output (as bytes) that would delegate coins to be staked in the specified delegation id. */ export function encode_output_delegate_staking(amount: Amount, delegation_id: string, network: Network): Uint8Array; + /** - * This function returns the staking pool data needed to create a staking pool in an output as bytes, - * given its parameters and the network type (testnet, mainnet, etc). + * Given the parameters needed to create hash timelock contract, and a network type (mainnet, testnet, etc), + * this function creates an output. */ -export function encode_stake_pool_data(value: Amount, staker: string, vrf_public_key: string, decommission_key: string, margin_ratio_per_thousand: number, cost_per_block: Amount, network: Network): Uint8Array; +export function encode_output_htlc(amount: Amount, token_id: string | null | undefined, secret_hash: string, spend_address: string, refund_address: string, refund_timelock: Uint8Array, network: Network): Uint8Array; + /** - * Given a pool id, staking data as bytes and the network type (mainnet, testnet, etc), - * this function returns an output that creates that staking pool. - * Note that the pool id is mandated to be taken from the hash of the first input. - * It is not arbitrary. + * Given the parameters needed to issue a fungible token, and a network type (mainnet, testnet, etc), + * this function creates an output that issues that token. */ -export function encode_output_create_stake_pool(pool_id: string, pool_data: Uint8Array, network: Network): Uint8Array; +export function encode_output_issue_fungible_token(authority: string, token_ticker: string, metadata_uri: string, number_of_decimals: number, total_supply: TotalSupply, supply_amount: Amount | null | undefined, is_token_freezable: FreezableToken, _current_block_height: bigint, network: Network): Uint8Array; + /** - * Returns the fee that needs to be paid by a transaction for issuing a new fungible token + * Given the parameters needed to issue an NFT, and a network type (mainnet, testnet, etc), + * this function creates an output that issues that NFT. */ -export function fungible_token_issuance_fee(_current_block_height: bigint, network: Network): Amount; +export function encode_output_issue_nft(token_id: string, authority: string, name: string, ticker: string, description: string, media_hash: Uint8Array, creator: Uint8Array | null | undefined, media_uri: string | null | undefined, icon_uri: string | null | undefined, additional_metadata_uri: string | null | undefined, _current_block_height: bigint, network: Network): Uint8Array; + /** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for issuing a new NFT - * The current block height information is used in case a network upgrade changed the value. + * Given a valid receiving address, and a locking rule as bytes (available in this file), + * and a network type (mainnet, testnet, etc), this function creates an output of type + * LockThenTransfer with the parameters provided. */ -export function nft_issuance_fee(current_block_height: bigint, network: Network): Amount; +export function encode_output_lock_then_transfer(amount: Amount, address: string, lock: Uint8Array, network: Network): Uint8Array; + /** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for changing the total supply of a token - * by either minting or unminting tokens - * The current block height information is used in case a network upgrade changed the value. + * Given a pool id and a staker address, this function returns an output that is emitted + * when producing a block via that pool. + * + * Note: a UTXO of this kind is consumed when decommissioning a pool (provided that the pool + * has staked at least once). */ -export function token_supply_change_fee(current_block_height: bigint, network: Network): Amount; +export function encode_output_produce_block_from_stake(pool_id: string, staker: string, network: Network): Uint8Array; + /** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for freezing/unfreezing a token - * The current block height information is used in case a network upgrade changed the value. + * Given an amount, token ID (in address form) and network type (mainnet, testnet, etc), + * this function creates an output (as bytes) to burn a given amount of tokens */ -export function token_freeze_fee(current_block_height: bigint, network: Network): Amount; +export function encode_output_token_burn(amount: Amount, token_id: string, network: Network): Uint8Array; + /** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for changing the authority of a token - * The current block height information is used in case a network upgrade changed the value. + * Given a valid receiving address, token ID (in address form), a locking rule as bytes (available in this file), + * and a network type (mainnet, testnet, etc), this function creates an output of type + * LockThenTransfer with the parameters provided. */ -export function token_change_authority_fee(current_block_height: bigint, network: Network): Amount; +export function encode_output_token_lock_then_transfer(amount: Amount, address: string, token_id: string, lock: Uint8Array, network: Network): Uint8Array; + /** - * Given the parameters needed to issue a fungible token, and a network type (mainnet, testnet, etc), - * this function creates an output that issues that token. + * Given a destination address, an amount, token ID (in address form) and a network type (mainnet, testnet, etc), this function + * creates an output of type Transfer for tokens, and returns it as bytes. */ -export function encode_output_issue_fungible_token(authority: string, token_ticker: string, metadata_uri: string, number_of_decimals: number, total_supply: TotalSupply, supply_amount: Amount | null | undefined, is_token_freezable: FreezableToken, _current_block_height: bigint, network: Network): Uint8Array; +export function encode_output_token_transfer(amount: Amount, address: string, token_id: string, network: Network): Uint8Array; + /** - * Returns the Fungible/NFT Token ID for the given inputs of a transaction + * Given a destination address, an amount and a network type (mainnet, testnet, etc), this function + * creates an output of type Transfer, and returns it as bytes. */ -export function get_token_id(inputs: Uint8Array, network: Network): string; +export function encode_output_transfer(amount: Amount, address: string, network: Network): Uint8Array; + /** - * Given the parameters needed to issue an NFT, and a network type (mainnet, testnet, etc), - * this function creates an output that issues that NFT. + * Return a PartiallySignedTransaction object as bytes. + * + * `transaction` is an encoded `Transaction` (which can be produced via `encode_transaction`). + * + * `signatures`, `input_utxos`, `input_destinations` and `htlc_secrets` are encoded lists of + * optional objects of the corresponding type. To produce such a list, iterate over your + * original list of optional objects and then: + * 1) emit byte 0 if the current object is null; + * 2) otherwise emit byte 1 followed by the object in its encoded form. + * + * Each individual object in each of the lists corresponds to the transaction input with the same + * index and its meaning is as follows: + * 1) `signatures` - the signature for the input; + * 2) `input_utxos`- the utxo for the input (if it's utxo-based); + * 3) `input_destinations` - the destination (address) corresponding to the input; this determines + * the key(s) with which the input has to be signed. Note that for utxo-based inputs the + * corresponding destination can usually be extracted from the utxo itself (the exception + * being the `ProduceBlockFromStake` utxo, which doesn't contain the pool's decommission key). + * However, PartiallySignedTransaction requires that *all* input destinations are provided + * explicitly anyway. + * 4) `htlc_secrets` - if the input is an HTLC one and if the transaction is spending the HTLC, + * this should be the HTLC secret. Otherwise it should be null. + * + * The number of items in each list must be equal to the number of transaction inputs. + * + * `additional_info` has the same meaning as in `encode_witness`. */ -export function encode_output_issue_nft(token_id: string, authority: string, name: string, ticker: string, description: string, media_hash: Uint8Array, creator: Uint8Array | null | undefined, media_uri: string | null | undefined, icon_uri: string | null | undefined, additional_metadata_uri: string | null | undefined, _current_block_height: bigint, network: Network): Uint8Array; +export function encode_partially_signed_transaction(transaction: Uint8Array, signatures: Uint8Array, input_utxos: Uint8Array, input_destinations: Uint8Array, htlc_secrets: Uint8Array, additional_info: TxAdditionalInfo, network: Network): Uint8Array; + /** - * Given data to be deposited in the blockchain, this function provides the output that deposits this data + * Given an unsigned transaction and signatures, this function returns a SignedTransaction object as bytes. */ -export function encode_output_data_deposit(data: Uint8Array): Uint8Array; +export function encode_signed_transaction(transaction: Uint8Array, signatures: Uint8Array): Uint8Array; + /** - * Returns the fee that needs to be paid by a transaction for issuing a data deposit + * Return a `SignedTransactionIntent` object as bytes given the message and encoded signatures. + * + * Note: to produce a valid signed intent one is expected to sign the corresponding message by private keys + * corresponding to each input of the transaction. + * + * Parameters: + * `signed_message` - this must have been produced by `make_transaction_intent_message_to_sign`. + * `signatures` - this should be an array of Uint8Array, each of them representing an individual signature + * of `signed_message` produced by `sign_challenge` using the private key for the corresponding input destination + * of the transaction. The number of signatures must be equal to the number of inputs in the transaction. */ -export function data_deposit_fee(current_block_height: bigint, network: Network): Amount; +export function encode_signed_transaction_intent(signed_message: Uint8Array, signatures: Uint8Array[]): Uint8Array; + /** - * Given the parameters needed to create hash timelock contract, and a network type (mainnet, testnet, etc), - * this function creates an output. + * This function returns the staking pool data needed to create a staking pool in an output as bytes, + * given its parameters and the network type (testnet, mainnet, etc). */ -export function encode_output_htlc(amount: Amount, token_id: string | null | undefined, secret_hash: string, spend_address: string, refund_address: string, refund_timelock: Uint8Array, network: Network): Uint8Array; +export function encode_stake_pool_data(value: Amount, staker: string, vrf_public_key: string, decommission_key: string, margin_ratio_per_thousand: number, cost_per_block: Amount, network: Network): Uint8Array; + /** - * Given a signed transaction and input outpoint that spends an htlc utxo, extract a secret that is - * encoded in the corresponding input signature + * Given inputs as bytes, outputs as bytes, and flags settings, this function returns + * the transaction that contains them all, as bytes. */ -export function extract_htlc_secret(signed_tx_bytes: Uint8Array, strict_byte_size: boolean, htlc_outpoint_source_id: Uint8Array, htlc_output_index: number): Uint8Array; +export function encode_transaction(inputs: Uint8Array, outputs: Uint8Array, flags: bigint): Uint8Array; + /** - * Given an output source id as bytes, and an output index, together representing a utxo, - * this function returns the input that puts them together, as bytes. + * Sign the specified input of the transaction and encode the signature as InputWitness. + * + * `input_utxos` must be formed as follows: for each transaction input, emit byte 0 if it's a non-UTXO input, + * otherwise emit 1 followed by the corresponding transaction output encoded via the appropriate "encode_output_" + * function. + * + * `additional_info` must contain the following: + * 1) for each `ProduceBlockFromStake` input of the transaction, the pool info for the pool referenced by that input; + * 2) for each `FillOrder` and `ConcludeOrder` input of the transaction, the order info for the order referenced by + * that input. + * Note: + * - It doesn't matter which input witness is currently being encoded. E.g. even if you are encoding a witness + * for some UTXO-based input but another input of the same transaction is `FillOrder`, you have to include the order + * info when encoding the witness for the UTXO-based input too. + * - After a certain hard fork, the produced signature will "commit" to the provided additional info, i.e. the info + * will become a part of what is being signed. So, passing invalid additional info will result in an invalid signature + * (with one small caveat: for `FillOrder` we only commit to order's initial balances and not the current ones; + * so if you only have `FillOrder` inputs, you can technically pass bogus values for the current balances and + * the resulting signature will still be valid; though it's better to avoid doing this). + */ +export function encode_witness(sighashtype: SignatureHashType, private_key: Uint8Array, input_owner_destination: string, transaction: Uint8Array, input_utxos: Uint8Array, input_index: number, additional_info: TxAdditionalInfo, current_block_height: bigint, network: Network): Uint8Array; + +/** + * Sign the specified HTLC input of the transaction and encode the signature as InputWitness. + * + * This function must be used for HTLC refunding when the refund address is a multisig one. + * + * `key_index` parameter is an index of the public key in the multisig challenge corresponding to + * the specified private key. + * `input_witness` parameter can be either empty or a result of previous calls to this function. + * + * `input_utxos` and `additional_info` have the same format and requirements as in `encode_witness`. */ -export function encode_input_for_utxo(outpoint_source_id: Uint8Array, output_index: number): Uint8Array; +export function encode_witness_htlc_refund_multisig(sighashtype: SignatureHashType, private_key: Uint8Array, key_index: number, input_witness: Uint8Array, multisig_challenge: Uint8Array, transaction: Uint8Array, input_utxos: Uint8Array, input_index: number, additional_info: TxAdditionalInfo, current_block_height: bigint, network: Network): Uint8Array; + /** - * Given a delegation id, an amount and a network type (mainnet, testnet, etc), this function - * creates an input that withdraws from a delegation. - * A nonce is needed because this spends from an account. The nonce must be in sequence for everything in that account. + * Sign the specified HTLC input of the transaction and encode the signature as InputWitness. + * + * This function must be used for HTLC refunding when the refund address is a single-sig one. + * + * `input_utxos` and `additional_info` have the same format and requirements as in `encode_witness`. */ -export function encode_input_for_withdraw_from_delegation(delegation_id: string, amount: Amount, nonce: bigint, network: Network): Uint8Array; +export function encode_witness_htlc_refund_single_sig(sighashtype: SignatureHashType, private_key: Uint8Array, input_owner_destination: string, transaction: Uint8Array, input_utxos: Uint8Array, input_index: number, additional_info: TxAdditionalInfo, current_block_height: bigint, network: Network): Uint8Array; + +/** + * Sign the specified HTLC input of the transaction and encode the signature as InputWitness. + * + * This function must be used for HTLC spending. + * + * `input_utxos` and `additional_info` have the same format and requirements as in `encode_witness`. + */ +export function encode_witness_htlc_spend(sighashtype: SignatureHashType, private_key: Uint8Array, input_owner_destination: string, transaction: Uint8Array, input_utxos: Uint8Array, input_index: number, secret: Uint8Array, additional_info: TxAdditionalInfo, current_block_height: bigint, network: Network): Uint8Array; + +/** + * Encode an input witness of the variant that contains no signature. + */ +export function encode_witness_no_signature(): Uint8Array; + /** * Given the inputs, along each input's destination that can spend that input * (e.g. If we are spending a UTXO in input number 1 and it is owned by address mtc1xxxx, then it is mtc1xxxx in element number 2 in the vector/list. @@ -273,44 +494,46 @@ export function encode_input_for_withdraw_from_delegation(delegation_id: string, * and in the case of AccountCommand inputs which change a token it is the token's authority destination) * and the outputs, estimate the transaction size. * ScriptHash and ClassicMultisig destinations are not supported. + * Also, the function assumes that the input UTXOs are not HTLC. */ export function estimate_transaction_size(inputs: Uint8Array, input_utxos_destinations: string[], outputs: Uint8Array, network: Network): number; + /** - * Given inputs as bytes, outputs as bytes, and flags settings, this function returns - * the transaction that contains them all, as bytes. + * Return the extended public key from an extended private key */ -export function encode_transaction(inputs: Uint8Array, outputs: Uint8Array, flags: bigint): Uint8Array; +export function extended_public_key_from_extended_private_key(private_key: Uint8Array): Uint8Array; + /** - * Encode an input witness of the variant that contains no signature. + * Given a signed transaction and input outpoint that spends an htlc utxo, extract a secret that is + * encoded in the corresponding input signature */ -export function encode_witness_no_signature(): Uint8Array; +export function extract_htlc_secret(signed_tx: Uint8Array, strict_byte_size: boolean, htlc_outpoint_source_id: Uint8Array, htlc_output_index: number): Uint8Array; + /** - * Given a private key, inputs and an input number to sign, and the destination that owns that output (through the utxo), - * and a network type (mainnet, testnet, etc), this function returns a witness to be used in a signed transaction, as bytes. + * Returns the fee that needs to be paid by a transaction for issuing a new fungible token */ -export function encode_witness(sighashtype: SignatureHashType, private_key_bytes: Uint8Array, input_owner_destination: string, transaction_bytes: Uint8Array, inputs: Uint8Array, input_num: number, network: Network): Uint8Array; +export function fungible_token_issuance_fee(_current_block_height: bigint, network: Network): Amount; + /** - * Given a private key, inputs and an input number to sign, and the destination that owns that output (through the utxo), - * and a network type (mainnet, testnet, etc), and an htlc secret this function returns a witness to be used in a signed transaction, as bytes. + * Returns the Delegation ID for the given inputs of a transaction */ -export function encode_witness_htlc_secret(sighashtype: SignatureHashType, private_key_bytes: Uint8Array, input_owner_destination: string, transaction_bytes: Uint8Array, inputs: Uint8Array, input_num: number, secret: Uint8Array, network: Network): Uint8Array; +export function get_delegation_id(inputs: Uint8Array, network: Network): string; + /** - * Given an arbitrary number of public keys as bytes, number of minimum required signatures, and a network type, this function returns - * the multisig challenge, as bytes. + * Returns the Order ID for the given inputs of a transaction */ -export function encode_multisig_challenge(public_keys_bytes: Uint8Array, min_required_signatures: number, network: Network): Uint8Array; +export function get_order_id(inputs: Uint8Array, network: Network): string; + /** - * Given a private key, inputs and an input number to sign, and multisig challenge, - * and a network type (mainnet, testnet, etc), this function returns a witness to be used in a signed transaction, as bytes. - * - * `key_index` parameter is an index of a public key in the challenge, against which is the signature produces from private key is to be verified. - * `input_witness` parameter can be either empty or a result of previous calls to this function. + * Returns the Pool ID for the given inputs of a transaction */ -export function encode_witness_htlc_multisig(sighashtype: SignatureHashType, private_key_bytes: Uint8Array, key_index: number, input_witness: Uint8Array, multisig_challenge: Uint8Array, transaction_bytes: Uint8Array, utxos: Uint8Array, input_num: number, network: Network): Uint8Array; +export function get_pool_id(inputs: Uint8Array, network: Network): string; + /** - * Given an unsigned transaction and signatures, this function returns a SignedTransaction object as bytes. + * Returns the Fungible/NFT Token ID for the given inputs of a transaction */ -export function encode_signed_transaction(transaction_bytes: Uint8Array, signatures: Uint8Array): Uint8Array; +export function get_token_id(inputs: Uint8Array, current_block_height: bigint, network: Network): string; + /** * Given a `Transaction` encoded in bytes (not a signed transaction, but a signed transaction is tolerated by ignoring the extra bytes, by choice) * this function will return the transaction id. @@ -322,121 +545,155 @@ export function encode_signed_transaction(transaction_bytes: Uint8Array, signatu * since the signatures are appended at the end of the `Transaction` object as a vector to create a `SignedTransaction`. * It is recommended to use a strict `Transaction` size and set the second parameter to `true`. */ -export function get_transaction_id(transaction_bytes: Uint8Array, strict_byte_size: boolean): string; +export function get_transaction_id(transaction: Uint8Array, strict_byte_size: boolean): string; + /** - * 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. + * Verify a witness produced by one of the `encode_witness` functions. + * + * `input_owner_destination` must be specified if `witness` actually contains a signature + * (i.e. it's not InputWitness::NoSignature) and the input is not an HTLC one. Otherwise it must + * be null. */ -export function effective_pool_balance(network: Network, pledge_amount: Amount, pool_balance: Amount): Amount; +export function internal_verify_witness(sighashtype: SignatureHashType, input_owner_destination: string | null | undefined, witness: Uint8Array, transaction: Uint8Array, input_utxos: Uint8Array, input_index: number, additional_info: TxAdditionalInfo, current_block_height: bigint, network: Network): void; + /** - * Given a token_id, an amount of tokens to mint and nonce return an encoded mint tokens input + * From an extended private key create a change private key for a given key index + * derivation path: current_derivation_path/1/key_index */ -export function encode_input_for_mint_tokens(token_id: string, amount: Amount, nonce: bigint, network: Network): Uint8Array; +export function make_change_address(private_key: Uint8Array, key_index: number): Uint8Array; + /** - * Given a token_id and nonce return an encoded unmint tokens input + * From an extended public key create a change public key for a given key index + * derivation path: current_derivation_path/1/key_index */ -export function encode_input_for_unmint_tokens(token_id: string, nonce: bigint, network: Network): Uint8Array; +export function make_change_address_public_key(extended_public_key: Uint8Array, key_index: number): Uint8Array; + /** - * Given a token_id and nonce return an encoded lock_token_supply input + * Create the default account's extended private key for a given mnemonic + * derivation path: 44'/mintlayer_coin_type'/0' */ -export function encode_input_for_lock_token_supply(token_id: string, nonce: bigint, network: Network): Uint8Array; +export function make_default_account_privkey(mnemonic: string, network: Network): Uint8Array; + /** - * Given a token_id, is token unfreezable and nonce return an encoded freeze token input + * Generates a new, random private key from entropy */ -export function encode_input_for_freeze_token(token_id: string, is_token_unfreezable: TokenUnfreezable, nonce: bigint, network: Network): Uint8Array; +export function make_private_key(): Uint8Array; + /** - * Given a token_id and nonce return an encoded unfreeze token input + * From an extended private key create a receiving private key for a given key index + * derivation path: current_derivation_path/0/key_index */ -export function encode_input_for_unfreeze_token(token_id: string, nonce: bigint, network: Network): Uint8Array; +export function make_receiving_address(private_key: Uint8Array, key_index: number): Uint8Array; + /** - * Given a token_id, new authority destination and nonce return an encoded change token authority input + * From an extended public key create a receiving public key for a given key index + * derivation path: current_derivation_path/0/key_index */ -export function encode_input_for_change_token_authority(token_id: string, new_authority: string, nonce: bigint, network: Network): Uint8Array; +export function make_receiving_address_public_key(extended_public_key: Uint8Array, key_index: number): Uint8Array; + /** - * Given a token_id, new metadata uri and nonce return an encoded change token metadata uri input + * Return the message that has to be signed to produce a signed transaction intent. */ -export function encode_input_for_change_token_metadata_uri(token_id: string, new_metadata_uri: string, nonce: bigint, network: Network): Uint8Array; +export function make_transaction_intent_message_to_sign(intent: string, transaction_id: string): Uint8Array; + /** - * Given ask and give amounts and a conclude key create output that creates an order. - * - * 'ask_token_id': the parameter represents a Token if it's Some and coins otherwise. - * 'give_token_id': the parameter represents a Token if it's Some and coins otherwise. + * Produce a multisig address given a multisig challenge. */ -export function encode_create_order_output(ask_amount: Amount, ask_token_id: string | null | undefined, give_amount: Amount, give_token_id: string | null | undefined, conclude_address: string, network: Network): Uint8Array; +export function multisig_challenge_to_address(multisig_challenge: Uint8Array, network: Network): string; + /** - * Given an amount to fill an order (which is described in terms of ask currency) and a destination - * for result outputs create an input that fills the order. + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for issuing a new NFT + * The current block height information is used in case a network upgrade changed the value. */ -export function encode_input_for_fill_order(order_id: string, fill_amount: Amount, destination: string, nonce: bigint, network: Network): Uint8Array; +export function nft_issuance_fee(current_block_height: bigint, network: Network): Amount; + /** - * Given an order id create an input that concludes the order. + * Given a public key (as bytes) and a network type (mainnet, testnet, etc), + * return the address public key hash from that public key as an address */ -export function encode_input_for_conclude_order(order_id: string, nonce: bigint, network: Network): Uint8Array; +export function pubkey_to_pubkeyhash_address(public_key: Uint8Array, network: Network): string; + /** - * Indicates whether a token can be frozen + * Given a private key, as bytes, return the bytes of the corresponding public key */ -export enum FreezableToken { - No = 0, - Yes = 1, -} +export function public_key_from_private_key(private_key: Uint8Array): Uint8Array; + /** - * The network, for which an operation to be done. Mainnet, testnet, etc. + * Given a message and a private key, create and sign a challenge with the given private key. + * This kind of signature is to be used when signing challenges. */ -export enum Network { - Mainnet = 0, - Testnet = 1, - Regtest = 2, - Signet = 3, -} +export function sign_challenge(private_key: Uint8Array, message: Uint8Array): Uint8Array; + /** - * The part of the transaction that will be committed in the signature. Similar to bitcoin's sighash. + * Given a message and a private key, sign the message with the given private key + * This kind of signature is to be used when signing spend requests, such as transaction + * input witness. */ -export enum SignatureHashType { - ALL = 0, - NONE = 1, - SINGLE = 2, - ANYONECANPAY = 3, -} +export function sign_message_for_spending(private_key: Uint8Array, message: Uint8Array): Uint8Array; + /** - * A utxo can either come from a transaction or a block reward. This enum signifies that. + * Given the current block height and a network type (mainnet, testnet, etc), + * this function returns the number of blocks, after which a pool that decommissioned, + * will have its funds unlocked and available for spending. + * The current block height information is used in case a network upgrade changed the value. */ -export enum SourceId { - Transaction = 0, - BlockReward = 1, -} +export function staking_pool_spend_maturity_block_count(current_block_height: bigint, network: Network): bigint; + /** - * Indicates whether a token can be unfrozen once frozen + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for changing the authority of a token + * The current block height information is used in case a network upgrade changed the value. */ -export enum TokenUnfreezable { - No = 0, - Yes = 1, -} +export function token_change_authority_fee(current_block_height: bigint, network: Network): Amount; + /** - * The token supply of a specific token, set on issuance + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for freezing/unfreezing a token + * The current block height information is used in case a network upgrade changed the value. */ -export enum TotalSupply { - /** - * Can be issued with no limit, but then can be locked to have a fixed supply. - */ - Lockable = 0, - /** - * Unlimited supply, no limits except for numeric limits due to u128 - */ - Unlimited = 1, - /** - * On issuance, the total number of coins is fixed - */ - Fixed = 2, -} +export function token_freeze_fee(current_block_height: bigint, network: Network): Amount; + /** - * Amount type abstraction. The amount type is stored in a string - * since JavaScript number type cannot fit 128-bit integers. - * The amount is given as an integer in units of "atoms". - * Atoms are the smallest, indivisible amount of a coin or token. + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for changing the total supply of a token + * by either minting or unminting tokens + * The current block height information is used in case a network upgrade changed the value. */ -export class Amount { - private constructor(); - free(): void; - static from_atoms(atoms: string): Amount; - atoms(): string; -} +export function token_supply_change_fee(current_block_height: bigint, network: Network): Amount; + +/** + * Given a signed challenge, an address and a message, verify that + * the signature is produced by signing the message with the private key + * that derived the given public key. + * This function is used for verifying messages-related challenges. + * + * Note: for signatures that were created by `sign_challenge`, the provided address must be + * a 'pubkeyhash' address. + * + * Note: currently this function never returns `false` - it either returns `true` or fails with an error. + */ +export function verify_challenge(address: string, network: Network, signed_challenge: Uint8Array, message: Uint8Array): boolean; + +/** + * Given a digital signature, a public key and a message. Verify that + * the signature is produced by signing the message with the private key + * that derived the given public key. + * Note that this function is used for verifying messages related to spending, + * such as transaction input witness. + */ +export function verify_signature_for_spending(public_key: Uint8Array, signature: Uint8Array, message: Uint8Array): boolean; + +/** + * Verify a signed transaction intent. + * + * Parameters: + * `expected_signed_message` - the message that is supposed to be signed; this must have been + * produced by `make_transaction_intent_message_to_sign`. + * `encoded_signed_intent` - the signed transaction intent produced by `encode_signed_transaction_intent`. + * `input_destinations` - an array of addresses (strings), corresponding to the transaction's input destinations + * (note that this function treats "pub key" and "pub key hash" addresses interchangeably, so it's ok to pass + * one instead of the other). + * `network` - the network being used (needed to decode the addresses). + */ +export function verify_transaction_intent(expected_signed_message: Uint8Array, encoded_signed_intent: Uint8Array, input_destinations: string[], network: Network): void; diff --git a/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.js b/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.js index d7eb5de..4601cab 100644 --- a/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.js +++ b/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers.js @@ -1,561 +1,529 @@ +/* @ts-self-types="./wasm_wrappers.d.ts" */ -let imports = {}; -imports['__wbindgen_placeholder__'] = module.exports; -let wasm; -const { TextDecoder, TextEncoder } = require(`util`); - -function addToExternrefTable0(obj) { - const idx = wasm.__externref_table_alloc(); - wasm.__wbindgen_export_2.set(idx, obj); - return idx; -} - -function handleError(f, args) { - try { - return f.apply(this, args); - } catch (e) { - const idx = addToExternrefTable0(e); - wasm.__wbindgen_exn_store(idx); - } -} - -let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - -let cachedUint8ArrayMemory0 = null; - -function getUint8ArrayMemory0() { - if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { - cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); +/** + * Amount type abstraction. The amount type is stored in a string + * since JavaScript number type cannot fit 128-bit integers. + * The amount is given as an integer in units of "atoms". + * Atoms are the smallest, indivisible amount of a coin or token. + */ +class Amount { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(Amount.prototype); + obj.__wbg_ptr = ptr; + AmountFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; } - return cachedUint8ArrayMemory0; -} - -function getStringFromWasm0(ptr, len) { - ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); -} - -function isLikeNone(x) { - return x === undefined || x === null; -} - -let WASM_VECTOR_LEN = 0; - -let cachedTextEncoder = new TextEncoder('utf-8'); - -const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' - ? function (arg, view) { - return cachedTextEncoder.encodeInto(arg, view); -} - : function (arg, view) { - const buf = cachedTextEncoder.encode(arg); - view.set(buf); - return { - read: arg.length, - written: buf.length - }; -}); - -function passStringToWasm0(arg, malloc, realloc) { - - if (realloc === undefined) { - const buf = cachedTextEncoder.encode(arg); - const ptr = malloc(buf.length, 1) >>> 0; - getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); - WASM_VECTOR_LEN = buf.length; + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + AmountFinalization.unregister(this); return ptr; } - - let len = arg.length; - let ptr = malloc(len, 1) >>> 0; - - const mem = getUint8ArrayMemory0(); - - let offset = 0; - - for (; offset < len; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_amount_free(ptr, 0); } - - if (offset !== len) { - if (offset !== 0) { - arg = arg.slice(offset); + /** + * @returns {string} + */ + atoms() { + let deferred1_0; + let deferred1_1; + try { + const ptr = this.__destroy_into_raw(); + const ret = wasm.amount_atoms(ptr); + deferred1_0 = ret[0]; + deferred1_1 = ret[1]; + return getStringFromWasm0(ret[0], ret[1]); + } finally { + wasm.__wbindgen_free(deferred1_0, deferred1_1, 1); } - ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; - const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); - const ret = encodeString(arg, view); - - offset += ret.written; - ptr = realloc(ptr, len, offset, 1) >>> 0; } - - WASM_VECTOR_LEN = offset; - return ptr; + /** + * @param {string} atoms + * @returns {Amount} + */ + static from_atoms(atoms) { + const ptr0 = passStringToWasm0(atoms, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.amount_from_atoms(ptr0, len0); + return Amount.__wrap(ret); + } } +if (Symbol.dispose) Amount.prototype[Symbol.dispose] = Amount.prototype.free; +exports.Amount = Amount; -let cachedDataViewMemory0 = null; +/** + * Indicates whether a token can be frozen + * @enum {0 | 1} + */ +const FreezableToken = Object.freeze({ + No: 0, "0": "No", + Yes: 1, "1": "Yes", +}); +exports.FreezableToken = FreezableToken; -function getDataViewMemory0() { - if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { - cachedDataViewMemory0 = new DataView(wasm.memory.buffer); - } - return cachedDataViewMemory0; -} +/** + * The network, for which an operation to be done. Mainnet, testnet, etc. + * @enum {0 | 1 | 2 | 3} + */ +const Network = Object.freeze({ + Mainnet: 0, "0": "Mainnet", + Testnet: 1, "1": "Testnet", + Regtest: 2, "2": "Regtest", + Signet: 3, "3": "Signet", +}); +exports.Network = Network; -function passArray8ToWasm0(arg, malloc) { - const ptr = malloc(arg.length * 1, 1) >>> 0; - getUint8ArrayMemory0().set(arg, ptr / 1); - WASM_VECTOR_LEN = arg.length; - return ptr; -} +/** + * The part of the transaction that will be committed in the signature. Similar to bitcoin's sighash. + * @enum {0 | 1 | 2 | 3} + */ +const SignatureHashType = Object.freeze({ + ALL: 0, "0": "ALL", + NONE: 1, "1": "NONE", + SINGLE: 2, "2": "SINGLE", + ANYONECANPAY: 3, "3": "ANYONECANPAY", +}); +exports.SignatureHashType = SignatureHashType; -function getArrayU8FromWasm0(ptr, len) { - ptr = ptr >>> 0; - return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); -} /** - * A utxo can either come from a transaction or a block reward. - * Given a source id, whether from a block reward or transaction, this function - * takes a generic id with it, and returns serialized binary data of the id - * with the given source id. - * @param {Uint8Array} id - * @param {SourceId} source - * @returns {Uint8Array} + * A utxo can either come from a transaction or a block reward. This enum signifies that. + * @enum {0 | 1} */ -module.exports.encode_outpoint_source_id = function(id, source) { - const ptr0 = passArray8ToWasm0(id, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_outpoint_source_id(ptr0, len0, source); - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; +const SourceId = Object.freeze({ + Transaction: 0, "0": "Transaction", + BlockReward: 1, "1": "BlockReward", +}); +exports.SourceId = SourceId; /** - * Generates a new, random private key from entropy - * @returns {Uint8Array} + * Indicates whether a token can be unfrozen once frozen + * @enum {0 | 1} */ -module.exports.make_private_key = function() { - const ret = wasm.make_private_key(); - var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v1; -}; +const TokenUnfreezable = Object.freeze({ + No: 0, "0": "No", + Yes: 1, "1": "Yes", +}); +exports.TokenUnfreezable = TokenUnfreezable; -function takeFromExternrefTable0(idx) { - const value = wasm.__wbindgen_export_2.get(idx); - wasm.__externref_table_dealloc(idx); - return value; -} /** - * Create the default account's extended private key for a given mnemonic - * derivation path: 44'/mintlayer_coin_type'/0' - * @param {string} mnemonic + * The token supply of a specific token, set on issuance + * @enum {0 | 1 | 2} + */ +const TotalSupply = Object.freeze({ + /** + * Can be issued with no limit, but then can be locked to have a fixed supply. + */ + Lockable: 0, "0": "Lockable", + /** + * Unlimited supply, no limits except for numeric limits due to u128 + */ + Unlimited: 1, "1": "Unlimited", + /** + * On issuance, the total number of coins is fixed + */ + Fixed: 2, "2": "Fixed", +}); +exports.TotalSupply = TotalSupply; + +/** + * Returns the fee that needs to be paid by a transaction for issuing a data deposit + * @param {bigint} current_block_height * @param {Network} network - * @returns {Uint8Array} + * @returns {Amount} */ -module.exports.make_default_account_privkey = function(mnemonic, network) { - const ptr0 = passStringToWasm0(mnemonic, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.make_default_account_privkey(ptr0, len0, network); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; +function data_deposit_fee(current_block_height, network) { + const ret = wasm.data_deposit_fee(current_block_height, network); + return Amount.__wrap(ret); +} +exports.data_deposit_fee = data_deposit_fee; /** - * From an extended private key create a receiving private key for a given key index - * derivation path: current_derivation_path/0/key_index - * @param {Uint8Array} private_key_bytes - * @param {number} key_index - * @returns {Uint8Array} + * Decodes a partially signed transaction from its binary encoding into a JavaScript object. + * @param {Uint8Array} transaction + * @param {Network} network + * @returns {any} */ -module.exports.make_receiving_address = function(private_key_bytes, key_index) { - const ptr0 = passArray8ToWasm0(private_key_bytes, wasm.__wbindgen_malloc); +function decode_partially_signed_transaction_to_js(transaction, network) { + const ptr0 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.make_receiving_address(ptr0, len0, key_index); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); + const ret = wasm.decode_partially_signed_transaction_to_js(ptr0, len0, network); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return takeFromExternrefTable0(ret[0]); +} +exports.decode_partially_signed_transaction_to_js = decode_partially_signed_transaction_to_js; /** - * From an extended private key create a change private key for a given key index - * derivation path: current_derivation_path/1/key_index - * @param {Uint8Array} private_key_bytes - * @param {number} key_index - * @returns {Uint8Array} + * Decodes a signed transaction from its binary encoding into a JavaScript object. + * @param {Uint8Array} transaction + * @param {Network} network + * @returns {any} */ -module.exports.make_change_address = function(private_key_bytes, key_index) { - const ptr0 = passArray8ToWasm0(private_key_bytes, wasm.__wbindgen_malloc); +function decode_signed_transaction_to_js(transaction, network) { + const ptr0 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.make_change_address(ptr0, len0, key_index); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); + const ret = wasm.decode_signed_transaction_to_js(ptr0, len0, network); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return takeFromExternrefTable0(ret[0]); +} +exports.decode_signed_transaction_to_js = decode_signed_transaction_to_js; /** - * Given a public key (as bytes) and a network type (mainnet, testnet, etc), - * return the address public key hash from that public key as an address - * @param {Uint8Array} public_key_bytes + * 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. * @param {Network} network - * @returns {string} + * @param {Amount} pledge_amount + * @param {Amount} pool_balance + * @returns {Amount} */ -module.exports.pubkey_to_pubkeyhash_address = function(public_key_bytes, network) { - let deferred3_0; - let deferred3_1; - try { - const ptr0 = passArray8ToWasm0(public_key_bytes, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.pubkey_to_pubkeyhash_address(ptr0, len0, network); - var ptr2 = ret[0]; - var len2 = ret[1]; - if (ret[3]) { - ptr2 = 0; len2 = 0; - throw takeFromExternrefTable0(ret[2]); - } - deferred3_0 = ptr2; - deferred3_1 = len2; - return getStringFromWasm0(ptr2, len2); - } finally { - wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); +function effective_pool_balance(network, pledge_amount, pool_balance) { + _assertClass(pledge_amount, Amount); + var ptr0 = pledge_amount.__destroy_into_raw(); + _assertClass(pool_balance, Amount); + var ptr1 = pool_balance.__destroy_into_raw(); + const ret = wasm.effective_pool_balance(network, ptr0, ptr1); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); } -}; + return Amount.__wrap(ret[0]); +} +exports.effective_pool_balance = effective_pool_balance; /** - * Given a private key, as bytes, return the bytes of the corresponding public key - * @param {Uint8Array} private_key + * Given ask and give amounts and a conclude key create output that creates an order. + * + * 'ask_token_id': the parameter represents a Token if it's Some and coins otherwise. + * 'give_token_id': the parameter represents a Token if it's Some and coins otherwise. + * @param {Amount} ask_amount + * @param {string | null | undefined} ask_token_id + * @param {Amount} give_amount + * @param {string | null | undefined} give_token_id + * @param {string} conclude_address + * @param {Network} network * @returns {Uint8Array} */ -module.exports.public_key_from_private_key = function(private_key) { - const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.public_key_from_private_key(ptr0, len0); +function encode_create_order_output(ask_amount, ask_token_id, give_amount, give_token_id, conclude_address, network) { + _assertClass(ask_amount, Amount); + var ptr0 = ask_amount.__destroy_into_raw(); + var ptr1 = isLikeNone(ask_token_id) ? 0 : passStringToWasm0(ask_token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + _assertClass(give_amount, Amount); + var ptr2 = give_amount.__destroy_into_raw(); + var ptr3 = isLikeNone(give_token_id) ? 0 : passStringToWasm0(give_token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len3 = WASM_VECTOR_LEN; + const ptr4 = passStringToWasm0(conclude_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len4 = WASM_VECTOR_LEN; + const ret = wasm.encode_create_order_output(ptr0, ptr1, len1, ptr2, ptr3, len3, ptr4, len4, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v6; +} +exports.encode_create_order_output = encode_create_order_output; /** - * Return the extended public key from an extended private key - * @param {Uint8Array} private_key_bytes + * Convert the specified string address into a Destination object, encoded as bytes. + * @param {string} address + * @param {Network} network * @returns {Uint8Array} */ -module.exports.extended_public_key_from_extended_private_key = function(private_key_bytes) { - const ptr0 = passArray8ToWasm0(private_key_bytes, wasm.__wbindgen_malloc); +function encode_destination(address, network) { + const ptr0 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.extended_public_key_from_extended_private_key(ptr0, len0); + const ret = wasm.encode_destination(ptr0, len0, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v2; -}; +} +exports.encode_destination = encode_destination; /** - * From an extended public key create a receiving public key for a given key index - * derivation path: current_derivation_path/0/key_index - * @param {Uint8Array} extended_public_key_bytes - * @param {number} key_index + * Given a token_id, new authority destination and nonce return an encoded change token authority input + * @param {string} token_id + * @param {string} new_authority + * @param {bigint} nonce + * @param {Network} network * @returns {Uint8Array} */ -module.exports.make_receiving_address_public_key = function(extended_public_key_bytes, key_index) { - const ptr0 = passArray8ToWasm0(extended_public_key_bytes, wasm.__wbindgen_malloc); +function encode_input_for_change_token_authority(token_id, new_authority, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.make_receiving_address_public_key(ptr0, len0, key_index); + const ptr1 = passStringToWasm0(new_authority, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.encode_input_for_change_token_authority(ptr0, len0, ptr1, len1, nonce, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v3; +} +exports.encode_input_for_change_token_authority = encode_input_for_change_token_authority; /** - * From an extended public key create a change public key for a given key index - * derivation path: current_derivation_path/1/key_index - * @param {Uint8Array} extended_public_key_bytes - * @param {number} key_index + * Given a token_id, new metadata uri and nonce return an encoded change token metadata uri input + * @param {string} token_id + * @param {string} new_metadata_uri + * @param {bigint} nonce + * @param {Network} network * @returns {Uint8Array} */ -module.exports.make_change_address_public_key = function(extended_public_key_bytes, key_index) { - const ptr0 = passArray8ToWasm0(extended_public_key_bytes, wasm.__wbindgen_malloc); +function encode_input_for_change_token_metadata_uri(token_id, new_metadata_uri, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.make_change_address_public_key(ptr0, len0, key_index); + const ptr1 = passStringToWasm0(new_metadata_uri, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.encode_input_for_change_token_metadata_uri(ptr0, len0, ptr1, len1, nonce, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v3; +} +exports.encode_input_for_change_token_metadata_uri = encode_input_for_change_token_metadata_uri; /** - * Given a message and a private key, sign the message with the given private key - * This kind of signature is to be used when signing spend requests, such as transaction - * input witness. - * @param {Uint8Array} private_key - * @param {Uint8Array} message + * Given an order id create an input that concludes the order. + * + * Note: the nonce is only needed before the orders V1 fork activation. After the fork the nonce is + * ignored and any value can be passed for the parameter. + * @param {string} order_id + * @param {bigint} nonce + * @param {bigint} current_block_height + * @param {Network} network * @returns {Uint8Array} */ -module.exports.sign_message_for_spending = function(private_key, message) { - const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); +function encode_input_for_conclude_order(order_id, nonce, current_block_height, network) { + const ptr0 = passStringToWasm0(order_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.sign_message_for_spending(ptr0, len0, ptr1, len1); + const ret = wasm.encode_input_for_conclude_order(ptr0, len0, nonce, current_block_height, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; - -/** - * Given a digital signature, a public key and a message. Verify that - * the signature is produced by signing the message with the private key - * that derived the given public key. - * Note that this function is used for verifying messages related to spending, - * such as transaction input witness. - * @param {Uint8Array} public_key - * @param {Uint8Array} signature - * @param {Uint8Array} message - * @returns {boolean} - */ -module.exports.verify_signature_for_spending = function(public_key, signature, message) { - const ptr0 = passArray8ToWasm0(public_key, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(signature, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); - const len2 = WASM_VECTOR_LEN; - const ret = wasm.verify_signature_for_spending(ptr0, len0, ptr1, len1, ptr2, len2); - if (ret[2]) { - throw takeFromExternrefTable0(ret[1]); - } - return ret[0] !== 0; -}; + return v2; +} +exports.encode_input_for_conclude_order = encode_input_for_conclude_order; /** - * Given a message and a private key, create and sign a challenge with the given private key. - * This kind of signature is to be used when signing challenges. - * @param {Uint8Array} private_key - * @param {Uint8Array} message + * Given an order id and an amount in the order's ask currency, create an input that fills the order. + * + * Note: + * 1) The nonce is only needed before the orders V1 fork activation. After the fork the nonce is + * ignored and any value can be passed for the parameter. + * 2) FillOrder inputs should not be signed, i.e. use `encode_witness_no_signature` for the inputs + * instead of `encode_witness`). + * Note that in orders v0 FillOrder inputs can technically have a signature, it's just not checked. + * But in orders V1 we actually require that those inputs don't have signatures. + * Also, in orders V1 the provided destination is always ignored. + * @param {string} order_id + * @param {Amount} fill_amount + * @param {string} destination + * @param {bigint} nonce + * @param {bigint} current_block_height + * @param {Network} network * @returns {Uint8Array} */ -module.exports.sign_challenge = function(private_key, message) { - const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); +function encode_input_for_fill_order(order_id, fill_amount, destination, nonce, current_block_height, network) { + const ptr0 = passStringToWasm0(order_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.sign_challenge(ptr0, len0, ptr1, len1); + _assertClass(fill_amount, Amount); + var ptr1 = fill_amount.__destroy_into_raw(); + const ptr2 = passStringToWasm0(destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.encode_input_for_fill_order(ptr0, len0, ptr1, ptr2, len2, nonce, current_block_height, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; + return v4; +} +exports.encode_input_for_fill_order = encode_input_for_fill_order; /** - * Given a signed challenge, an address and a message, verify that - * the signature is produced by signing the message with the private key - * that derived the given public key. - * This function is used for verifying messages-related challenges. - * - * Note: for signatures that were created by `sign_challenge`, the provided address must be - * a 'pubkeyhash' address. + * Given an order id create an input that freezes the order. * - * Note: currently this function never returns `false` - it either returns `true` or fails with an error. - * @param {string} address + * Note: order freezing is available only after the orders V1 fork activation. + * @param {string} order_id + * @param {bigint} current_block_height * @param {Network} network - * @param {Uint8Array} signed_challenge - * @param {Uint8Array} message - * @returns {boolean} + * @returns {Uint8Array} */ -module.exports.verify_challenge = function(address, network, signed_challenge, message) { - const ptr0 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_input_for_freeze_order(order_id, current_block_height, network) { + const ptr0 = passStringToWasm0(order_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(signed_challenge, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); - const len2 = WASM_VECTOR_LEN; - const ret = wasm.verify_challenge(ptr0, len0, network, ptr1, len1, ptr2, len2); - if (ret[2]) { - throw takeFromExternrefTable0(ret[1]); + const ret = wasm.encode_input_for_freeze_order(ptr0, len0, current_block_height, network); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); } - return ret[0] !== 0; -}; + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.encode_input_for_freeze_order = encode_input_for_freeze_order; /** - * Return the message that has to be signed to produce a signed transaction intent. - * @param {string} intent - * @param {string} transaction_id + * Given a token_id, is token unfreezable and nonce return an encoded freeze token input + * @param {string} token_id + * @param {TokenUnfreezable} is_token_unfreezable + * @param {bigint} nonce + * @param {Network} network * @returns {Uint8Array} */ -module.exports.make_transaction_intent_message_to_sign = function(intent, transaction_id) { - const ptr0 = passStringToWasm0(intent, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_input_for_freeze_token(token_id, is_token_unfreezable, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(transaction_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.make_transaction_intent_message_to_sign(ptr0, len0, ptr1, len1); + const ret = wasm.encode_input_for_freeze_token(ptr0, len0, is_token_unfreezable, nonce, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; + return v2; +} +exports.encode_input_for_freeze_token = encode_input_for_freeze_token; /** - * Return a `SignedTransactionIntent` object as bytes given the message and encoded signatures. - * - * Note: to produce a valid signed intent one is expected to sign the corresponding message by private keys - * corresponding to each input of the transaction. - * - * Parameters: - * `signed_message` - this must have been produced by `make_transaction_intent_message_to_sign`. - * `signatures` - this should be an array of arrays of bytes, each of them representing an individual signature - * of `signed_message` produced by `sign_challenge` using the private key for the corresponding input destination - * of the transaction. The number of signatures must be equal to the number of inputs in the transaction. - * @param {Uint8Array} signed_message - * @param {any} signatures + * Given a token_id and nonce return an encoded lock_token_supply input + * @param {string} token_id + * @param {bigint} nonce + * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_signed_transaction_intent = function(signed_message, signatures) { - const ptr0 = passArray8ToWasm0(signed_message, wasm.__wbindgen_malloc); +function encode_input_for_lock_token_supply(token_id, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_signed_transaction_intent(ptr0, len0, signatures); + const ret = wasm.encode_input_for_lock_token_supply(ptr0, len0, nonce, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v2; -}; - -function passArrayJsValueToWasm0(array, malloc) { - const ptr = malloc(array.length * 4, 4) >>> 0; - for (let i = 0; i < array.length; i++) { - const add = addToExternrefTable0(array[i]); - getDataViewMemory0().setUint32(ptr + 4 * i, add, true); - } - WASM_VECTOR_LEN = array.length; - return ptr; } +exports.encode_input_for_lock_token_supply = encode_input_for_lock_token_supply; + /** - * Verify a signed transaction intent. - * - * Parameters: - * `expected_signed_message` - the message that is supposed to be signed; this must have been - * produced by `make_transaction_intent_message_to_sign`. - * `encoded_signed_intent` - the signed transaction intent produced by `encode_signed_transaction_intent`. - * `input_destinations` - an array of addresses (strings), corresponding to the transaction's input destinations - * (note that this function treats "pub key" and "pub key hash" addresses interchangeably, so it's ok to pass - * one instead of the other). - * `network` - the network being used (needed to decode the addresses). - * @param {Uint8Array} expected_signed_message - * @param {Uint8Array} encoded_signed_intent - * @param {string[]} input_destinations + * Given a token_id, an amount of tokens to mint and nonce return an encoded mint tokens input + * @param {string} token_id + * @param {Amount} amount + * @param {bigint} nonce * @param {Network} network + * @returns {Uint8Array} */ -module.exports.verify_transaction_intent = function(expected_signed_message, encoded_signed_intent, input_destinations, network) { - const ptr0 = passArray8ToWasm0(expected_signed_message, wasm.__wbindgen_malloc); +function encode_input_for_mint_tokens(token_id, amount, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(encoded_signed_intent, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passArrayJsValueToWasm0(input_destinations, wasm.__wbindgen_malloc); - const len2 = WASM_VECTOR_LEN; - const ret = wasm.verify_transaction_intent(ptr0, len0, ptr1, len1, ptr2, len2, network); - if (ret[1]) { - throw takeFromExternrefTable0(ret[0]); - } -}; - -function _assertClass(instance, klass) { - if (!(instance instanceof klass)) { - throw new Error(`expected instance of ${klass.name}`); + _assertClass(amount, Amount); + var ptr1 = amount.__destroy_into_raw(); + const ret = wasm.encode_input_for_mint_tokens(ptr0, len0, ptr1, nonce, network); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); } + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; } +exports.encode_input_for_mint_tokens = encode_input_for_mint_tokens; + /** - * Given a destination address, an amount and a network type (mainnet, testnet, etc), this function - * creates an output of type Transfer, and returns it as bytes. - * @param {Amount} amount - * @param {string} address + * Given a token_id and nonce return an encoded unfreeze token input + * @param {string} token_id + * @param {bigint} nonce * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_transfer = function(amount, address, network) { - _assertClass(amount, Amount); - var ptr0 = amount.__destroy_into_raw(); - const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_transfer(ptr0, ptr1, len1, network); +function encode_input_for_unfreeze_token(token_id, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.encode_input_for_unfreeze_token(ptr0, len0, nonce, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; + return v2; +} +exports.encode_input_for_unfreeze_token = encode_input_for_unfreeze_token; /** - * Given a destination address, an amount, token ID (in address form) and a network type (mainnet, testnet, etc), this function - * creates an output of type Transfer for tokens, and returns it as bytes. - * @param {Amount} amount - * @param {string} address + * Given a token_id and nonce return an encoded unmint tokens input * @param {string} token_id + * @param {bigint} nonce * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_token_transfer = function(amount, address, token_id, network) { - _assertClass(amount, Amount); - var ptr0 = amount.__destroy_into_raw(); - const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len2 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_token_transfer(ptr0, ptr1, len1, ptr2, len2, network); +function encode_input_for_unmint_tokens(token_id, nonce, network) { + const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.encode_input_for_unmint_tokens(ptr0, len0, nonce, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v4; -}; + return v2; +} +exports.encode_input_for_unmint_tokens = encode_input_for_unmint_tokens; /** - * Given the current block height and a network type (mainnet, testnet, etc), - * this function returns the number of blocks, after which a pool that decommissioned, - * will have its funds unlocked and available for spending. - * The current block height information is used in case a network upgrade changed the value. - * @param {bigint} current_block_height + * Given an output source id as bytes, and an output index, together representing a utxo, + * this function returns the input that puts them together, as bytes. + * @param {Uint8Array} outpoint_source_id + * @param {number} output_index + * @returns {Uint8Array} + */ +function encode_input_for_utxo(outpoint_source_id, output_index) { + const ptr0 = passArray8ToWasm0(outpoint_source_id, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.encode_input_for_utxo(ptr0, len0, output_index); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.encode_input_for_utxo = encode_input_for_utxo; + +/** + * Given a delegation id, an amount and a network type (mainnet, testnet, etc), this function + * creates an input that withdraws from a delegation. + * A nonce is needed because this spends from an account. The nonce must be in sequence for everything in that account. + * @param {string} delegation_id + * @param {Amount} amount + * @param {bigint} nonce * @param {Network} network - * @returns {bigint} + * @returns {Uint8Array} */ -module.exports.staking_pool_spend_maturity_block_count = function(current_block_height, network) { - const ret = wasm.staking_pool_spend_maturity_block_count(current_block_height, network); - return BigInt.asUintN(64, ret); -}; +function encode_input_for_withdraw_from_delegation(delegation_id, amount, nonce, network) { + const ptr0 = passStringToWasm0(delegation_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + _assertClass(amount, Amount); + var ptr1 = amount.__destroy_into_raw(); + const ret = wasm.encode_input_for_withdraw_from_delegation(ptr0, len0, ptr1, nonce, network); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; +} +exports.encode_input_for_withdraw_from_delegation = encode_input_for_withdraw_from_delegation; /** * Given a number of blocks, this function returns the output timelock @@ -564,12 +532,13 @@ module.exports.staking_pool_spend_maturity_block_count = function(current_block_ * @param {bigint} block_count * @returns {Uint8Array} */ -module.exports.encode_lock_for_block_count = function(block_count) { +function encode_lock_for_block_count(block_count) { const ret = wasm.encode_lock_for_block_count(block_count); var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v1; -}; +} +exports.encode_lock_for_block_count = encode_lock_for_block_count; /** * Given a number of clock seconds, this function returns the output timelock @@ -578,101 +547,89 @@ module.exports.encode_lock_for_block_count = function(block_count) { * @param {bigint} total_seconds * @returns {Uint8Array} */ -module.exports.encode_lock_for_seconds = function(total_seconds) { +function encode_lock_for_seconds(total_seconds) { const ret = wasm.encode_lock_for_seconds(total_seconds); var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v1; -}; +} +exports.encode_lock_for_seconds = encode_lock_for_seconds; /** - * Given a timestamp represented by as unix timestamp, i.e., number of seconds since unix epoch, - * this function returns the output timelock which is used in locked outputs to lock an output - * until the given timestamp - * @param {bigint} timestamp_since_epoch_in_seconds + * Given a block height, this function returns the output timelock which is used in + * locked outputs to lock an output until that block height is reached. + * @param {bigint} block_height * @returns {Uint8Array} */ -module.exports.encode_lock_until_time = function(timestamp_since_epoch_in_seconds) { - const ret = wasm.encode_lock_until_time(timestamp_since_epoch_in_seconds); +function encode_lock_until_height(block_height) { + const ret = wasm.encode_lock_until_height(block_height); var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v1; -}; +} +exports.encode_lock_until_height = encode_lock_until_height; /** - * Given a block height, this function returns the output timelock which is used in - * locked outputs to lock an output until that block height is reached. - * @param {bigint} block_height + * Given a timestamp represented by as unix timestamp, i.e., number of seconds since unix epoch, + * this function returns the output timelock which is used in locked outputs to lock an output + * until the given timestamp + * @param {bigint} timestamp_since_epoch_in_seconds * @returns {Uint8Array} */ -module.exports.encode_lock_until_height = function(block_height) { - const ret = wasm.encode_lock_until_height(block_height); +function encode_lock_until_time(timestamp_since_epoch_in_seconds) { + const ret = wasm.encode_lock_until_time(timestamp_since_epoch_in_seconds); var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v1; -}; +} +exports.encode_lock_until_time = encode_lock_until_time; /** - * Given a valid receiving address, and a locking rule as bytes (available in this file), - * and a network type (mainnet, testnet, etc), this function creates an output of type - * LockThenTransfer with the parameters provided. - * @param {Amount} amount - * @param {string} address - * @param {Uint8Array} lock + * Given an arbitrary number of public keys as bytes, number of minimum required signatures, and a network type, this function returns + * the multisig challenge, as bytes. + * @param {Uint8Array} public_keys + * @param {number} min_required_signatures * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_lock_then_transfer = function(amount, address, lock, network) { - _assertClass(amount, Amount); - var ptr0 = amount.__destroy_into_raw(); - const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(lock, wasm.__wbindgen_malloc); - const len2 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_lock_then_transfer(ptr0, ptr1, len1, ptr2, len2, network); +function encode_multisig_challenge(public_keys, min_required_signatures, network) { + const ptr0 = passArray8ToWasm0(public_keys, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.encode_multisig_challenge(ptr0, len0, min_required_signatures, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v4; -}; + return v2; +} +exports.encode_multisig_challenge = encode_multisig_challenge; /** - * Given a valid receiving address, token ID (in address form), a locking rule as bytes (available in this file), - * and a network type (mainnet, testnet, etc), this function creates an output of type - * LockThenTransfer with the parameters provided. - * @param {Amount} amount - * @param {string} address - * @param {string} token_id - * @param {Uint8Array} lock - * @param {Network} network + * A utxo can either come from a transaction or a block reward. + * Given a source id, whether from a block reward or transaction, this function + * takes a generic id with it, and returns serialized binary data of the id + * with the given source id. + * @param {Uint8Array} id + * @param {SourceId} source * @returns {Uint8Array} */ -module.exports.encode_output_token_lock_then_transfer = function(amount, address, token_id, lock, network) { - _assertClass(amount, Amount); - var ptr0 = amount.__destroy_into_raw(); - const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len2 = WASM_VECTOR_LEN; - const ptr3 = passArray8ToWasm0(lock, wasm.__wbindgen_malloc); - const len3 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_token_lock_then_transfer(ptr0, ptr1, len1, ptr2, len2, ptr3, len3, network); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); +function encode_outpoint_source_id(id, source) { + const ptr0 = passArray8ToWasm0(id, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.encode_outpoint_source_id(ptr0, len0, source); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v5; -}; + return v2; +} +exports.encode_outpoint_source_id = encode_outpoint_source_id; /** * Given an amount, this function creates an output (as bytes) to burn a given amount of coins * @param {Amount} amount * @returns {Uint8Array} */ -module.exports.encode_output_coin_burn = function(amount) { +function encode_output_coin_burn(amount) { _assertClass(amount, Amount); var ptr0 = amount.__destroy_into_raw(); const ret = wasm.encode_output_coin_burn(ptr0); @@ -682,52 +639,78 @@ module.exports.encode_output_coin_burn = function(amount) { var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v2; -}; +} +exports.encode_output_coin_burn = encode_output_coin_burn; /** - * Given an amount, token ID (in address form) and network type (mainnet, testnet, etc), - * this function creates an output (as bytes) to burn a given amount of tokens - * @param {Amount} amount - * @param {string} token_id + * Given a pool id as string, an owner address and a network type (mainnet, testnet, etc), + * this function returns an output (as bytes) to create a delegation to the given pool. + * The owner address is the address that is authorized to withdraw from that delegation. + * @param {string} pool_id + * @param {string} owner_address * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_token_burn = function(amount, token_id, network) { - _assertClass(amount, Amount); - var ptr0 = amount.__destroy_into_raw(); - const ptr1 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_output_create_delegation(pool_id, owner_address, network) { + const ptr0 = passStringToWasm0(pool_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(owner_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_token_burn(ptr0, ptr1, len1, network); + const ret = wasm.encode_output_create_delegation(ptr0, len0, ptr1, len1, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; +} +exports.encode_output_create_delegation = encode_output_create_delegation; /** - * Given a pool id as string, an owner address and a network type (mainnet, testnet, etc), - * this function returns an output (as bytes) to create a delegation to the given pool. - * The owner address is the address that is authorized to withdraw from that delegation. + * Given a pool id, staking data as bytes and the network type (mainnet, testnet, etc), + * this function returns an output that creates that staking pool. + * Note that the pool id is mandated to be taken from the hash of the first input. + * It is not arbitrary. + * + * Note: a UTXO of this kind is consumed when decommissioning a pool (provided that the pool + * never staked). * @param {string} pool_id - * @param {string} owner_address + * @param {Uint8Array} pool_data * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_create_delegation = function(pool_id, owner_address, network) { +function encode_output_create_stake_pool(pool_id, pool_data, network) { const ptr0 = passStringToWasm0(pool_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(owner_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const ptr1 = passArray8ToWasm0(pool_data, wasm.__wbindgen_malloc); const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_create_delegation(ptr0, len0, ptr1, len1, network); + const ret = wasm.encode_output_create_stake_pool(ptr0, len0, ptr1, len1, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; +} +exports.encode_output_create_stake_pool = encode_output_create_stake_pool; + +/** + * Given data to be deposited in the blockchain, this function provides the output that deposits this data + * @param {Uint8Array} data + * @returns {Uint8Array} + */ +function encode_output_data_deposit(data) { + const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.encode_output_data_deposit(ptr0, len0); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.encode_output_data_deposit = encode_output_data_deposit; /** * Given a delegation id (as string, in address form), an amount and a network type (mainnet, testnet, etc), @@ -737,7 +720,7 @@ module.exports.encode_output_create_delegation = function(pool_id, owner_address * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_delegate_staking = function(amount, delegation_id, network) { +function encode_output_delegate_staking(amount, delegation_id, network) { _assertClass(amount, Amount); var ptr0 = amount.__destroy_into_raw(); const ptr1 = passStringToWasm0(delegation_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -749,127 +732,43 @@ module.exports.encode_output_delegate_staking = function(amount, delegation_id, var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; +} +exports.encode_output_delegate_staking = encode_output_delegate_staking; /** - * This function returns the staking pool data needed to create a staking pool in an output as bytes, - * given its parameters and the network type (testnet, mainnet, etc). - * @param {Amount} value - * @param {string} staker - * @param {string} vrf_public_key - * @param {string} decommission_key - * @param {number} margin_ratio_per_thousand - * @param {Amount} cost_per_block + * Given the parameters needed to create hash timelock contract, and a network type (mainnet, testnet, etc), + * this function creates an output. + * @param {Amount} amount + * @param {string | null | undefined} token_id + * @param {string} secret_hash + * @param {string} spend_address + * @param {string} refund_address + * @param {Uint8Array} refund_timelock * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_stake_pool_data = function(value, staker, vrf_public_key, decommission_key, margin_ratio_per_thousand, cost_per_block, network) { - _assertClass(value, Amount); - var ptr0 = value.__destroy_into_raw(); - const ptr1 = passStringToWasm0(staker, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passStringToWasm0(vrf_public_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_output_htlc(amount, token_id, secret_hash, spend_address, refund_address, refund_timelock, network) { + _assertClass(amount, Amount); + var ptr0 = amount.__destroy_into_raw(); + var ptr1 = isLikeNone(token_id) ? 0 : passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(secret_hash, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len2 = WASM_VECTOR_LEN; - const ptr3 = passStringToWasm0(decommission_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const ptr3 = passStringToWasm0(spend_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len3 = WASM_VECTOR_LEN; - _assertClass(cost_per_block, Amount); - var ptr4 = cost_per_block.__destroy_into_raw(); - const ret = wasm.encode_stake_pool_data(ptr0, ptr1, len1, ptr2, len2, ptr3, len3, margin_ratio_per_thousand, ptr4, network); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v6; -}; - -/** - * Given a pool id, staking data as bytes and the network type (mainnet, testnet, etc), - * this function returns an output that creates that staking pool. - * Note that the pool id is mandated to be taken from the hash of the first input. - * It is not arbitrary. - * @param {string} pool_id - * @param {Uint8Array} pool_data - * @param {Network} network - * @returns {Uint8Array} - */ -module.exports.encode_output_create_stake_pool = function(pool_id, pool_data, network) { - const ptr0 = passStringToWasm0(pool_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(pool_data, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_create_stake_pool(ptr0, len0, ptr1, len1, network); + const ptr4 = passStringToWasm0(refund_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len4 = WASM_VECTOR_LEN; + const ptr5 = passArray8ToWasm0(refund_timelock, wasm.__wbindgen_malloc); + const len5 = WASM_VECTOR_LEN; + const ret = wasm.encode_output_htlc(ptr0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v7 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; - -/** - * Returns the fee that needs to be paid by a transaction for issuing a new fungible token - * @param {bigint} _current_block_height - * @param {Network} network - * @returns {Amount} - */ -module.exports.fungible_token_issuance_fee = function(_current_block_height, network) { - const ret = wasm.fungible_token_issuance_fee(_current_block_height, network); - return Amount.__wrap(ret); -}; - -/** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for issuing a new NFT - * The current block height information is used in case a network upgrade changed the value. - * @param {bigint} current_block_height - * @param {Network} network - * @returns {Amount} - */ -module.exports.nft_issuance_fee = function(current_block_height, network) { - const ret = wasm.nft_issuance_fee(current_block_height, network); - return Amount.__wrap(ret); -}; - -/** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for changing the total supply of a token - * by either minting or unminting tokens - * The current block height information is used in case a network upgrade changed the value. - * @param {bigint} current_block_height - * @param {Network} network - * @returns {Amount} - */ -module.exports.token_supply_change_fee = function(current_block_height, network) { - const ret = wasm.token_supply_change_fee(current_block_height, network); - return Amount.__wrap(ret); -}; - -/** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for freezing/unfreezing a token - * The current block height information is used in case a network upgrade changed the value. - * @param {bigint} current_block_height - * @param {Network} network - * @returns {Amount} - */ -module.exports.token_freeze_fee = function(current_block_height, network) { - const ret = wasm.token_freeze_fee(current_block_height, network); - return Amount.__wrap(ret); -}; - -/** - * Given the current block height and a network type (mainnet, testnet, etc), - * this will return the fee that needs to be paid by a transaction for changing the authority of a token - * The current block height information is used in case a network upgrade changed the value. - * @param {bigint} current_block_height - * @param {Network} network - * @returns {Amount} - */ -module.exports.token_change_authority_fee = function(current_block_height, network) { - const ret = wasm.token_change_authority_fee(current_block_height, network); - return Amount.__wrap(ret); -}; + return v7; +} +exports.encode_output_htlc = encode_output_htlc; /** * Given the parameters needed to issue a fungible token, and a network type (mainnet, testnet, etc), @@ -885,7 +784,7 @@ module.exports.token_change_authority_fee = function(current_block_height, netwo * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_issue_fungible_token = function(authority, token_ticker, metadata_uri, number_of_decimals, total_supply, supply_amount, is_token_freezable, _current_block_height, network) { +function encode_output_issue_fungible_token(authority, token_ticker, metadata_uri, number_of_decimals, total_supply, supply_amount, is_token_freezable, _current_block_height, network) { const ptr0 = passStringToWasm0(authority, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; const ptr1 = passStringToWasm0(token_ticker, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -904,34 +803,8 @@ module.exports.encode_output_issue_fungible_token = function(authority, token_ti var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v5; -}; - -/** - * Returns the Fungible/NFT Token ID for the given inputs of a transaction - * @param {Uint8Array} inputs - * @param {Network} network - * @returns {string} - */ -module.exports.get_token_id = function(inputs, network) { - let deferred3_0; - let deferred3_1; - try { - const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.get_token_id(ptr0, len0, network); - var ptr2 = ret[0]; - var len2 = ret[1]; - if (ret[3]) { - ptr2 = 0; len2 = 0; - throw takeFromExternrefTable0(ret[2]); - } - deferred3_0 = ptr2; - deferred3_1 = len2; - return getStringFromWasm0(ptr2, len2); - } finally { - wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); - } -}; +} +exports.encode_output_issue_fungible_token = encode_output_issue_fungible_token; /** * Given the parameters needed to issue an NFT, and a network type (mainnet, testnet, etc), @@ -950,7 +823,7 @@ module.exports.get_token_id = function(inputs, network) { * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_issue_nft = function(token_id, authority, name, ticker, description, media_hash, creator, media_uri, icon_uri, additional_metadata_uri, _current_block_height, network) { +function encode_output_issue_nft(token_id, authority, name, ticker, description, media_hash, creator, media_uri, icon_uri, additional_metadata_uri, _current_block_height, network) { const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; const ptr1 = passStringToWasm0(authority, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -978,324 +851,229 @@ module.exports.encode_output_issue_nft = function(token_id, authority, name, tic var v11 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v11; -}; - -/** - * Given data to be deposited in the blockchain, this function provides the output that deposits this data - * @param {Uint8Array} data - * @returns {Uint8Array} - */ -module.exports.encode_output_data_deposit = function(data) { - const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_data_deposit(ptr0, len0); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; - -/** - * Returns the fee that needs to be paid by a transaction for issuing a data deposit - * @param {bigint} current_block_height - * @param {Network} network - * @returns {Amount} - */ -module.exports.data_deposit_fee = function(current_block_height, network) { - const ret = wasm.data_deposit_fee(current_block_height, network); - return Amount.__wrap(ret); -}; +} +exports.encode_output_issue_nft = encode_output_issue_nft; /** - * Given the parameters needed to create hash timelock contract, and a network type (mainnet, testnet, etc), - * this function creates an output. + * Given a valid receiving address, and a locking rule as bytes (available in this file), + * and a network type (mainnet, testnet, etc), this function creates an output of type + * LockThenTransfer with the parameters provided. * @param {Amount} amount - * @param {string | null | undefined} token_id - * @param {string} secret_hash - * @param {string} spend_address - * @param {string} refund_address - * @param {Uint8Array} refund_timelock + * @param {string} address + * @param {Uint8Array} lock * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_output_htlc = function(amount, token_id, secret_hash, spend_address, refund_address, refund_timelock, network) { +function encode_output_lock_then_transfer(amount, address, lock, network) { _assertClass(amount, Amount); var ptr0 = amount.__destroy_into_raw(); - var ptr1 = isLikeNone(token_id) ? 0 : passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len1 = WASM_VECTOR_LEN; - const ptr2 = passStringToWasm0(secret_hash, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(lock, wasm.__wbindgen_malloc); const len2 = WASM_VECTOR_LEN; - const ptr3 = passStringToWasm0(spend_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len3 = WASM_VECTOR_LEN; - const ptr4 = passStringToWasm0(refund_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len4 = WASM_VECTOR_LEN; - const ptr5 = passArray8ToWasm0(refund_timelock, wasm.__wbindgen_malloc); - const len5 = WASM_VECTOR_LEN; - const ret = wasm.encode_output_htlc(ptr0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, network); + const ret = wasm.encode_output_lock_then_transfer(ptr0, ptr1, len1, ptr2, len2, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v7 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v7; -}; + return v4; +} +exports.encode_output_lock_then_transfer = encode_output_lock_then_transfer; /** - * Given a signed transaction and input outpoint that spends an htlc utxo, extract a secret that is - * encoded in the corresponding input signature - * @param {Uint8Array} signed_tx_bytes - * @param {boolean} strict_byte_size - * @param {Uint8Array} htlc_outpoint_source_id - * @param {number} htlc_output_index + * Given a pool id and a staker address, this function returns an output that is emitted + * when producing a block via that pool. + * + * Note: a UTXO of this kind is consumed when decommissioning a pool (provided that the pool + * has staked at least once). + * @param {string} pool_id + * @param {string} staker + * @param {Network} network * @returns {Uint8Array} */ -module.exports.extract_htlc_secret = function(signed_tx_bytes, strict_byte_size, htlc_outpoint_source_id, htlc_output_index) { - const ptr0 = passArray8ToWasm0(signed_tx_bytes, wasm.__wbindgen_malloc); +function encode_output_produce_block_from_stake(pool_id, staker, network) { + const ptr0 = passStringToWasm0(pool_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(htlc_outpoint_source_id, wasm.__wbindgen_malloc); + const ptr1 = passStringToWasm0(staker, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len1 = WASM_VECTOR_LEN; - const ret = wasm.extract_htlc_secret(ptr0, len0, strict_byte_size, ptr1, len1, htlc_output_index); + const ret = wasm.encode_output_produce_block_from_stake(ptr0, len0, ptr1, len1, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; - -/** - * Given an output source id as bytes, and an output index, together representing a utxo, - * this function returns the input that puts them together, as bytes. - * @param {Uint8Array} outpoint_source_id - * @param {number} output_index - * @returns {Uint8Array} - */ -module.exports.encode_input_for_utxo = function(outpoint_source_id, output_index) { - const ptr0 = passArray8ToWasm0(outpoint_source_id, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_utxo(ptr0, len0, output_index); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; +} +exports.encode_output_produce_block_from_stake = encode_output_produce_block_from_stake; /** - * Given a delegation id, an amount and a network type (mainnet, testnet, etc), this function - * creates an input that withdraws from a delegation. - * A nonce is needed because this spends from an account. The nonce must be in sequence for everything in that account. - * @param {string} delegation_id + * Given an amount, token ID (in address form) and network type (mainnet, testnet, etc), + * this function creates an output (as bytes) to burn a given amount of tokens * @param {Amount} amount - * @param {bigint} nonce + * @param {string} token_id * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_input_for_withdraw_from_delegation = function(delegation_id, amount, nonce, network) { - const ptr0 = passStringToWasm0(delegation_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; +function encode_output_token_burn(amount, token_id, network) { _assertClass(amount, Amount); - var ptr1 = amount.__destroy_into_raw(); - const ret = wasm.encode_input_for_withdraw_from_delegation(ptr0, len0, ptr1, nonce, network); + var ptr0 = amount.__destroy_into_raw(); + const ptr1 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.encode_output_token_burn(ptr0, ptr1, len1, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; +} +exports.encode_output_token_burn = encode_output_token_burn; /** - * Given the inputs, along each input's destination that can spend that input - * (e.g. If we are spending a UTXO in input number 1 and it is owned by address mtc1xxxx, then it is mtc1xxxx in element number 2 in the vector/list. - * for Account inputs that spend from a delegation it is the owning address of that delegation, - * and in the case of AccountCommand inputs which change a token it is the token's authority destination) - * and the outputs, estimate the transaction size. - * ScriptHash and ClassicMultisig destinations are not supported. - * @param {Uint8Array} inputs - * @param {string[]} input_utxos_destinations - * @param {Uint8Array} outputs - * @param {Network} network - * @returns {number} - */ -module.exports.estimate_transaction_size = function(inputs, input_utxos_destinations, outputs, network) { - const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passArrayJsValueToWasm0(input_utxos_destinations, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(outputs, wasm.__wbindgen_malloc); - const len2 = WASM_VECTOR_LEN; - const ret = wasm.estimate_transaction_size(ptr0, len0, ptr1, len1, ptr2, len2, network); - if (ret[2]) { - throw takeFromExternrefTable0(ret[1]); - } - return ret[0] >>> 0; -}; - -/** - * Given inputs as bytes, outputs as bytes, and flags settings, this function returns - * the transaction that contains them all, as bytes. - * @param {Uint8Array} inputs - * @param {Uint8Array} outputs - * @param {bigint} flags - * @returns {Uint8Array} - */ -module.exports.encode_transaction = function(inputs, outputs, flags) { - const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(outputs, wasm.__wbindgen_malloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_transaction(ptr0, len0, ptr1, len1, flags); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; - -/** - * Encode an input witness of the variant that contains no signature. - * @returns {Uint8Array} - */ -module.exports.encode_witness_no_signature = function() { - const ret = wasm.encode_witness_no_signature(); - var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v1; -}; - -/** - * Given a private key, inputs and an input number to sign, and the destination that owns that output (through the utxo), - * and a network type (mainnet, testnet, etc), this function returns a witness to be used in a signed transaction, as bytes. - * @param {SignatureHashType} sighashtype - * @param {Uint8Array} private_key_bytes - * @param {string} input_owner_destination - * @param {Uint8Array} transaction_bytes - * @param {Uint8Array} inputs - * @param {number} input_num + * Given a valid receiving address, token ID (in address form), a locking rule as bytes (available in this file), + * and a network type (mainnet, testnet, etc), this function creates an output of type + * LockThenTransfer with the parameters provided. + * @param {Amount} amount + * @param {string} address + * @param {string} token_id + * @param {Uint8Array} lock * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_witness = function(sighashtype, private_key_bytes, input_owner_destination, transaction_bytes, inputs, input_num, network) { - const ptr0 = passArray8ToWasm0(private_key_bytes, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(input_owner_destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_output_token_lock_then_transfer(amount, address, token_id, lock, network) { + _assertClass(amount, Amount); + var ptr0 = amount.__destroy_into_raw(); + const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(transaction_bytes, wasm.__wbindgen_malloc); + const ptr2 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len2 = WASM_VECTOR_LEN; - const ptr3 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); + const ptr3 = passArray8ToWasm0(lock, wasm.__wbindgen_malloc); const len3 = WASM_VECTOR_LEN; - const ret = wasm.encode_witness(sighashtype, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, input_num, network); + const ret = wasm.encode_output_token_lock_then_transfer(ptr0, ptr1, len1, ptr2, len2, ptr3, len3, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v5; -}; +} +exports.encode_output_token_lock_then_transfer = encode_output_token_lock_then_transfer; /** - * Given a private key, inputs and an input number to sign, and the destination that owns that output (through the utxo), - * and a network type (mainnet, testnet, etc), and an htlc secret this function returns a witness to be used in a signed transaction, as bytes. - * @param {SignatureHashType} sighashtype - * @param {Uint8Array} private_key_bytes - * @param {string} input_owner_destination - * @param {Uint8Array} transaction_bytes - * @param {Uint8Array} inputs - * @param {number} input_num - * @param {Uint8Array} secret + * Given a destination address, an amount, token ID (in address form) and a network type (mainnet, testnet, etc), this function + * creates an output of type Transfer for tokens, and returns it as bytes. + * @param {Amount} amount + * @param {string} address + * @param {string} token_id * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_witness_htlc_secret = function(sighashtype, private_key_bytes, input_owner_destination, transaction_bytes, inputs, input_num, secret, network) { - const ptr0 = passArray8ToWasm0(private_key_bytes, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(input_owner_destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_output_token_transfer(amount, address, token_id, network) { + _assertClass(amount, Amount); + var ptr0 = amount.__destroy_into_raw(); + const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(transaction_bytes, wasm.__wbindgen_malloc); + const ptr2 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len2 = WASM_VECTOR_LEN; - const ptr3 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); - const len3 = WASM_VECTOR_LEN; - const ptr4 = passArray8ToWasm0(secret, wasm.__wbindgen_malloc); - const len4 = WASM_VECTOR_LEN; - const ret = wasm.encode_witness_htlc_secret(sighashtype, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, input_num, ptr4, len4, network); + const ret = wasm.encode_output_token_transfer(ptr0, ptr1, len1, ptr2, len2, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v6; -}; + return v4; +} +exports.encode_output_token_transfer = encode_output_token_transfer; /** - * Given an arbitrary number of public keys as bytes, number of minimum required signatures, and a network type, this function returns - * the multisig challenge, as bytes. - * @param {Uint8Array} public_keys_bytes - * @param {number} min_required_signatures + * Given a destination address, an amount and a network type (mainnet, testnet, etc), this function + * creates an output of type Transfer, and returns it as bytes. + * @param {Amount} amount + * @param {string} address * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_multisig_challenge = function(public_keys_bytes, min_required_signatures, network) { - const ptr0 = passArray8ToWasm0(public_keys_bytes, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_multisig_challenge(ptr0, len0, min_required_signatures, network); +function encode_output_transfer(amount, address, network) { + _assertClass(amount, Amount); + var ptr0 = amount.__destroy_into_raw(); + const ptr1 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.encode_output_transfer(ptr0, ptr1, len1, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v3; +} +exports.encode_output_transfer = encode_output_transfer; /** - * Given a private key, inputs and an input number to sign, and multisig challenge, - * and a network type (mainnet, testnet, etc), this function returns a witness to be used in a signed transaction, as bytes. + * Return a PartiallySignedTransaction object as bytes. * - * `key_index` parameter is an index of a public key in the challenge, against which is the signature produces from private key is to be verified. - * `input_witness` parameter can be either empty or a result of previous calls to this function. - * @param {SignatureHashType} sighashtype - * @param {Uint8Array} private_key_bytes - * @param {number} key_index - * @param {Uint8Array} input_witness - * @param {Uint8Array} multisig_challenge - * @param {Uint8Array} transaction_bytes - * @param {Uint8Array} utxos - * @param {number} input_num + * `transaction` is an encoded `Transaction` (which can be produced via `encode_transaction`). + * + * `signatures`, `input_utxos`, `input_destinations` and `htlc_secrets` are encoded lists of + * optional objects of the corresponding type. To produce such a list, iterate over your + * original list of optional objects and then: + * 1) emit byte 0 if the current object is null; + * 2) otherwise emit byte 1 followed by the object in its encoded form. + * + * Each individual object in each of the lists corresponds to the transaction input with the same + * index and its meaning is as follows: + * 1) `signatures` - the signature for the input; + * 2) `input_utxos`- the utxo for the input (if it's utxo-based); + * 3) `input_destinations` - the destination (address) corresponding to the input; this determines + * the key(s) with which the input has to be signed. Note that for utxo-based inputs the + * corresponding destination can usually be extracted from the utxo itself (the exception + * being the `ProduceBlockFromStake` utxo, which doesn't contain the pool's decommission key). + * However, PartiallySignedTransaction requires that *all* input destinations are provided + * explicitly anyway. + * 4) `htlc_secrets` - if the input is an HTLC one and if the transaction is spending the HTLC, + * this should be the HTLC secret. Otherwise it should be null. + * + * The number of items in each list must be equal to the number of transaction inputs. + * + * `additional_info` has the same meaning as in `encode_witness`. + * @param {Uint8Array} transaction + * @param {Uint8Array} signatures + * @param {Uint8Array} input_utxos + * @param {Uint8Array} input_destinations + * @param {Uint8Array} htlc_secrets + * @param {TxAdditionalInfo} additional_info * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_witness_htlc_multisig = function(sighashtype, private_key_bytes, key_index, input_witness, multisig_challenge, transaction_bytes, utxos, input_num, network) { - const ptr0 = passArray8ToWasm0(private_key_bytes, wasm.__wbindgen_malloc); +function encode_partially_signed_transaction(transaction, signatures, input_utxos, input_destinations, htlc_secrets, additional_info, network) { + const ptr0 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(input_witness, wasm.__wbindgen_malloc); + const ptr1 = passArray8ToWasm0(signatures, wasm.__wbindgen_malloc); const len1 = WASM_VECTOR_LEN; - const ptr2 = passArray8ToWasm0(multisig_challenge, wasm.__wbindgen_malloc); + const ptr2 = passArray8ToWasm0(input_utxos, wasm.__wbindgen_malloc); const len2 = WASM_VECTOR_LEN; - const ptr3 = passArray8ToWasm0(transaction_bytes, wasm.__wbindgen_malloc); + const ptr3 = passArray8ToWasm0(input_destinations, wasm.__wbindgen_malloc); const len3 = WASM_VECTOR_LEN; - const ptr4 = passArray8ToWasm0(utxos, wasm.__wbindgen_malloc); + const ptr4 = passArray8ToWasm0(htlc_secrets, wasm.__wbindgen_malloc); const len4 = WASM_VECTOR_LEN; - const ret = wasm.encode_witness_htlc_multisig(sighashtype, ptr0, len0, key_index, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, input_num, network); + const ret = wasm.encode_partially_signed_transaction(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, additional_info, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v6; -}; +} +exports.encode_partially_signed_transaction = encode_partially_signed_transaction; /** * Given an unsigned transaction and signatures, this function returns a SignedTransaction object as bytes. - * @param {Uint8Array} transaction_bytes + * @param {Uint8Array} transaction * @param {Uint8Array} signatures * @returns {Uint8Array} */ -module.exports.encode_signed_transaction = function(transaction_bytes, signatures) { - const ptr0 = passArray8ToWasm0(transaction_bytes, wasm.__wbindgen_malloc); +function encode_signed_transaction(transaction, signatures) { + const ptr0 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; const ptr1 = passArray8ToWasm0(signatures, wasm.__wbindgen_malloc); const len1 = WASM_VECTOR_LEN; @@ -1306,575 +1084,1219 @@ module.exports.encode_signed_transaction = function(transaction_bytes, signature var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; +} +exports.encode_signed_transaction = encode_signed_transaction; /** - * Given a `Transaction` encoded in bytes (not a signed transaction, but a signed transaction is tolerated by ignoring the extra bytes, by choice) - * this function will return the transaction id. + * Return a `SignedTransactionIntent` object as bytes given the message and encoded signatures. * - * The second parameter, the boolean, is provided as means of asserting that the given bytes exactly match a `Transaction` object. - * When set to `true`, the bytes provided must exactly match a single `Transaction` object. - * When set to `false`, extra bytes can exist, but will be ignored. - * This is useful when the provided bytes are of a `SignedTransaction` instead of a `Transaction`, - * since the signatures are appended at the end of the `Transaction` object as a vector to create a `SignedTransaction`. - * It is recommended to use a strict `Transaction` size and set the second parameter to `true`. - * @param {Uint8Array} transaction_bytes - * @param {boolean} strict_byte_size - * @returns {string} - */ -module.exports.get_transaction_id = function(transaction_bytes, strict_byte_size) { - let deferred3_0; - let deferred3_1; - try { - const ptr0 = passArray8ToWasm0(transaction_bytes, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.get_transaction_id(ptr0, len0, strict_byte_size); - var ptr2 = ret[0]; - var len2 = ret[1]; - if (ret[3]) { - ptr2 = 0; len2 = 0; - throw takeFromExternrefTable0(ret[2]); - } - deferred3_0 = ptr2; - deferred3_1 = len2; - return getStringFromWasm0(ptr2, len2); - } finally { - wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); - } -}; - -/** - * 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. - * @param {Network} network - * @param {Amount} pledge_amount - * @param {Amount} pool_balance - * @returns {Amount} - */ -module.exports.effective_pool_balance = function(network, pledge_amount, pool_balance) { - _assertClass(pledge_amount, Amount); - var ptr0 = pledge_amount.__destroy_into_raw(); - _assertClass(pool_balance, Amount); - var ptr1 = pool_balance.__destroy_into_raw(); - const ret = wasm.effective_pool_balance(network, ptr0, ptr1); - if (ret[2]) { - throw takeFromExternrefTable0(ret[1]); - } - return Amount.__wrap(ret[0]); -}; - -/** - * Given a token_id, an amount of tokens to mint and nonce return an encoded mint tokens input - * @param {string} token_id - * @param {Amount} amount - * @param {bigint} nonce - * @param {Network} network + * Note: to produce a valid signed intent one is expected to sign the corresponding message by private keys + * corresponding to each input of the transaction. + * + * Parameters: + * `signed_message` - this must have been produced by `make_transaction_intent_message_to_sign`. + * `signatures` - this should be an array of Uint8Array, each of them representing an individual signature + * of `signed_message` produced by `sign_challenge` using the private key for the corresponding input destination + * of the transaction. The number of signatures must be equal to the number of inputs in the transaction. + * @param {Uint8Array} signed_message + * @param {Uint8Array[]} signatures * @returns {Uint8Array} */ -module.exports.encode_input_for_mint_tokens = function(token_id, amount, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_signed_transaction_intent(signed_message, signatures) { + const ptr0 = passArray8ToWasm0(signed_message, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - _assertClass(amount, Amount); - var ptr1 = amount.__destroy_into_raw(); - const ret = wasm.encode_input_for_mint_tokens(ptr0, len0, ptr1, nonce, network); + const ptr1 = passArrayJsValueToWasm0(signatures, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.encode_signed_transaction_intent(ptr0, len0, ptr1, len1); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v3; -}; +} +exports.encode_signed_transaction_intent = encode_signed_transaction_intent; /** - * Given a token_id and nonce return an encoded unmint tokens input - * @param {string} token_id - * @param {bigint} nonce + * This function returns the staking pool data needed to create a staking pool in an output as bytes, + * given its parameters and the network type (testnet, mainnet, etc). + * @param {Amount} value + * @param {string} staker + * @param {string} vrf_public_key + * @param {string} decommission_key + * @param {number} margin_ratio_per_thousand + * @param {Amount} cost_per_block * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_input_for_unmint_tokens = function(token_id, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_unmint_tokens(ptr0, len0, nonce, network); +function encode_stake_pool_data(value, staker, vrf_public_key, decommission_key, margin_ratio_per_thousand, cost_per_block, network) { + _assertClass(value, Amount); + var ptr0 = value.__destroy_into_raw(); + const ptr1 = passStringToWasm0(staker, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(vrf_public_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passStringToWasm0(decommission_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len3 = WASM_VECTOR_LEN; + _assertClass(cost_per_block, Amount); + var ptr4 = cost_per_block.__destroy_into_raw(); + const ret = wasm.encode_stake_pool_data(ptr0, ptr1, len1, ptr2, len2, ptr3, len3, margin_ratio_per_thousand, ptr4, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v6; +} +exports.encode_stake_pool_data = encode_stake_pool_data; /** - * Given a token_id and nonce return an encoded lock_token_supply input - * @param {string} token_id - * @param {bigint} nonce - * @param {Network} network + * Given inputs as bytes, outputs as bytes, and flags settings, this function returns + * the transaction that contains them all, as bytes. + * @param {Uint8Array} inputs + * @param {Uint8Array} outputs + * @param {bigint} flags * @returns {Uint8Array} */ -module.exports.encode_input_for_lock_token_supply = function(token_id, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_transaction(inputs, outputs, flags) { + const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_lock_token_supply(ptr0, len0, nonce, network); + const ptr1 = passArray8ToWasm0(outputs, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.encode_transaction(ptr0, len0, ptr1, len1, flags); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v3; +} +exports.encode_transaction = encode_transaction; /** - * Given a token_id, is token unfreezable and nonce return an encoded freeze token input - * @param {string} token_id - * @param {TokenUnfreezable} is_token_unfreezable - * @param {bigint} nonce + * Sign the specified input of the transaction and encode the signature as InputWitness. + * + * `input_utxos` must be formed as follows: for each transaction input, emit byte 0 if it's a non-UTXO input, + * otherwise emit 1 followed by the corresponding transaction output encoded via the appropriate "encode_output_" + * function. + * + * `additional_info` must contain the following: + * 1) for each `ProduceBlockFromStake` input of the transaction, the pool info for the pool referenced by that input; + * 2) for each `FillOrder` and `ConcludeOrder` input of the transaction, the order info for the order referenced by + * that input. + * Note: + * - It doesn't matter which input witness is currently being encoded. E.g. even if you are encoding a witness + * for some UTXO-based input but another input of the same transaction is `FillOrder`, you have to include the order + * info when encoding the witness for the UTXO-based input too. + * - After a certain hard fork, the produced signature will "commit" to the provided additional info, i.e. the info + * will become a part of what is being signed. So, passing invalid additional info will result in an invalid signature + * (with one small caveat: for `FillOrder` we only commit to order's initial balances and not the current ones; + * so if you only have `FillOrder` inputs, you can technically pass bogus values for the current balances and + * the resulting signature will still be valid; though it's better to avoid doing this). + * @param {SignatureHashType} sighashtype + * @param {Uint8Array} private_key + * @param {string} input_owner_destination + * @param {Uint8Array} transaction + * @param {Uint8Array} input_utxos + * @param {number} input_index + * @param {TxAdditionalInfo} additional_info + * @param {bigint} current_block_height * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_input_for_freeze_token = function(token_id, is_token_unfreezable, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_witness(sighashtype, private_key, input_owner_destination, transaction, input_utxos, input_index, additional_info, current_block_height, network) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_freeze_token(ptr0, len0, is_token_unfreezable, nonce, network); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); - } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; - -/** - * Given a token_id and nonce return an encoded unfreeze token input - * @param {string} token_id - * @param {bigint} nonce - * @param {Network} network - * @returns {Uint8Array} - */ -module.exports.encode_input_for_unfreeze_token = function(token_id, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_unfreeze_token(ptr0, len0, nonce, network); + const ptr1 = passStringToWasm0(input_owner_destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passArray8ToWasm0(input_utxos, wasm.__wbindgen_malloc); + const len3 = WASM_VECTOR_LEN; + const ret = wasm.encode_witness(sighashtype, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, input_index, additional_info, current_block_height, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v2; -}; + return v5; +} +exports.encode_witness = encode_witness; /** - * Given a token_id, new authority destination and nonce return an encoded change token authority input - * @param {string} token_id - * @param {string} new_authority - * @param {bigint} nonce + * Sign the specified HTLC input of the transaction and encode the signature as InputWitness. + * + * This function must be used for HTLC refunding when the refund address is a multisig one. + * + * `key_index` parameter is an index of the public key in the multisig challenge corresponding to + * the specified private key. + * `input_witness` parameter can be either empty or a result of previous calls to this function. + * + * `input_utxos` and `additional_info` have the same format and requirements as in `encode_witness`. + * @param {SignatureHashType} sighashtype + * @param {Uint8Array} private_key + * @param {number} key_index + * @param {Uint8Array} input_witness + * @param {Uint8Array} multisig_challenge + * @param {Uint8Array} transaction + * @param {Uint8Array} input_utxos + * @param {number} input_index + * @param {TxAdditionalInfo} additional_info + * @param {bigint} current_block_height * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_input_for_change_token_authority = function(token_id, new_authority, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_witness_htlc_refund_multisig(sighashtype, private_key, key_index, input_witness, multisig_challenge, transaction, input_utxos, input_index, additional_info, current_block_height, network) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(new_authority, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const ptr1 = passArray8ToWasm0(input_witness, wasm.__wbindgen_malloc); const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_change_token_authority(ptr0, len0, ptr1, len1, nonce, network); + const ptr2 = passArray8ToWasm0(multisig_challenge, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); + const len3 = WASM_VECTOR_LEN; + const ptr4 = passArray8ToWasm0(input_utxos, wasm.__wbindgen_malloc); + const len4 = WASM_VECTOR_LEN; + const ret = wasm.encode_witness_htlc_refund_multisig(sighashtype, ptr0, len0, key_index, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, input_index, additional_info, current_block_height, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; + return v6; +} +exports.encode_witness_htlc_refund_multisig = encode_witness_htlc_refund_multisig; /** - * Given a token_id, new metadata uri and nonce return an encoded change token metadata uri input - * @param {string} token_id - * @param {string} new_metadata_uri - * @param {bigint} nonce + * Sign the specified HTLC input of the transaction and encode the signature as InputWitness. + * + * This function must be used for HTLC refunding when the refund address is a single-sig one. + * + * `input_utxos` and `additional_info` have the same format and requirements as in `encode_witness`. + * @param {SignatureHashType} sighashtype + * @param {Uint8Array} private_key + * @param {string} input_owner_destination + * @param {Uint8Array} transaction + * @param {Uint8Array} input_utxos + * @param {number} input_index + * @param {TxAdditionalInfo} additional_info + * @param {bigint} current_block_height * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_input_for_change_token_metadata_uri = function(token_id, new_metadata_uri, nonce, network) { - const ptr0 = passStringToWasm0(token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_witness_htlc_refund_single_sig(sighashtype, private_key, input_owner_destination, transaction, input_utxos, input_index, additional_info, current_block_height, network) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(new_metadata_uri, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const ptr1 = passStringToWasm0(input_owner_destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len1 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_change_token_metadata_uri(ptr0, len0, ptr1, len1, nonce, network); + const ptr2 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passArray8ToWasm0(input_utxos, wasm.__wbindgen_malloc); + const len3 = WASM_VECTOR_LEN; + const ret = wasm.encode_witness_htlc_refund_single_sig(sighashtype, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, input_index, additional_info, current_block_height, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } - var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v3; -}; + return v5; +} +exports.encode_witness_htlc_refund_single_sig = encode_witness_htlc_refund_single_sig; /** - * Given ask and give amounts and a conclude key create output that creates an order. + * Sign the specified HTLC input of the transaction and encode the signature as InputWitness. * - * 'ask_token_id': the parameter represents a Token if it's Some and coins otherwise. - * 'give_token_id': the parameter represents a Token if it's Some and coins otherwise. - * @param {Amount} ask_amount - * @param {string | null | undefined} ask_token_id - * @param {Amount} give_amount - * @param {string | null | undefined} give_token_id - * @param {string} conclude_address + * This function must be used for HTLC spending. + * + * `input_utxos` and `additional_info` have the same format and requirements as in `encode_witness`. + * @param {SignatureHashType} sighashtype + * @param {Uint8Array} private_key + * @param {string} input_owner_destination + * @param {Uint8Array} transaction + * @param {Uint8Array} input_utxos + * @param {number} input_index + * @param {Uint8Array} secret + * @param {TxAdditionalInfo} additional_info + * @param {bigint} current_block_height * @param {Network} network * @returns {Uint8Array} */ -module.exports.encode_create_order_output = function(ask_amount, ask_token_id, give_amount, give_token_id, conclude_address, network) { - _assertClass(ask_amount, Amount); - var ptr0 = ask_amount.__destroy_into_raw(); - var ptr1 = isLikeNone(ask_token_id) ? 0 : passStringToWasm0(ask_token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len1 = WASM_VECTOR_LEN; - _assertClass(give_amount, Amount); - var ptr2 = give_amount.__destroy_into_raw(); - var ptr3 = isLikeNone(give_token_id) ? 0 : passStringToWasm0(give_token_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len3 = WASM_VECTOR_LEN; - const ptr4 = passStringToWasm0(conclude_address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_witness_htlc_spend(sighashtype, private_key, input_owner_destination, transaction, input_utxos, input_index, secret, additional_info, current_block_height, network) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(input_owner_destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passArray8ToWasm0(input_utxos, wasm.__wbindgen_malloc); + const len3 = WASM_VECTOR_LEN; + const ptr4 = passArray8ToWasm0(secret, wasm.__wbindgen_malloc); const len4 = WASM_VECTOR_LEN; - const ret = wasm.encode_create_order_output(ptr0, ptr1, len1, ptr2, ptr3, len3, ptr4, len4, network); + const ret = wasm.encode_witness_htlc_spend(sighashtype, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, input_index, ptr4, len4, additional_info, current_block_height, network); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v6 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v6; -}; +} +exports.encode_witness_htlc_spend = encode_witness_htlc_spend; /** - * Given an amount to fill an order (which is described in terms of ask currency) and a destination - * for result outputs create an input that fills the order. - * @param {string} order_id - * @param {Amount} fill_amount - * @param {string} destination - * @param {bigint} nonce - * @param {Network} network + * Encode an input witness of the variant that contains no signature. * @returns {Uint8Array} */ -module.exports.encode_input_for_fill_order = function(order_id, fill_amount, destination, nonce, network) { - const ptr0 = passStringToWasm0(order_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function encode_witness_no_signature() { + const ret = wasm.encode_witness_no_signature(); + var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v1; +} +exports.encode_witness_no_signature = encode_witness_no_signature; + +/** + * Given the inputs, along each input's destination that can spend that input + * (e.g. If we are spending a UTXO in input number 1 and it is owned by address mtc1xxxx, then it is mtc1xxxx in element number 2 in the vector/list. + * for Account inputs that spend from a delegation it is the owning address of that delegation, + * and in the case of AccountCommand inputs which change a token it is the token's authority destination) + * and the outputs, estimate the transaction size. + * ScriptHash and ClassicMultisig destinations are not supported. + * Also, the function assumes that the input UTXOs are not HTLC. + * @param {Uint8Array} inputs + * @param {string[]} input_utxos_destinations + * @param {Uint8Array} outputs + * @param {Network} network + * @returns {number} + */ +function estimate_transaction_size(inputs, input_utxos_destinations, outputs, network) { + const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - _assertClass(fill_amount, Amount); - var ptr1 = fill_amount.__destroy_into_raw(); - const ptr2 = passStringToWasm0(destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const ptr1 = passArrayJsValueToWasm0(input_utxos_destinations, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(outputs, wasm.__wbindgen_malloc); const len2 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_fill_order(ptr0, len0, ptr1, ptr2, len2, nonce, network); - if (ret[3]) { - throw takeFromExternrefTable0(ret[2]); + const ret = wasm.estimate_transaction_size(ptr0, len0, ptr1, len1, ptr2, len2, network); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); } - var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); - wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); - return v4; -}; + return ret[0] >>> 0; +} +exports.estimate_transaction_size = estimate_transaction_size; /** - * Given an order id create an input that concludes the order. - * @param {string} order_id - * @param {bigint} nonce - * @param {Network} network + * Return the extended public key from an extended private key + * @param {Uint8Array} private_key * @returns {Uint8Array} */ -module.exports.encode_input_for_conclude_order = function(order_id, nonce, network) { - const ptr0 = passStringToWasm0(order_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); +function extended_public_key_from_extended_private_key(private_key) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); const len0 = WASM_VECTOR_LEN; - const ret = wasm.encode_input_for_conclude_order(ptr0, len0, nonce, network); + const ret = wasm.extended_public_key_from_extended_private_key(ptr0, len0); if (ret[3]) { throw takeFromExternrefTable0(ret[2]); } var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); return v2; -}; +} +exports.extended_public_key_from_extended_private_key = extended_public_key_from_extended_private_key; /** - * Indicates whether a token can be frozen - * @enum {0 | 1} + * Given a signed transaction and input outpoint that spends an htlc utxo, extract a secret that is + * encoded in the corresponding input signature + * @param {Uint8Array} signed_tx + * @param {boolean} strict_byte_size + * @param {Uint8Array} htlc_outpoint_source_id + * @param {number} htlc_output_index + * @returns {Uint8Array} */ -module.exports.FreezableToken = Object.freeze({ - No: 0, "0": "No", - Yes: 1, "1": "Yes", -}); +function extract_htlc_secret(signed_tx, strict_byte_size, htlc_outpoint_source_id, htlc_output_index) { + const ptr0 = passArray8ToWasm0(signed_tx, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(htlc_outpoint_source_id, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.extract_htlc_secret(ptr0, len0, strict_byte_size, ptr1, len1, htlc_output_index); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; +} +exports.extract_htlc_secret = extract_htlc_secret; + /** - * The network, for which an operation to be done. Mainnet, testnet, etc. - * @enum {0 | 1 | 2 | 3} + * Returns the fee that needs to be paid by a transaction for issuing a new fungible token + * @param {bigint} _current_block_height + * @param {Network} network + * @returns {Amount} */ -module.exports.Network = Object.freeze({ - Mainnet: 0, "0": "Mainnet", - Testnet: 1, "1": "Testnet", - Regtest: 2, "2": "Regtest", - Signet: 3, "3": "Signet", -}); +function fungible_token_issuance_fee(_current_block_height, network) { + const ret = wasm.fungible_token_issuance_fee(_current_block_height, network); + return Amount.__wrap(ret); +} +exports.fungible_token_issuance_fee = fungible_token_issuance_fee; + /** - * The part of the transaction that will be committed in the signature. Similar to bitcoin's sighash. - * @enum {0 | 1 | 2 | 3} + * Returns the Delegation ID for the given inputs of a transaction + * @param {Uint8Array} inputs + * @param {Network} network + * @returns {string} */ -module.exports.SignatureHashType = Object.freeze({ - ALL: 0, "0": "ALL", - NONE: 1, "1": "NONE", - SINGLE: 2, "2": "SINGLE", - ANYONECANPAY: 3, "3": "ANYONECANPAY", -}); +function get_delegation_id(inputs, network) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.get_delegation_id(ptr0, len0, network); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.get_delegation_id = get_delegation_id; + /** - * A utxo can either come from a transaction or a block reward. This enum signifies that. - * @enum {0 | 1} + * Returns the Order ID for the given inputs of a transaction + * @param {Uint8Array} inputs + * @param {Network} network + * @returns {string} */ -module.exports.SourceId = Object.freeze({ - Transaction: 0, "0": "Transaction", - BlockReward: 1, "1": "BlockReward", -}); +function get_order_id(inputs, network) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.get_order_id(ptr0, len0, network); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.get_order_id = get_order_id; + /** - * Indicates whether a token can be unfrozen once frozen - * @enum {0 | 1} - */ -module.exports.TokenUnfreezable = Object.freeze({ - No: 0, "0": "No", - Yes: 1, "1": "Yes", -}); + * Returns the Pool ID for the given inputs of a transaction + * @param {Uint8Array} inputs + * @param {Network} network + * @returns {string} + */ +function get_pool_id(inputs, network) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.get_pool_id(ptr0, len0, network); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.get_pool_id = get_pool_id; + +/** + * Returns the Fungible/NFT Token ID for the given inputs of a transaction + * @param {Uint8Array} inputs + * @param {bigint} current_block_height + * @param {Network} network + * @returns {string} + */ +function get_token_id(inputs, current_block_height, network) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(inputs, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.get_token_id(ptr0, len0, current_block_height, network); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.get_token_id = get_token_id; + +/** + * Given a `Transaction` encoded in bytes (not a signed transaction, but a signed transaction is tolerated by ignoring the extra bytes, by choice) + * this function will return the transaction id. + * + * The second parameter, the boolean, is provided as means of asserting that the given bytes exactly match a `Transaction` object. + * When set to `true`, the bytes provided must exactly match a single `Transaction` object. + * When set to `false`, extra bytes can exist, but will be ignored. + * This is useful when the provided bytes are of a `SignedTransaction` instead of a `Transaction`, + * since the signatures are appended at the end of the `Transaction` object as a vector to create a `SignedTransaction`. + * It is recommended to use a strict `Transaction` size and set the second parameter to `true`. + * @param {Uint8Array} transaction + * @param {boolean} strict_byte_size + * @returns {string} + */ +function get_transaction_id(transaction, strict_byte_size) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.get_transaction_id(ptr0, len0, strict_byte_size); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.get_transaction_id = get_transaction_id; + +/** + * Verify a witness produced by one of the `encode_witness` functions. + * + * `input_owner_destination` must be specified if `witness` actually contains a signature + * (i.e. it's not InputWitness::NoSignature) and the input is not an HTLC one. Otherwise it must + * be null. + * @param {SignatureHashType} sighashtype + * @param {string | null | undefined} input_owner_destination + * @param {Uint8Array} witness + * @param {Uint8Array} transaction + * @param {Uint8Array} input_utxos + * @param {number} input_index + * @param {TxAdditionalInfo} additional_info + * @param {bigint} current_block_height + * @param {Network} network + */ +function internal_verify_witness(sighashtype, input_owner_destination, witness, transaction, input_utxos, input_index, additional_info, current_block_height, network) { + var ptr0 = isLikeNone(input_owner_destination) ? 0 : passStringToWasm0(input_owner_destination, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(witness, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(transaction, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passArray8ToWasm0(input_utxos, wasm.__wbindgen_malloc); + const len3 = WASM_VECTOR_LEN; + const ret = wasm.internal_verify_witness(sighashtype, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, input_index, additional_info, current_block_height, network); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } +} +exports.internal_verify_witness = internal_verify_witness; + +/** + * From an extended private key create a change private key for a given key index + * derivation path: current_derivation_path/1/key_index + * @param {Uint8Array} private_key + * @param {number} key_index + * @returns {Uint8Array} + */ +function make_change_address(private_key, key_index) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.make_change_address(ptr0, len0, key_index); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.make_change_address = make_change_address; + +/** + * From an extended public key create a change public key for a given key index + * derivation path: current_derivation_path/1/key_index + * @param {Uint8Array} extended_public_key + * @param {number} key_index + * @returns {Uint8Array} + */ +function make_change_address_public_key(extended_public_key, key_index) { + const ptr0 = passArray8ToWasm0(extended_public_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.make_change_address_public_key(ptr0, len0, key_index); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.make_change_address_public_key = make_change_address_public_key; + +/** + * Create the default account's extended private key for a given mnemonic + * derivation path: 44'/mintlayer_coin_type'/0' + * @param {string} mnemonic + * @param {Network} network + * @returns {Uint8Array} + */ +function make_default_account_privkey(mnemonic, network) { + const ptr0 = passStringToWasm0(mnemonic, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.make_default_account_privkey(ptr0, len0, network); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.make_default_account_privkey = make_default_account_privkey; + +/** + * Generates a new, random private key from entropy + * @returns {Uint8Array} + */ +function make_private_key() { + const ret = wasm.make_private_key(); + var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v1; +} +exports.make_private_key = make_private_key; + +/** + * From an extended private key create a receiving private key for a given key index + * derivation path: current_derivation_path/0/key_index + * @param {Uint8Array} private_key + * @param {number} key_index + * @returns {Uint8Array} + */ +function make_receiving_address(private_key, key_index) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.make_receiving_address(ptr0, len0, key_index); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.make_receiving_address = make_receiving_address; + +/** + * From an extended public key create a receiving public key for a given key index + * derivation path: current_derivation_path/0/key_index + * @param {Uint8Array} extended_public_key + * @param {number} key_index + * @returns {Uint8Array} + */ +function make_receiving_address_public_key(extended_public_key, key_index) { + const ptr0 = passArray8ToWasm0(extended_public_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.make_receiving_address_public_key(ptr0, len0, key_index); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.make_receiving_address_public_key = make_receiving_address_public_key; + +/** + * Return the message that has to be signed to produce a signed transaction intent. + * @param {string} intent + * @param {string} transaction_id + * @returns {Uint8Array} + */ +function make_transaction_intent_message_to_sign(intent, transaction_id) { + const ptr0 = passStringToWasm0(intent, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(transaction_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.make_transaction_intent_message_to_sign(ptr0, len0, ptr1, len1); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; +} +exports.make_transaction_intent_message_to_sign = make_transaction_intent_message_to_sign; + +/** + * Produce a multisig address given a multisig challenge. + * @param {Uint8Array} multisig_challenge + * @param {Network} network + * @returns {string} + */ +function multisig_challenge_to_address(multisig_challenge, network) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(multisig_challenge, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.multisig_challenge_to_address(ptr0, len0, network); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.multisig_challenge_to_address = multisig_challenge_to_address; + +/** + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for issuing a new NFT + * The current block height information is used in case a network upgrade changed the value. + * @param {bigint} current_block_height + * @param {Network} network + * @returns {Amount} + */ +function nft_issuance_fee(current_block_height, network) { + const ret = wasm.nft_issuance_fee(current_block_height, network); + return Amount.__wrap(ret); +} +exports.nft_issuance_fee = nft_issuance_fee; + +/** + * Given a public key (as bytes) and a network type (mainnet, testnet, etc), + * return the address public key hash from that public key as an address + * @param {Uint8Array} public_key + * @param {Network} network + * @returns {string} + */ +function pubkey_to_pubkeyhash_address(public_key, network) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(public_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.pubkey_to_pubkeyhash_address(ptr0, len0, network); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} +exports.pubkey_to_pubkeyhash_address = pubkey_to_pubkeyhash_address; + +/** + * Given a private key, as bytes, return the bytes of the corresponding public key + * @param {Uint8Array} private_key + * @returns {Uint8Array} + */ +function public_key_from_private_key(private_key) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.public_key_from_private_key(ptr0, len0); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; +} +exports.public_key_from_private_key = public_key_from_private_key; + +/** + * Given a message and a private key, create and sign a challenge with the given private key. + * This kind of signature is to be used when signing challenges. + * @param {Uint8Array} private_key + * @param {Uint8Array} message + * @returns {Uint8Array} + */ +function sign_challenge(private_key, message) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.sign_challenge(ptr0, len0, ptr1, len1); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; +} +exports.sign_challenge = sign_challenge; + +/** + * Given a message and a private key, sign the message with the given private key + * This kind of signature is to be used when signing spend requests, such as transaction + * input witness. + * @param {Uint8Array} private_key + * @param {Uint8Array} message + * @returns {Uint8Array} + */ +function sign_message_for_spending(private_key, message) { + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.sign_message_for_spending(ptr0, len0, ptr1, len1); + if (ret[3]) { + throw takeFromExternrefTable0(ret[2]); + } + var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v3; +} +exports.sign_message_for_spending = sign_message_for_spending; + +/** + * Given the current block height and a network type (mainnet, testnet, etc), + * this function returns the number of blocks, after which a pool that decommissioned, + * will have its funds unlocked and available for spending. + * The current block height information is used in case a network upgrade changed the value. + * @param {bigint} current_block_height + * @param {Network} network + * @returns {bigint} + */ +function staking_pool_spend_maturity_block_count(current_block_height, network) { + const ret = wasm.staking_pool_spend_maturity_block_count(current_block_height, network); + return BigInt.asUintN(64, ret); +} +exports.staking_pool_spend_maturity_block_count = staking_pool_spend_maturity_block_count; + +/** + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for changing the authority of a token + * The current block height information is used in case a network upgrade changed the value. + * @param {bigint} current_block_height + * @param {Network} network + * @returns {Amount} + */ +function token_change_authority_fee(current_block_height, network) { + const ret = wasm.token_change_authority_fee(current_block_height, network); + return Amount.__wrap(ret); +} +exports.token_change_authority_fee = token_change_authority_fee; + +/** + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for freezing/unfreezing a token + * The current block height information is used in case a network upgrade changed the value. + * @param {bigint} current_block_height + * @param {Network} network + * @returns {Amount} + */ +function token_freeze_fee(current_block_height, network) { + const ret = wasm.token_freeze_fee(current_block_height, network); + return Amount.__wrap(ret); +} +exports.token_freeze_fee = token_freeze_fee; + +/** + * Given the current block height and a network type (mainnet, testnet, etc), + * this will return the fee that needs to be paid by a transaction for changing the total supply of a token + * by either minting or unminting tokens + * The current block height information is used in case a network upgrade changed the value. + * @param {bigint} current_block_height + * @param {Network} network + * @returns {Amount} + */ +function token_supply_change_fee(current_block_height, network) { + const ret = wasm.token_supply_change_fee(current_block_height, network); + return Amount.__wrap(ret); +} +exports.token_supply_change_fee = token_supply_change_fee; + +/** + * Given a signed challenge, an address and a message, verify that + * the signature is produced by signing the message with the private key + * that derived the given public key. + * This function is used for verifying messages-related challenges. + * + * Note: for signatures that were created by `sign_challenge`, the provided address must be + * a 'pubkeyhash' address. + * + * Note: currently this function never returns `false` - it either returns `true` or fails with an error. + * @param {string} address + * @param {Network} network + * @param {Uint8Array} signed_challenge + * @param {Uint8Array} message + * @returns {boolean} + */ +function verify_challenge(address, network, signed_challenge, message) { + const ptr0 = passStringToWasm0(address, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(signed_challenge, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.verify_challenge(ptr0, len0, network, ptr1, len1, ptr2, len2); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return ret[0] !== 0; +} +exports.verify_challenge = verify_challenge; + /** - * The token supply of a specific token, set on issuance - * @enum {0 | 1 | 2} + * Given a digital signature, a public key and a message. Verify that + * the signature is produced by signing the message with the private key + * that derived the given public key. + * Note that this function is used for verifying messages related to spending, + * such as transaction input witness. + * @param {Uint8Array} public_key + * @param {Uint8Array} signature + * @param {Uint8Array} message + * @returns {boolean} */ -module.exports.TotalSupply = Object.freeze({ - /** - * Can be issued with no limit, but then can be locked to have a fixed supply. - */ - Lockable: 0, "0": "Lockable", - /** - * Unlimited supply, no limits except for numeric limits due to u128 - */ - Unlimited: 1, "1": "Unlimited", - /** - * On issuance, the total number of coins is fixed - */ - Fixed: 2, "2": "Fixed", -}); +function verify_signature_for_spending(public_key, signature, message) { + const ptr0 = passArray8ToWasm0(public_key, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(signature, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(message, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.verify_signature_for_spending(ptr0, len0, ptr1, len1, ptr2, len2); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return ret[0] !== 0; +} +exports.verify_signature_for_spending = verify_signature_for_spending; + +/** + * Verify a signed transaction intent. + * + * Parameters: + * `expected_signed_message` - the message that is supposed to be signed; this must have been + * produced by `make_transaction_intent_message_to_sign`. + * `encoded_signed_intent` - the signed transaction intent produced by `encode_signed_transaction_intent`. + * `input_destinations` - an array of addresses (strings), corresponding to the transaction's input destinations + * (note that this function treats "pub key" and "pub key hash" addresses interchangeably, so it's ok to pass + * one instead of the other). + * `network` - the network being used (needed to decode the addresses). + * @param {Uint8Array} expected_signed_message + * @param {Uint8Array} encoded_signed_intent + * @param {string[]} input_destinations + * @param {Network} network + */ +function verify_transaction_intent(expected_signed_message, encoded_signed_intent, input_destinations, network) { + const ptr0 = passArray8ToWasm0(expected_signed_message, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(encoded_signed_intent, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArrayJsValueToWasm0(input_destinations, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.verify_transaction_intent(ptr0, len0, ptr1, len1, ptr2, len2, network); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } +} +exports.verify_transaction_intent = verify_transaction_intent; + +function __wbg_get_imports() { + const import0 = { + __proto__: null, + __wbg___wbindgen_debug_string_0bc8482c6e3508ae: function(arg0, arg1) { + const ret = debugString(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, + __wbg___wbindgen_is_undefined_9e4d92534c42d778: function(arg0) { + const ret = arg0 === undefined; + return ret; + }, + __wbg___wbindgen_string_get_72fb696202c56729: function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, + __wbg___wbindgen_throw_be289d5034ed271b: function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }, + __wbg_getRandomValues_2a91986308c74a93: function() { return handleError(function (arg0, arg1) { + globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1)); + }, arguments); }, + __wbg_length_32ed9a279acd054c: function(arg0) { + const ret = arg0.length; + return ret; + }, + __wbg_parse_708461a1feddfb38: function() { return handleError(function (arg0, arg1) { + const ret = JSON.parse(getStringFromWasm0(arg0, arg1)); + return ret; + }, arguments); }, + __wbg_prototypesetcall_bdcdcc5842e4d77d: function(arg0, arg1, arg2) { + Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2); + }, + __wbg_stringify_8d1cc6ff383e8bae: function() { return handleError(function (arg0) { + const ret = JSON.stringify(arg0); + return ret; + }, arguments); }, + __wbindgen_cast_0000000000000001: function(arg0, arg1) { + // Cast intrinsic for `Ref(String) -> Externref`. + const ret = getStringFromWasm0(arg0, arg1); + return ret; + }, + __wbindgen_init_externref_table: function() { + const table = wasm.__wbindgen_externrefs; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + }, + }; + return { + __proto__: null, + "./wasm_wrappers_bg.js": import0, + }; +} const AmountFinalization = (typeof FinalizationRegistry === 'undefined') ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry(ptr => wasm.__wbg_amount_free(ptr >>> 0, 1)); -/** - * Amount type abstraction. The amount type is stored in a string - * since JavaScript number type cannot fit 128-bit integers. - * The amount is given as an integer in units of "atoms". - * Atoms are the smallest, indivisible amount of a coin or token. - */ -class Amount { - static __wrap(ptr) { - ptr = ptr >>> 0; - const obj = Object.create(Amount.prototype); - obj.__wbg_ptr = ptr; - AmountFinalization.register(obj, obj.__wbg_ptr, obj); - return obj; - } +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_externrefs.set(idx, obj); + return idx; +} - __destroy_into_raw() { - const ptr = this.__wbg_ptr; - this.__wbg_ptr = 0; - AmountFinalization.unregister(this); - return ptr; +function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); } +} - free() { - const ptr = this.__destroy_into_raw(); - wasm.__wbg_amount_free(ptr, 0); +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } } - /** - * @param {string} atoms - * @returns {Amount} - */ - static from_atoms(atoms) { - const ptr0 = passStringToWasm0(atoms, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.amount_from_atoms(ptr0, len0); - return Amount.__wrap(ret); + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } } - /** - * @returns {string} - */ - atoms() { - let deferred1_0; - let deferred1_1; + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches && builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. try { - const ptr = this.__destroy_into_raw(); - const ret = wasm.amount_atoms(ptr); - deferred1_0 = ret[0]; - deferred1_1 = ret[1]; - return getStringFromWasm0(ret[0], ret[1]); - } finally { - wasm.__wbindgen_free(deferred1_0, deferred1_1, 1); + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; } } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} + +let cachedDataViewMemory0 = null; +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; } -module.exports.Amount = Amount; - -module.exports.__wbg_buffer_609cc3eee51ed158 = function(arg0) { - const ret = arg0.buffer; - return ret; -}; - -module.exports.__wbg_call_672a4d21634d4a24 = function() { return handleError(function (arg0, arg1) { - const ret = arg0.call(arg1); - return ret; -}, arguments) }; - -module.exports.__wbg_call_7cccdd69e0791ae2 = function() { return handleError(function (arg0, arg1, arg2) { - const ret = arg0.call(arg1, arg2); - return ret; -}, arguments) }; - -module.exports.__wbg_crypto_ed58b8e10a292839 = function(arg0) { - const ret = arg0.crypto; - return ret; -}; - -module.exports.__wbg_getRandomValues_bcb4912f16000dc4 = function() { return handleError(function (arg0, arg1) { - arg0.getRandomValues(arg1); -}, arguments) }; - -module.exports.__wbg_msCrypto_0a36e2ec3a343d26 = function(arg0) { - const ret = arg0.msCrypto; - return ret; -}; - -module.exports.__wbg_new_a12002a7f91c75be = function(arg0) { - const ret = new Uint8Array(arg0); - return ret; -}; - -module.exports.__wbg_newnoargs_105ed471475aaf50 = function(arg0, arg1) { - const ret = new Function(getStringFromWasm0(arg0, arg1)); - return ret; -}; - -module.exports.__wbg_newwithbyteoffsetandlength_d97e637ebe145a9a = function(arg0, arg1, arg2) { - const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0); - return ret; -}; - -module.exports.__wbg_newwithlength_a381634e90c276d4 = function(arg0) { - const ret = new Uint8Array(arg0 >>> 0); - return ret; -}; - -module.exports.__wbg_node_02999533c4ea02e3 = function(arg0) { - const ret = arg0.node; - return ret; -}; - -module.exports.__wbg_process_5c1d670bc53614b8 = function(arg0) { - const ret = arg0.process; - return ret; -}; - -module.exports.__wbg_randomFillSync_ab2cfe79ebbf2740 = function() { return handleError(function (arg0, arg1) { - arg0.randomFillSync(arg1); -}, arguments) }; - -module.exports.__wbg_require_79b1e9274cde3c87 = function() { return handleError(function () { - const ret = module.require; - return ret; -}, arguments) }; - -module.exports.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) { - arg0.set(arg1, arg2 >>> 0); -}; - -module.exports.__wbg_static_accessor_GLOBAL_88a902d13a557d07 = function() { - const ret = typeof global === 'undefined' ? null : global; - return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); -}; - -module.exports.__wbg_static_accessor_GLOBAL_THIS_56578be7e9f832b0 = function() { - const ret = typeof globalThis === 'undefined' ? null : globalThis; - return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); -}; - -module.exports.__wbg_static_accessor_SELF_37c5d418e4bf5819 = function() { - const ret = typeof self === 'undefined' ? null : self; - return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); -}; - -module.exports.__wbg_static_accessor_WINDOW_5de37043a91a9c40 = function() { - const ret = typeof window === 'undefined' ? null : window; - return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); -}; - -module.exports.__wbg_stringify_f7ed6987935b4a24 = function() { return handleError(function (arg0) { - const ret = JSON.stringify(arg0); - return ret; -}, arguments) }; - -module.exports.__wbg_subarray_aa9065fa9dc5df96 = function(arg0, arg1, arg2) { - const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0); - return ret; -}; - -module.exports.__wbg_versions_c71aa1626a93e0a1 = function(arg0) { - const ret = arg0.versions; - return ret; -}; - -module.exports.__wbindgen_init_externref_table = function() { - const table = wasm.__wbindgen_export_2; - const offset = table.grow(4); - table.set(0, undefined); - table.set(offset + 0, undefined); - table.set(offset + 1, null); - table.set(offset + 2, true); - table.set(offset + 3, false); - ; -}; - -module.exports.__wbindgen_is_function = function(arg0) { - const ret = typeof(arg0) === 'function'; - return ret; -}; - -module.exports.__wbindgen_is_object = function(arg0) { - const val = arg0; - const ret = typeof(val) === 'object' && val !== null; - return ret; -}; - -module.exports.__wbindgen_is_string = function(arg0) { - const ret = typeof(arg0) === 'string'; - return ret; -}; - -module.exports.__wbindgen_is_undefined = function(arg0) { - const ret = arg0 === undefined; - return ret; -}; - -module.exports.__wbindgen_memory = function() { - const ret = wasm.memory; - return ret; -}; - -module.exports.__wbindgen_string_get = function(arg0, arg1) { - const obj = arg1; - const ret = typeof(obj) === 'string' ? obj : undefined; - var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len1 = WASM_VECTOR_LEN; - getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); - getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); -}; -module.exports.__wbindgen_string_new = function(arg0, arg1) { - const ret = getStringFromWasm0(arg0, arg1); - return ret; -}; +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return decodeText(ptr, len); +} -module.exports.__wbindgen_throw = function(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); -}; +let cachedUint8ArrayMemory0 = null; +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} -const path = require('path').join(__dirname, 'wasm_wrappers_bg.wasm'); -const bytes = require('fs').readFileSync(path); +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} -const wasmModule = new WebAssembly.Module(bytes); -const wasmInstance = new WebAssembly.Instance(wasmModule, imports); -wasm = wasmInstance.exports; -module.exports.__wasm = wasm; +function isLikeNone(x) { + return x === undefined || x === null; +} -wasm.__wbindgen_start(); +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8ArrayMemory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0; + for (let i = 0; i < array.length; i++) { + const add = addToExternrefTable0(array[i]); + getDataViewMemory0().setUint32(ptr + 4 * i, add, true); + } + WASM_VECTOR_LEN = array.length; + return ptr; +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_externrefs.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +function decodeText(ptr, len) { + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const cachedTextEncoder = new TextEncoder(); + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; + }; +} + +let WASM_VECTOR_LEN = 0; + +const wasmPath = `${__dirname}/wasm_wrappers_bg.wasm`; +const wasmBytes = require('fs').readFileSync(wasmPath); +const wasmModule = new WebAssembly.Module(wasmBytes); +const wasm = new WebAssembly.Instance(wasmModule, __wbg_get_imports()).exports; +wasm.__wbindgen_start(); diff --git a/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers_bg.wasm b/packages/sdk/tests/__mocks__/pkg-node/wasm_wrappers_bg.wasm index 343bfab6cc6d357f6bd6d87340f1ef9b2132c035..34a1e0cc037a1da8e20e259e58fda43abc43b2a3 100644 GIT binary patch delta 2108323 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