diff --git a/libs/awcp/LICENSE b/libs/awcp/LICENSE index 530738b..5e98689 100644 --- a/libs/awcp/LICENSE +++ b/libs/awcp/LICENSE @@ -1,6 +1,7 @@ ISC License -Copyright (c) 2022-2023 Peter Harpending +Copyright (c) 2022 Peter Harpending +Copyright (c) 2022-2023 Aeternity Foundation Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/libs/blakejs/LICENSE b/libs/blakejs/LICENSE index 8b66a9a..cf32e90 100644 --- a/libs/blakejs/LICENSE +++ b/libs/blakejs/LICENSE @@ -1,4 +1,5 @@ Copyright (c) 2022 Blakejs contributors +Copyright (c) 2023 Aeternity Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libs/parasite/LICENSE b/libs/parasite/LICENSE index 2e52b8d..5e98689 100644 --- a/libs/parasite/LICENSE +++ b/libs/parasite/LICENSE @@ -1,6 +1,7 @@ ISC License Copyright (c) 2022 Peter Harpending +Copyright (c) 2022-2023 Aeternity Foundation Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/libs/tweetnacl/README.md b/libs/tweetnacl/README.md index f31c876..b2c9fcd 100644 --- a/libs/tweetnacl/README.md +++ b/libs/tweetnacl/README.md @@ -2,6 +2,8 @@ This is a jex port of [TweetNaCl](https://github.com/dchest/tweetnacl-js) +Public Domain + ## building ``` diff --git a/libs/vdk_aecrypt/LICENSE b/libs/vdk_aecrypt/LICENSE new file mode 100644 index 0000000..d6429f8 --- /dev/null +++ b/libs/vdk_aecrypt/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2023 Aeternity Foundation + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/libs/vdk_aecrypt/README.md b/libs/vdk_aecrypt/README.md new file mode 100644 index 0000000..7d6addf --- /dev/null +++ b/libs/vdk_aecrypt/README.md @@ -0,0 +1,9 @@ +# `vdk_aecrypt` + +Aeternity-specific cryptography helper functions + +## building + +``` +jex install +``` diff --git a/libs/vdk_aecrypt/jex.eterms b/libs/vdk_aecrypt/jex.eterms index f7ce62f..0d9809e 100644 --- a/libs/vdk_aecrypt/jex.eterms +++ b/libs/vdk_aecrypt/jex.eterms @@ -1,6 +1,6 @@ {type, library}. {realm, local}. {name, vdk_aecrypt}. -{version, "0.1.0"}. +{version, "0.1.1"}. {deps, ["local-blakejs-1.2.1", "local-vdk_binary-0.1.0"]}. diff --git a/libs/vdk_aertext/LICENSE b/libs/vdk_aertext/LICENSE new file mode 100644 index 0000000..d6429f8 --- /dev/null +++ b/libs/vdk_aertext/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2023 Aeternity Foundation + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/libs/vdk_aertext/README.md b/libs/vdk_aertext/README.md new file mode 100644 index 0000000..473a1c4 --- /dev/null +++ b/libs/vdk_aertext/README.md @@ -0,0 +1,9 @@ +# `vdk_aertext`: AE Recovery Text + +Seed phrases bad. AE Recovery Text good + +## building + +``` +jex install +``` diff --git a/libs/vdk_aeser/LICENSE b/libs/vdk_aeser/LICENSE new file mode 100644 index 0000000..d6429f8 --- /dev/null +++ b/libs/vdk_aeser/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2023 Aeternity Foundation + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/libs/vdk_aeser/README.md b/libs/vdk_aeser/README.md new file mode 100644 index 0000000..0d54a56 --- /dev/null +++ b/libs/vdk_aeser/README.md @@ -0,0 +1,10 @@ +# `vdk_aeser` + +Serialization/deserialization routines for AE data. For instance, read a +`tx_...` string and figure out what the sender, recipient, payload, etc are + +## building + +``` +jex install +``` diff --git a/libs/vdk_base58/LICENSE b/libs/vdk_base58/LICENSE new file mode 100644 index 0000000..d6429f8 --- /dev/null +++ b/libs/vdk_base58/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2023 Aeternity Foundation + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/libs/vdk_base58/README.md b/libs/vdk_base58/README.md new file mode 100644 index 0000000..0ea40b2 --- /dev/null +++ b/libs/vdk_base58/README.md @@ -0,0 +1,9 @@ +# `vdk_base58` + +Base58 encode/decode routines. See + +## building + +``` +jex install +``` diff --git a/libs/vdk_base58/notes b/libs/vdk_base58/notes deleted file mode 100644 index 97c0e0c..0000000 --- a/libs/vdk_base58/notes +++ /dev/null @@ -1,24 +0,0 @@ -done: -- base64/base58 encoding/decoding -- rlp - -today: -- pull apart data - -tomorrow: -- basic easy serialization/deserialization -- serialize/deserialize examples -- (maybe) pull in awcp/sidekick -- sidekick: sign/propagate and sign/noprop - -later: - -- general node querying with parasite (think about autogeneration) -- simple aetto/ae/etc unit converter -- ghetto sophia ide -- general "send money to someone" page - -GUI: - -- simple testnet explorer -- contract ide diff --git a/libs/vdk_base58/scratch/anth.ts b/libs/vdk_base58/scratch/anth.ts deleted file mode 100644 index 6117067..0000000 --- a/libs/vdk_base58/scratch/anth.ts +++ /dev/null @@ -1,403 +0,0 @@ -/** - * Node API constructor/deconstructor - * - * This is similar to serialization/deserialization, but not quite the same - * thing. It converts back and forth between different forms of - * "api-serialized" data. - * - * References: - * 1. https://github.com/aeternity/protocol/blob/master/serializations.md - * 2. https://github.com/aeternity/protocol/blob/master/node/api/api_encoding.md - * - * ## General type rules - * - * ``` - * ERLANG TYPE | JS TYPE - * ------------------------------- - * integer | bigint - * list | Array - * binary | Uint8Array - * ``` - * - * # Example - * - * We start with the string `tx_+FgMAaEByWN+RgDnqzvC5n/GQOgjdkRE9DBV2l1VeKSaN1r6GNyhAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAACYdoYWluYW5hA7ZC1w==`. - * - * We can tell by the `tx_` prefix that this represents transaction data of - * some sort. But the rest of the data is totally opaque. The task of this - * module is to "humanize" that `tx_...` string and show what data is contained - * in the rest of it. - * - * The remainder of the string is a base64-encoded bytestring - * - * ```erlang - * 3> io:format("~tw~n", [base64:decode(<<"+FgMAaEByWN+RgDnqzvC5n/GQOgjdkRE9DBV2l1VeKSaN1r6GNyhAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAACYdoYWluYW5hA7ZC1w==">>)]). - * <<248,88,12,1,161,1,201,99,126,70,0,231,171,59,194,230,127,198,64,232,35,118,68,68,244,48,85,218,93,85,120,164,154,55,90,250,24,220,161,1,123,102,230,195,5,7,8,54,228,233,121,32,82,61,195,234,89,203,191,216,108,88,186,7,3,234,139,205,10,184,167,108,10,134,15,38,245,97,200,0,0,9,135,104,97,105,110,97,110,97,3,182,66,215>> - * ``` - * - * That bytestring contains data encoded using Ethereum's RLP codec. Luckily, I - * wrote an RLP decoder. RLP has two types of data: binaries, and - * arbitrary-depth (possibly empty) lists of binaries. - * - * ```erlang - * -type decoded_data() :: binary() | [decoded_data()]. - * - * -spec decode(RLP) -> {Data, Rest} - * when RLP :: binary(), - * Data :: decoded_data(), - * Rest :: binary(). - * ``` - * - * ```erlang - * 2> rlp:decode(base64:decode(<<"+FgMAaEByWN+RgDnqzvC5n/GQOgjdkRE9DBV2l1VeKSaN1r6GNyhAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAACYdoYWluYW5hA7ZC1w==">>)). - * {[<<"\f">>, - * <<1>>, - * <<1,201,99,126,70,0,231,171,59,194,230,127,198,64,232,35, - * 118,68,68,244,48,85,218,93,85,...>>, - * <<1,123,102,230,195,5,7,8,54,228,233,121,32,82,61,195,234, - * 89,203,191,216,108,88,186,...>>, - * <<"\n">>, - * <<15,38,245,97,200,0>>, - * <<0>>, - * <<"\t">>,<<"hainana">>], - * <<3,182,66,215>>} - * ``` - * - * As expected, we get back the return tuple `{Data, Rest}`. `Rest` is the double-sha256 of the beginning - * - * ```erlang - * 3> X = base64:decode(<<"+FgMAaEByWN+RgDnqzvC5n/GQOgjdkRE9DBV2l1VeKSaN1r6GNyhAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAACYdoYWluYW5hA7ZC1w==">>). - * <<248,88,12,1,161,1,201,99,126,70,0,231,171,59,194,230, - * 127,198,64,232,35,118,68,68,244,48,85,218,93,...>> - * 4> SizeX = byte_size(X). - * 94 - * 6> <> = X. - * <<248,88,12,1,161,1,201,99,126,70,0,231,171,59,194,230, - * 127,198,64,232,35,118,68,68,244,48,85,218,93,...>> - * 10> <> = crypto:hash(sha256, crypto:hash(sha256, RLPEncodedData)). - * <<3,182,66,215,195,99,112,99,25,7,84,31,151,188,149,81, - * 189,184,82,207,164,68,128,43,11,174,236,59,77,...>> - * 11> Hash. - * <<3,182,66,215>> - * 12> Check. - * <<3,182,66,215>> - * ``` - * - * What we're really interested in is `Data` - * - * ```erlang - * 14> {Data, _} = rlp:decode(X). - * {[<<"\f">>, - * <<1>>, - * <<1,201,99,126,70,0,231,171,59,194,230,127,198,64,232,35, - * 118,68,68,244,48,85,218,93,85,...>>, - * <<1,123,102,230,195,5,7,8,54,228,233,121,32,82,61,195,234, - * 89,203,191,216,108,88,186,...>>, - * <<"\n">>, - * <<15,38,245,97,200,0>>, - * <<0>>, - * <<"\t">>,<<"hainana">>], - * <<3,182,66,215>>} - * ``` - * - * `Data` is a list. The first field `<<"\f">>` is meant to be an integer which - * tells us what type of data this is. - * - * ```erlang - * 16> $\f. - * 12 - * ``` - * - * If we look at our table - * (https://github.com/aeternity/protocol/blob/master/serializations.md#table-of-object-tags), - * we see that a value of `12` is a spend transaction. - * - * The second field `<<1>>` tells us the "version" of the field orderings, - * which we can ignore for now. - * - * The remaining fields are the fields of a spend transaction (https://github.com/aeternity/protocol/blob/master/serializations.md#spend-transaction) - * - * ```erlang - * [ :: id() % <<1,201,99,126,...> "=" "ak_2XhCkjzTwcq1coXSSzHJoMZkUzTwnjH88zmPGkkowUsFNTo9UE" - * , :: id() % <<1,123,102,230,...> "=" "ak_wM8yFU8eSETXU7VSN48HMDmevGoCMiuveQZgkPuRn1nTiRqyv" - * , :: int() % <<"\n">> "=" 10 - * , :: int() % <<15,38,245,97,200,0>> "=" 16_660_000_000_000 - * , :: int() % <<0>> "=" 0 - * , :: int() % <<"\t">> "=" 9 - * , :: binary() % <<"hainana">> "=" "hainana" - * ] - * ``` - * - * Our task here is to be able to pull apart the "tx_..." string into its fields. - * - * Converting the binaries to integers is pretty trivial. The only mildly - * annoying thing is the `id` type. - * - * `id`s have two fields: a single-byte prefix which says which type of ID it - * is. In this case, both `id`s have a prefix of `1`, which means they are both - * normal accounts (hence the `ak_` prefix on the "api-encoded" id). The other - * options are oracles (prefix `4`/`ok_`), contracts (prefix `5`/`ct_`), or - * names (prefix `2`/`nm_`) - * - * To "api-encode" the name, we first pick the appropriate prefix based on the - * first byte (in this case `1 -> "ak_"). The remaining 32 bytes are then - * double-SHA'd to get the 4-byte check suffix - * - * ```erlang - * 30> SenderBytes = lists:nth(3, Data). - * <<1,201,99,126,70,0,231,171,59,194,230,127,198,64,232,35, - * 118,68,68,244,48,85,218,93,85,120,164,154,55,...>> - * 31> <<1, SenderAddrBytes/binary>> = SenderBytes. - * <<1,201,99,126,70,0,231,171,59,194,230,127,198,64,232,35, - * 118,68,68,244,48,85,218,93,85,120,164,154,55,...>> - * 32> DoubleSha = fun(Bytes) -> <> = crypto:hash(sha256, crypto:hash(sha256, Bytes)), Foo end. - * #Fun - * 33> "ak_" ++ b58:enc(<>). - * "ak_2XhCkjzTwcq1coXSSzHJoMZkUzTwnjH88zmPGkkowUsFNTo9UE" - * 34> RecipBytes = lists:nth(4, Data). - * <<1,123,102,230,195,5,7,8,54,228,233,121,32,82,61,195,234, - * 89,203,191,216,108,88,186,7,3,234,139,205,...>> - * 35> <<1, RecipAddrBytes/binary>> = RecipBytes. - * <<1,123,102,230,195,5,7,8,54,228,233,121,32,82,61,195,234, - * 89,203,191,216,108,88,186,7,3,234,139,205,...>> - * 36> "ak_" ++ b58:enc(<>). - * "ak_wM8yFU8eSETXU7VSN48HMDmevGoCMiuveQZgkPuRn1nTiRqyv" - * ``` - * - * ```js - * > anth.deconstruct("tx_+FgMAaEByWN+RgDnqzvC5n/GQOgjdkRE9DBV2l1VeKSaN1r6GNyhAXtm5sMFBwg25Ol5IFI9w+pZy7/YbFi6BwPqi80KuKdsCoYPJvVhyAAACYdoYWluYW5hA7ZC1w==") - * {tag : 'SpendTx', - * version : 1n, - * fields : {sender : "ak_2XhCkjzTwcq1coXSSzHJoMZkUzTwnjH88zmPGkkowUsFNTo9UE", - * recipient : "ak_wM8yFU8eSETXU7VSN48HMDmevGoCMiuveQZgkPuRn1nTiRqyv", - * amount : 10n, - * fee : 16660000000000n, - * ttl : 0n, - * nonce : 9n, - * payload : Uint8Array([104, 97, 105, 110, 97, 110, 97])}} - * ``` - * - * @module - */ - -export { - // types - tx_str, - deconstructed_tx, - // functions - deconstruct_tx -}; - -import * as b64 from './b64.js' -import * as bin from './bin.js' -import * as rlp from './rlp.js' - - -/** - * Alias type for a `tx_...` string - */ -type tx_str = string; - -/** - * Alias type for a `sg_...` string - */ -type sg_str = string; - -/** - * types of decoded tx we currently support - * @internal - */ -type tx_type_str - = 'SignedTx' - | 'SpendTx' - | 'ContractCreateTx' - | 'ContractCallTx'; - - -/** - * Results of deconstruct_tx - */ -type deconstructed_tx - = {type : 'SignedTx', - version : bigint, - fields : fields_SignedTx} - | {type : 'SpendTx', - version : bigint, - fields : fields_SpendTx} - | {type : 'ContractCreateTx', - version : bigint, - fields : fields_ContractCreateTx} - | {type : 'ContractCallTx' - version : bigint, - fields : fields_ContractCallTx}; - -/** - * Convenient type alias - * - * @internal - */ -type rlpdata = rlp.decoded_data; - - -/** - * Fields types - */ -type fields - = fields_SignedTx - | fields_SpendTx - | fields_ContractCreateTx - | fields_ContractCallTx; - -type fields_SignedTx - = {signatures : Array, - transaction : tx_str}; - -type fields_SpendTx - = {sender : string, - recipient : string, - amount : bigint, - fee : bigint, - ttl : bigint, - nonce : bigint, - payload : Uint8Array}; - -/** - * Deconstruct a Tx - */ -function -deconstruct_tx - (tx_str: tx_str) - : deconstructed_tx -{ - let b64_str : string = tx_str.slice(3); // tx_[...] -> [...] - let tx_rlp_encoded : Uint8Array = b64.decode(b64_str); // [...] -> bytes - let tx_data : Array = shasha_rlp_decode_list(tx_rlp_encoded); // decode data and check the double-sha thing - let tx_type : bigint = bin.bytes_to_bigint(tx_data[0]); // get a bigint - let tts : tx_type_str = tx_type_str(tx_type); - let tx_version : bigint = bin.bytes_to_bigint(tx_data[1]); - let tx_fields : fields = deconstruct_fields(tts, tx_version, tx_data.slice(2)); - return {type : tts, - version : tx_version, - fields : tx_fields}; -} - - -/** - * Data that's "api-encoded" goes through the following stages: - * - * 1. data structure -> rlp decode data (arbitrary-depth [possibly 0] list of bytestrings) - * 2. rlp decode data -> bytestring - * 3. bytestring -> <> - * 4. HashedBytestring -> base64/base58 string encoding - * 5. Add string prefix - * - * This function undoes step 3 and step 2, returns back the rlp decode data - * - * FIXME: Does not check double-sha (yet); need to figure out way to handle hash failures - * FIXME: No good way to handle failure cases - * - * @internal - */ -function -shasha_rlp_decode_list - (hashed_bs : Uint8Array) - : Array -{ - let len = hashed_bs.length; - let bytes = hashed_bs.slice(0, len - 4); - let {decoded_data} = rlp.decode(bytes); - return (decoded_data as Array); -} - - - -/** - * Convert an object tag that's a type of transaction to the type string - * - * See: https://github.com/aeternity/protocol/blob/master/serializations.md#table-of-object-tags - * - * @internal - */ -function -tx_type_str - (tx_type_int : bigint) - : tx_type_str -{ - switch (tx_type_int) - { - case 11n: return 'SignedTx'; - case 12n: return 'SpendTx'; - case 42n: return 'ContractCreateTx'; - case 43n: return 'ContractCallTx'; - default: throw new Error('invalid transaction type: ' + tx_type_int); - } -} - - - -/** - * Given an array of data decoded from RLP, convert it to the fields, as - * appropriate as given by the tx type string and the version - */ -function -deconstruct_fields - (tx_type_str : tx_type_str, - tx_version : bigint, - tx_rawfields : Array) - : fields - { - switch (tx_type_str) - { - // case 'SignedTx' : return deconstruct_fields_SignedTx(tx_rawfields); - case 'SpendTx' : return deconstruct_fields_SpendTx(tx_rawfields); - // case 'ContractCreateTx' : return deconstruct_fields_ContractCreateTx(tx_rawfields); - // case 'ContractCallTx' : return deconstruct_fields_ContractCallTx(tx_rawfields); - default : throw new Error('invalid tx type str: ' + tx_type_str); - } - } - - -// TODO: do all this in Erlang - function - deconstruct_fields_SpendTx - (fields: Array) - : fields_SpendTx -{ - let sender_bytes = fields[0]; - let recip_bytes = fields[1]; - let amount_bytes = fields[2]; - let fee_bytes = fields[3]; - let ttl_bytes = fields[4]; - let nonce_bytes = fields[5]; - let payload_bytes = fields[6]; - return {sender : encode_id(sender_bytes), - recipient : encode_id(sender_bytes), - amount : bin.bytes_to_bigint(amount_bytes), - fee : bin.bytes_to_bigint(fee_bytes), - ttl : bin.bytes_to_bigint(ttl_bytes), - nonce : bin.bytes_to_bigint(nonce_bytes), - payload : bin.bytes_to_bigint(payload_bytes)}; -} - - -/** - * Convert a binary account/name/etc binary id into the appropriate type of string - * - * @internal - */ -function -encode_id - (id: Uint8Array) - : string -{ - throw new Error('nyi'); -} - -/* -FIXME: -1. work out all this in Erlang to clear conceptual goo -2. think about how i want type safety etc to work -3. think about a language to assert that the data has the correct shape to it -4. get some examples working in Erlang -5. convert erlang code back to ts -*/ diff --git a/libs/vdk_base58/scratch/bin.ts b/libs/vdk_base58/scratch/bin.ts deleted file mode 100644 index 47ad66a..0000000 --- a/libs/vdk_base58/scratch/bin.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Concatenate two bitstrings - */ -function -bits_concat - (bits1 : bits, - bits2 : bits) - : bits -{ - let result_bit_length : number = bits1.bit_length + bits2.bit_length; - let bytes1 : Uint8Array = bits1.bytes; - let bytes2 : Uint8Array = bits2.bytes; - // using zeros here because of our xor trick in a minute - let result_bits : bits = bits_zeros(result_bit_length); - let result_bytes : Uint8Array = result_bits.bytes; - - // alright so - // we can start by copying the first bytes into result bytes - for (let bytes1_idx0 = 0; - bytes1_idx0 < bytes1.length; - bytes1_idx0++) - { - result_bytes[bytes1_idx0] = bytes1[bytes1_idx0]; - } - - // next - // we need to calculate the left-shift offset - // this will be 8 - (bytes1.bit_length % 8) - let num_trailing_zeros_in_first_array : number = 8 - (bits1.bit_length % 8); - // so - // bytes1: ABCD_EF00 - // bytes2: GH12_3000 - // result: ABCD_EFGH 1230_0000 - // ah ok, so we need to for each byte in the second array - // take the first however many bits, xor it with the existing byte - // then take the last however many bits and place them into the next byte - // this is super confusing but - // ABCD_EF00 - // GH12_3456 - // operation: - // ABCD_EF00 - // xor 0000_00GH - // = ABCD_EFGH 1234_5600 - // - // then on the next iteration - // 1234_5600 - // abcd_efgh - // -> - // 1234_56ab cdef_gh00 - // - // ah so there's a pattern - // however many trailing 0s there are in the first array - // say there's 2 - // we take the first 2 bits of the upcoming byte - // xor that against the current byte - // take the last 6 bits of the upcoming byte - // set the next byte to that - // - // have to think about edge behavior - // this is ripe for off-by-1 errors - // but i think the general idea is right - // - // so we start the iteration - // on the last byte of the first array - let last_byte_of_first_array_idx0 : number = bytes1.length - 1; - // and we end - // on the second-to-last-byte of the result array - let second_to_last_byte_of_result_array_idx0 : number = result_bytes.length - 2; - // the reason we do that is because we're doing this is because we are - // going along, xoring against the current byte and then setting the next - // byte - // - // ok so - for (let this_result_byte_idx0 = last_byte_of_first_array_idx0; - this_result_byte_idx0 <= second_to_last_byte_of_result_array_idx0; - this_result_byte_idx0++) - { - let this_result_byte : number = result_bytes[this_result_byte_idx0]; - - // ok here we need to fish out the relevant byte of the second array - // gaaah - // so this will be 0 at the start of the loop - let relevant_byte_of_second_array_idx0 : number = this_result_byte_idx0 - last_byte_of_first_array_idx0; - let relevant_byte_of_second_array : number = bytes2[relevant_byte_of_second_array_idx0]; - - // ok so let's fish out the leading digits - // the number of leading digits is the number of trailing 0s in the first array - let num_leading_digits : number = num_trailing_zeros_in_first_array; - let num_trailing_digits : number = 8 - num_leading_digits; - - // suppose there are 2 leading digits and 6 trailing digits - // ABCD_EFGH - // leading digits are - // ABCD_EFGH >> 6 = 0000_00AB - // trailing digits are - // (ABCD_EFGH << 2) % 255 = CDEF_GH00 - let leading_digits : number = relevant_byte_of_second_array >> num_trailing_digits; - let trailing_digits : number = (relevant_byte_of_second_array << num_leading_digits) % 255; - - // xor the current byte against the leading digits - let new_this_result_byte : number = this_result_byte ^ leading_digits; - result_bytes[this_result_byte_idx0] = new_this_result_byte; - - // set the next byte to the trailing digits - result_bytes[this_result_byte_idx0 + 1] = trailing_digits; - } - - // i think we're done - return {bit_length : result_bit_length, - bytes : result_bytes}; -} - diff --git a/libs/vdk_base58/scratch/scratch.txt b/libs/vdk_base58/scratch/scratch.txt deleted file mode 100644 index 9213abc..0000000 --- a/libs/vdk_base58/scratch/scratch.txt +++ /dev/null @@ -1,159 +0,0 @@ - -const OTAG_SIGNED_TX = 11n; -const OTAG_SPEND_TX = 12n; -const OTAG_CONTRACT_CREATE_TX = 42n; -const OTAG_CONTRACT_CALL_TX = 43n; - -type otag = 11n | 12n | 42n | 43n; - -const IDTAG_ACCOUNT = 1n; -const IDTAG_NAME = 2n; -const IDTAG_CONTRACT = 5n; - -type idtag = 1n | 2n | 5n; - - -type id = - {tag : idtag, - hash : Uint8Array}; - -type SignedTx = - {signatures : Array, - transaction : Uint8Array}; - -type SpendTx = - {sender : id, - recipient : id, - amount : bigint, - fee : bigint, - ttl : bigint, - nonce : bigint, - payload : Uint8Array}; - -type ContractCreateTx = - {owner : id, - nonce : bigint, - code : Uint8Array, - ct_version : bigint, - fee : bigint, - ttl : bigint, - deposit : bigint, - amount : bigint, - gas : bigint, - gas_price : bigint, - call_data : Uint8Array}; - -type ContractCallTx = - {caller : id, - nonce : bigint, - contract : id, - abi_version : bigint, - fee : bigint, - ttl : bigint, - amount : bigint, - gas : bigint, - gas_price : bigint, - call_data : Uint8Array}; - -type tx = SignedTx | SpendTx | ContractCreateTx | ContractCallTx; - -type decoded_tx = - {tag : otag, - version : Uint8Array, - tx : tx}; - -/** - * Decode a `tx_Base64` string - */ -function -decode_tx(tx_str : string): decoded_tx { - let base64_stuff : string = tx_str.slice(3); // tx_[...] -> [...] - let stuff : Uint8Array = b64.decode(base64_stuff); // <> - let rlp_stuff : Uint8Array = stuff.slice(0, stuff.length - 4); // <> - let decoded_datas : Array = rlp.decode(rlp_stuff).decoded_data as Array; // decoded_data : list(rlp.decoded_data() :: binary() | list(decoded_data())) - // tag, vsn - let tag_bytes : Uint8Array = decoded_datas[0] as Uint8Array; // [tag, vsn, fields] -> tag - let tag : bigint = bytes_to_bigint(tag_bytes); // <> = TagBytes - let vsn : Uint8Array = decoded_datas[1] as Uint8Array; - // tx fields - let tx_fields : Array = decoded_datas.slice(2); - let tx : tx = decode_fields(tag, tx_fields); - return {tag: tag as otag, version: vsn, tx: tx}; -} - -/** - * Decode a transaction given the raw fields - * - * @internal - */ -function -decode_fields(tag: bigint, fields: Array): tx { - switch (tag) { - case 11n: return decode_fields_SignedTx(fields); - case 12n: return decode_fields_SpendTx(fields); - case 42n: return decode_fields_ContractCreateTx(fields); - case 43n: return decode_fields_ContractCallTx(fields); - default : throw new Error("invalid object tag: " + tag); - } - console.log('fields: ', fields); - throw new Error("nyi"); -} - - -/** - * Decode a SignedTx - * - * @internal - */ -function -decode_fields_SignedTx(fields: Array): SignedTx { - throw new Error('nyi'); -} - - -/** - * Decode a SpendTx - * - * @internal - */ -function -decode_fields_SpendTx(fields: Array): SpendTx { - // [ :: id(), - // :: id(), - // :: int(), - // :: int(), - // :: int(), - // :: int(), - // :: binary()] - let sender : id = decode_id(fields[0] as Uint8Array); - let recipient : id = decode_id(fields[1] as Uint8Array); - let amount : bigint = bytes_to_bigint(fields[2] as Uint8Array); - let fee : bigint = bytes_to_bigint(fields[3] as Uint8Array); - let ttl : bigint = bytes_to_bigint(fields[4] as Uint8Array); - let nonce : bigint = bytes_to_bigint(fields[5] as Uint8Array); - let payload : Uint8Array = fields[6] as Uint8Array; - return {sender : sender, - recipient : recipient, - amount : amount, - fee : fee, - ttl : ttl, - nonce : nonce, - payload : payload}; - -} - -function -decode_fields_ContractCreateTx(fields: Array): ContractCreateTx { - throw new Error('nyi'); -} - -function -decode_fields_ContractCallTx(fields: Array): ContractCallTx { - throw new Error('nyi'); -} - -function -decode_id(id: Uint8Array): id { - let idtag : idtag = BigInt(id[0]) as idtag; - return {tag: idtag, hash: id.slice(1)}; -} diff --git a/libs/vdk_base58/scratch/sp.ts b/libs/vdk_base58/scratch/sp.ts deleted file mode 100644 index 8448945..0000000 --- a/libs/vdk_base58/scratch/sp.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Vanillae Seed Phrase Library - * - * Refs: - * 1. BIP 39: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki - * - * @module - */ - - -/** - * Get a given number of seed bits. - * - * `how_many` must be a multiple of 33. - * - * Ref: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#generating-the-mnemonic - */ -function -seed_and_check_bits - (how_many : number) - : Uint8Array -{ -}