Giter Club home page Giter Club logo

coinselection-ts's Introduction

coinselection-ts

Coin selection library in Typescript

This library adopts the same strategy of Bitcoin Core. It implements Branch and Bound, Knapsack and SRD algorithms and uses a waste metric to decide what solution will be used. Obs.: Some parts of this library is based on coinselect (https://github.com/bitcoinjs/coinselect).

Install

npm i --save coinselection-ts

How to use

import { coinselection } from "coinselection-ts"

const fee_rate = 1; //satoshis per byte
const long_term_fee = 10;

const utxos = [
    ...,
    {
    txId: '...',
    vout: 0,
    ...,
    value: 10000,
    script: {
            ...
        }
    }
];

const outputs = [
    ...,
    {
        address: '1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm',
        value: 5000
    }
];

const { inputs, outputs, fee } = coinselection(utxos, outputs, fee_rate, long_term_fee);

coinselection-ts's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

coinselection-ts's Issues

Invalid selection for insufficient funds

Hi Bruno, thanks for your work in porting this library. Unfortunelly it doesn't seem to work correctly.
When the available utxos are not sufficient for the output, the library returns invalid selection instead of no selection at all, and also the feeRate is negative.

    test("Insufficient funds result in an empty array", () => {
       const utxos =
           [
               {
                   "txId": "0eb727d9da3cbbabae776d8200221f68473d5a0bc2c456d18e419c493ed0bf2d",
                   "vout": 46,
                   "value": 14561,
               },
               {
                   "txId": "d4eb4955286bb97c40302b5ec018b55f9b498f2b64ce726f19b0eadb7f4a7c44",
                   "vout": 80,
                   "value": 355933,
               }
           ];

       const recipients = [
               {
                   "value": 69036119,
                   "to": "1GsPMkp9dr1nHYoXzuBitiCiGcDzAuhnB5",
               }
       ];

        const { inputs, outputs } = coinselection(utxos, recipients, 5, 1);
        expect(inputs.length).toEqual(0);
        expect(outputs.length).toEqual(0);
    });

All three strategies return invalid selection. Am I missing something here or is this a bug?

Bnb strategy results in invalid selections & too low fees

Here are two cases which result in invalid selection.

Invalid selection, fee rate negative:
   test("", () => {
            const recipients = [
                {
                    "value": 78544099,
                    "to": "1DLvZKke9UXK2QwaxnPzQ3Mh8YHu7TsKjS",
                }
            ];
            const utxos = [
            {
                "txId": "7ee0dd32d14fc462e623a5d1cfe38f7412a2f740427f778166131ac9e7950158",
                "vout": 75,
                "value": 864351
            },
            {
                "txId": "2d62424ade769d7f7841d03966877a306e2c039930cbbad36ea3bb6cdf378350",
                "vout": 59,
                "value": 5059
            },
            {
                "txId": "6317f465f13cfd6b907d0715c5bb0f2d87d6f83d14699387f6d39ebbfc453747",
                "vout": 34,
                "value": 1278831
            },
            {
                "txId": "0cdde4f3f5b729642327050b9c9348975b74a9bd8771654c475ea008d527c358",
                "vout": 67,
                "value": 105841088
            },
            {
                "txId": "d78b14b7a40aff897210bbd158687c1c6efefa73515445d16e0ea687ce110cf2",
                "vout": 12,
                "value": 384570
            },
            {
                "txId": "8dfa2f40aca062258aec0f365795a685502beda329d5e7c55db266c955ae1e75",
                "vout": 71,
                "value": 121959
            },
            {
                "txId": "084f26d41457c683d08f78e3bea96e4978f715d912aaf4ec2e55a4baf7abdd60",
                "vout": 29,
                "value": 1063197
            },
            {
                "txId": "3072d49285ac92004f70e091d02cb3fbeefb8127cb6165795a31269462d0f347",
                "vout": 8,
                "value": 1292976
            },
            {
                "txId": "0711f8a8745d6e584c585cb5bfbecd7b85acec4e8281c21b9f354b3b0992533a",
                "vout": 50,
                "value": 1523048
            },
            {
                "txId": "11e8e5901baa2a7eac37d192bbaf20c63ac54b9bffc66b86ef47d130f95fe3f8",
                "vout": 87,
                "value": 116444705
            },
            {
                "txId": "34cceb022593edde49d9d4075060cf32e9323d84c865210098012eacadb8773c",
                "vout": 36,
                "value": 9336
            },
            {
                "txId": "43ceadd80743f7133768e1d9eae5c673c9c1a16621924a6bd0aa996f3a04384c",
                "vout": 29,
                "value": 1192622
            },
            {
                "txId": "fce7846e1b9eff68e777853462b22a04d1f67b690119c4eec89c1aa2f545f9a5",
                "vout": 88,
                "value": 423376
            },
            {
                "txId": "1b0bb27a82a93a0fb60dcac10a882769a8d7199d563b48d93213b0c6736cd897",
                "vout": 19,
                "value": 559328
            },
            {
                "txId": "62590fb8d0f6e04692ce9c8b1f96c4e1dc9192a3fbc19bf824b983b17c458b98",
                "vout": 97,
                "value": 3541
            },
            {
                "txId": "280b6d048c2aa681bcd527148496620533d8eef11ee98edda25981cdd3628a1b",
                "vout": 11,
                "value": 741267
            },
            {
                "txId": "ce6547e727f9e20901a8abfa383d7d8b70e0bc5692d88d9c174f4d9806eecf63",
                "vout": 74,
                "value": 1431470
            },
            {
                "txId": "b657b66deefdca5f7b640811d9e3c90e78f3761be6971b7f9e06dbccf625a643",
                "vout": 51,
                "value": 7049
            },
            {
                "txId": "cdc3450c5e41552270fdc60e87b4fe7fc66f978b9e6791009923581100521902",
                "vout": 54,
                "value": 15380
            },
            {
                "txId": "a54cc2feb63a08da3c9946ec0d930d695c0f1cabf10d4bae4b4bb7b12b58c23f",
                "vout": 31,
                "value": 1981645
            },
            {
                "txId": "8dfe00450a29db2609e21597ee9cd1335ccd4af6d0cae77c0ab429043e4fe913",
                "vout": 37,
                "value": 72795249
            },
            {
                "txId": "ccf742c8edb0020717c179c8bac3efe28498700c4f532b7333fe57e6eedade49",
                "vout": 97,
                "value": 7095
            },
            {
                "txId": "5aa27f69208949188e9de652bf905e307403f4929a96d7f3f6de64b89310de84",
                "vout": 11,
                "value": 6260
            },
            {
                "txId": "116d88f50fba2c5bf0bb1be8080ece41dc4df867809d7d5055bcbae34cdf89d4",
                "vout": 89,
                "value": 511317
            },
            {
                "txId": "0d1efec7bdc4ed9845265e9ed18b0e9ac19c378009214adeafcaf36ca5b002ec",
                "vout": 51,
                "value": 663794
            },
            {
                "txId": "d639c97b14f2c0f0016c0cba7bf75fd61519dd1c507213f29499a4ea96774894",
                "vout": 40,
                "value": 15657
            },
            {
                "txId": "da4ab79aa34f3ac6b60618a366560c6d7d21d851198161703c156a3fbfd77c38",
                "vout": 63,
                "value": 82035389
            },
            {
                "txId": "05ab5d7308333a82bc5b2b806d438e66c9e6648aac490d90e9c32ac12615fc96",
                "vout": 27,
                "value": 301810
            },
            {
                "txId": "443cd864ef20f95bb262301b2da801372adb552220472362526f5b3aa8755d4e",
                "vout": 87,
                "value": 7846
            },
            {
                "txId": "4da51480c21ce1e0deab0578e7fd470d6025cccdf4c69d3b5e5823c0a2dfd260",
                "vout": 27,
                "value": 521513
            }
        ];

        const { inputs, outputs, fee } = coinselection(utxos, recipients, 1, 3);
        expect(fee).toBeGreaterThan(0);
    });
Fee too low case: ```
test("Fee is appropriate", () => {
    const recipients = [
    {
            "value": 48214431,
            "to": "1NxYgZF8DQS5VLB4Keh1DWDNREtJuJaF6U",
    }];

    const utxos = [
        {
            "txId": "252a4a4d42cd78187b1e2e4b5b739e2a49857ea870eb5d2f031572fa8cdb3ae9",
            "vout": 24,
            "value": 377646
        },
        {
            "txId": "213e966ddf037c70d6e9a631b4ca5f73c0e452ab706c00f5bc4f76d042cf753b",
            "vout": 55,
            "value": 256823
        },
        {
            "txId": "23d689fcffc2f7e3aaafb1c57fad14a9bbb08b677bde08cd25a0cf5a1aa35477",
            "vout": 83,
            "value": 7289
        },
        {
            "txId": "0e7bdd5981cb6073364dc7812c55e5a19e13a0f712a83e368196a5356f32d2c4",
            "vout": 35,
            "value": 6315
        },
        {
            "txId": "82f3d1637d630ff3d8c7964350e61542e41a75927307828f50d2c20e44f1e2e7",
            "vout": 40,
            "value": 5518
        },
        {
            "txId": "c45e000e051ebe6cd6a1a5d0b8f4dff4cb8c5505cc6d89e844f65d94b5159710",
            "vout": 7,
            "value": 4413
        },
        {
            "txId": "ca3a9f304b2dadb70488c236ad2c1f87964e531854da7003371d0a82ac9e8d37",
            "vout": 10,
            "value": 126361738
        },
        {
            "txId": "64dc03fea16ef65e138392ffeec1319459f958436d017dd5bafab4f13601ad7b",
            "vout": 74,
            "value": 1118484
        },
        {
            "txId": "974912868eaa2ea4694c6431e5d186b6b05e5970861482d6d923e01f619587fa",
            "vout": 14,
            "value": 6851
        },
        {
            "txId": "99f3faaac62e7e488ae557090712086f9da4a73553c1672c4ff8ade755ceb4e0",
            "vout": 69,
            "value": 5114
        },
        {
            "txId": "aa01a5878454224b7a0741670410e1eb2bec408ff81ad956f0850f191261eacb",
            "vout": 42,
            "value": 52133838
        },
        {
            "txId": "cd949e4a29c402d89fb2d57afa1ccc7831aa4207e630fb13e3b8bb56f5404b67",
            "vout": 87,
            "value": 192754
        },
        {
            "txId": "1a44be2914ea9ae59b79ab9818be96f9a96983ad68874b10a784955918a40dfd",
            "vout": 99,
            "value": 577
        },
        {
            "txId": "5421a4753528aba1e4103ddcefd4a4fc5fb0ed9e1d72476788a746bd362a914b",
            "vout": 87,
            "value": 953751
        },
        {
            "txId": "663814f069190a3fcd0c3f1fd14269b9990228115cdc419d9526e7898e410ed1",
            "vout": 39,
            "value": 21055
        },
        {
            "txId": "46e7ac15ba53d2b2bea0e63d91fc3f3b0b3f6a927a9cba44d491260e2d5b26b5",
            "vout": 18,
            "value": 1102083
        },
        {
            "txId": "9654d9f66452e4efac8f2b9dfa3e2c943459060590c0e5b56a968a859c397cba",
            "vout": 62,
            "value": 31110730
        },
        {
            "txId": "a07dd8de6f5cf9d554ef48a99af2718b43ac8c7de2c744e9f28d2d4e54a9d746",
            "vout": 20,
            "value": 70222889
        },
        {
            "txId": "3522b2f6645e51668db802e76020928b2754b1d6bc2db053a9527f458a5880da",
            "vout": 87,
            "value": 2254
        },
        {
            "txId": "235d6cbb81c5aaab77baee2d41263a3c1dc0f3b583e08839480148b8d837a1cc",
            "vout": 82,
            "value": 167886207
        },
        {
            "txId": "ab5aa7bfd82faeeb3fb293c5ebcda97f583a88caf36c53b0c8f2c8dca1dad934",
            "vout": 41,
            "value": 35288853
        },
        {
            "txId": "c7e3874f53510af85fd0ad71591220922eba3ee5d67f7134375f489af772b21f",
            "vout": 22,
            "value": 822353
        },
        {
            "txId": "7a862ed298e5a3b4bad7fad0fcc7a6235d4792d1983060c12903bbcd6080480e",
            "vout": 41,
            "value": 689573
        },
        {
            "txId": "4940f72012ac96a2d5655a279dc15ff960d391c08240c470051bdb44fa3ee97c",
            "vout": 35,
            "value": 994343
        },
        {
            "txId": "909a57a756ee1995c70ede730fab5f659d800f65ed4f7cb4743baeac36091a3f",
            "vout": 94,
            "value": 753812
        },
        {
            "txId": "0a789ef189d5233fbd3d8e35615ddfe0d1a4dace027b00d107e22864330a8b87",
            "vout": 75,
            "value": 3938
        },
        {
            "txId": "92fa1d441641bd2322ebdcd346c488a2d5d5f0912aff2c461c150fe499910a05",
            "vout": 13,
            "value": 45862844
        },
        {
            "txId": "ea865d84753ee9995fbac127f4c8c7ebf5defed0fe5728a66dee1545a41d9f34",
            "vout": 11,
            "value": 1813262
        },
        {
            "txId": "367e00e19eb5a278106db904ac553b7f7ed506787bde22f94da2762ab453c197",
            "vout": 91,
            "value": 307059
        },
        {
            "txId": "22f9730295de06b2214ead938580f79c34649e35ae95f95fd11f4b124c6e3b8d",
            "vout": 31,
            "value": 6666
        },
        {
            "txId": "37d5a37a23993a32b9982a7a416eee3ba6cb7f760eb0c67b0d5009c68a288e12",
            "vout": 94,
            "value": 1406993
        },
        {
            "txId": "001791010a5e0cf53b279dc151427646574e17f09edfce2f1cbce38275f41601",
            "vout": 44,
            "value": 1162524
        },
        {
            "txId": "61876e5b026771528637c77f872662329aa411ba4dd17e5f36e6797d2b59df87",
            "vout": 96,
            "value": 657606
        }
    ];
    const { inputs, outputs, fee } = coinselection(utxos, recipients, 1, 1);
    expect(fee).toBeGreaterThan(100);
});
</details>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.