@@ -100,7 +100,9 @@ Dash.create = function ({
100100
101101 // TODO make more accurate?
102102 let feePreEstimate = 1000 ;
103- let utxos = await getOptimalUtxos ( utxoAddr , amount + feePreEstimate ) ;
103+ let body = await insightApi . getUtxos ( utxoAddr ) ;
104+ let coreUtxos = await getUtxos ( body ) ;
105+ let utxos = await getOptimalUtxos ( coreUtxos , amount + feePreEstimate ) ;
104106 let balance = getBalance ( utxos ) ;
105107
106108 if ( ! utxos . length ) {
@@ -145,16 +147,89 @@ Dash.create = function ({
145147 return tx ;
146148 } ;
147149
150+ /**
151+ * @typedef {Object } CorePayment
152+ * @property {(String|import('@dashevo/dashcore-lib').Address) } address
153+ * @property {Number } satoshis
154+ */
155+
156+ /**
157+ * Send with change back
158+ * @param {String } privKey
159+ * @param {Array<CorePayment> } payments
160+ * @param {(String|import('@dashevo/dashcore-lib').Address) } [changeAddr]
161+ */
162+ dashApi . createPayments = async function ( privKey , payments , changeAddr ) {
163+ let pk = new Dashcore . PrivateKey ( privKey ) ;
164+ let utxoAddr = pk . toPublicKey ( ) . toAddress ( ) . toString ( ) ;
165+ if ( ! changeAddr ) {
166+ changeAddr = utxoAddr ;
167+ }
168+
169+ // TODO make more accurate?
170+ let amount = payments . reduce ( function ( total , pay ) {
171+ return pay . satoshis ;
172+ } , 0 ) ;
173+ let body = await insightApi . getUtxos ( utxoAddr ) ;
174+ let coreUtxos = await getUtxos ( body ) ;
175+ let feePreEstimate = 150 * ( payments . length + coreUtxos . length ) ;
176+ let utxos = await getOptimalUtxos ( coreUtxos , amount + feePreEstimate ) ;
177+ let balance = getBalance ( utxos ) ;
178+
179+ if ( ! utxos . length ) {
180+ throw new Error ( `not enough funds available in utxos for ${ utxoAddr } ` ) ;
181+ }
182+
183+ // (estimate) don't send dust back as change
184+ if ( balance - amount <= DUST + FEE ) {
185+ amount = balance ;
186+ }
187+
188+ console . log ( "DEBUG" ) ;
189+ console . log ( payments , changeAddr ) ;
190+
191+ //@ts -ignore - no input required, actually
192+ let tmpTx = new Transaction ( )
193+ //@ts -ignore - allows single value or array
194+ . from ( utxos ) ;
195+ // TODO update jsdoc for dashcore
196+ tmpTx . to ( payments , 0 ) ;
197+ //@ts -ignore - the JSDoc is wrong in dashcore-lib/lib/transaction/transaction.js
198+ tmpTx . change ( changeAddr ) ;
199+ tmpTx . sign ( pk ) ;
200+
201+ // TODO getsmartfeeestimate??
202+ // fee = 1duff/byte (2 chars hex is 1 byte)
203+ // +10 to be safe (the tmpTx may be a few bytes off - probably only 4 -
204+ // due to how small numbers are encoded)
205+ let fee = 10 + tmpTx . toString ( ) . length / 2 ;
206+
207+ // (adjusted) don't send dust back as change
208+ if ( balance + - amount + - fee <= DUST ) {
209+ amount = balance - fee ;
210+ }
211+
212+ //@ts -ignore - no input required, actually
213+ let tx = new Transaction ( )
214+ //@ts -ignore - allows single value or array
215+ . from ( utxos ) ;
216+ tx . to ( payments , 0 ) ;
217+ tx . fee ( fee ) ;
218+ //@ts -ignore - see above
219+ tx . change ( changeAddr ) ;
220+ tx . sign ( pk ) ;
221+
222+ return tx ;
223+ } ;
224+
148225 // TODO make more optimal
149226 /**
150- * @param {String } utxoAddr
227+ * @param {Array<CoreUtxo> } utxos
151228 * @param {Number } fullAmount - including fee estimate
152229 */
153- async function getOptimalUtxos ( utxoAddr , fullAmount ) {
230+ async function getOptimalUtxos ( utxos , fullAmount ) {
154231 // get smallest coin larger than transaction
155232 // if that would create dust, donate it as tx fee
156- let body = await insightApi . getUtxos ( utxoAddr ) ;
157- let utxos = await getUtxos ( body ) ;
158233 let balance = getBalance ( utxos ) ;
159234
160235 if ( balance < fullAmount ) {
@@ -244,3 +319,10 @@ Dash.create = function ({
244319
245320 return dashApi ;
246321} ;
322+
323+ /**
324+ * @param {String } dash - ex: 0.00000000
325+ */
326+ Dash . toDuff = function ( dash ) {
327+ return Math . round ( parseFloat ( dash ) * DUFFS ) ;
328+ } ;
0 commit comments