@@ -4,6 +4,7 @@ import 'dart:isolate';
44import 'dart:math' ;
55
66import 'package:bitcoindart/bitcoindart.dart' as btc;
7+ import 'package:bitcoindart/src/utils/script.dart' as bscript;
78import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
89import 'package:decimal/decimal.dart' ;
910import 'package:flutter/foundation.dart' ;
@@ -50,6 +51,8 @@ const SPARK_OUT_LIMIT_PER_TX = 16;
5051const OP_SPARKMINT = 0xd1 ;
5152const OP_SPARKSMINT = 0xd2 ;
5253const OP_SPARKSPEND = 0xd3 ;
54+ const OP_SPARKNAMEID = 0xe1 ;
55+ const OP_DROP = 0x75 ;
5356
5457/// top level function for use with [compute]
5558String _hashTag (String tag) {
@@ -61,6 +64,28 @@ String _hashTag(String tag) {
6164 return hash;
6265}
6366
67+ @visibleForTesting
68+ Uint8List sparkNameFeeScript ({
69+ required Uint8List baseScript,
70+ required String name,
71+ required String sparkAddress,
72+ }) => Uint8List .fromList ([
73+ ...baseScript,
74+ ...bscript.compile ([
75+ OP_SPARKNAMEID ,
76+ Uint8List .fromList (utf8.encode (name)),
77+ OP_DROP ,
78+ Uint8List .fromList (utf8.encode (sparkAddress)),
79+ OP_DROP ,
80+ ]),
81+ ]);
82+
83+ @visibleForTesting
84+ bool shouldSubtractSparkFeeFromAmount ({
85+ required bool isSparkNameRegistration,
86+ required bool spendsAll,
87+ }) => ! isSparkNameRegistration && spendsAll;
88+
6489void initSparkLogging (Level level) => libSpark.initSparkLogging (level);
6590
6691abstract class _SparkIsolate {
@@ -568,7 +593,10 @@ mixin SparkInterface<T extends ElectrumXCurrencyInterface>
568593 throw Exception ("Insufficient Spark balance" );
569594 }
570595
571- final bool isSendAll = available == txAmount;
596+ final bool isSendAll = shouldSubtractSparkFeeFromAmount (
597+ isSparkNameRegistration: txData.sparkNameInfo != null ,
598+ spendsAll: available == txAmount,
599+ );
572600
573601 // prepare coin data for ffi
574602 final serializedCoins = coins
@@ -693,6 +721,7 @@ mixin SparkInterface<T extends ElectrumXCurrencyInterface>
693721 final List <InputV2 > tempInputs = [];
694722 final List <OutputV2 > tempOutputs = [];
695723
724+ var sparkNameFeeScriptSizeDelta = 0 ;
696725 for (int i = 0 ; i < (txData.recipients? .length ?? 0 ); i++ ) {
697726 if (txData.recipients! [i].amount.raw == BigInt .zero) {
698727 continue ;
@@ -708,10 +737,19 @@ mixin SparkInterface<T extends ElectrumXCurrencyInterface>
708737 ),
709738 );
710739
711- final scriptPubKey = btc.Address .addressToOutputScript (
740+ var scriptPubKey = btc.Address .addressToOutputScript (
712741 txData.recipients! [i].address,
713742 _bitcoinDartNetwork,
714743 );
744+ if (txData.sparkNameInfo != null ) {
745+ final baseScript = scriptPubKey;
746+ scriptPubKey = sparkNameFeeScript (
747+ baseScript: scriptPubKey,
748+ name: txData.sparkNameInfo! .name,
749+ sparkAddress: txData.sparkNameInfo! .sparkAddress.value,
750+ );
751+ sparkNameFeeScriptSizeDelta += scriptPubKey.length - baseScript.length;
752+ }
715753 txb.addOutput (
716754 scriptPubKey,
717755 recipientsWithFeeSubtracted[i].amount.raw.toInt (),
@@ -816,7 +854,7 @@ mixin SparkInterface<T extends ElectrumXCurrencyInterface>
816854 txHash: extractedTx.getHash (),
817855 additionalTxSize: txData.sparkNameInfo == null
818856 ? 0
819- : noProofNameTxData! .size,
857+ : noProofNameTxData! .size + sparkNameFeeScriptSizeDelta ,
820858 ));
821859
822860 for (final outputScript in spend.outputScripts) {
0 commit comments