@buildonspark/spark-sdk 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/bare/index.cjs +9240 -9125
- package/dist/bare/index.d.cts +14 -11
- package/dist/bare/index.d.ts +14 -11
- package/dist/bare/index.js +3917 -3802
- package/dist/{chunk-XPHYQ2L6.js → chunk-KDEVNW7C.js} +4895 -4779
- package/dist/{chunk-LIZFXQWK.js → chunk-P4HYYSMU.js} +1 -1
- package/dist/{chunk-EHKP3Y65.js → chunk-SRPKOCG4.js} +1 -2
- package/dist/{chunk-FJ7LTA2O.js → chunk-UYTT3C6H.js} +1 -1
- package/dist/{client-AHn11NHe.d.cts → client-Bcb7TUIp.d.cts} +11 -9
- package/dist/{client-GOlkXliC.d.ts → client-D9T58OY8.d.ts} +11 -9
- package/dist/debug.cjs +1852 -1738
- package/dist/debug.d.cts +4 -4
- package/dist/debug.d.ts +4 -4
- package/dist/debug.js +2 -2
- package/dist/graphql/objects/index.d.cts +2 -2
- package/dist/graphql/objects/index.d.ts +2 -2
- package/dist/index.cjs +174 -58
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/index.node.cjs +174 -57
- package/dist/index.node.d.cts +5 -5
- package/dist/index.node.d.ts +5 -5
- package/dist/index.node.js +2 -2
- package/dist/{logging-D7ukPwRA.d.ts → logging-JIaZZIbR.d.ts} +2 -2
- package/dist/{logging-CW3kwBaM.d.cts → logging-zkr4UlOi.d.cts} +2 -2
- package/dist/native/{index.cjs → index.react-native.cjs} +182 -62
- package/dist/native/{index.d.cts → index.react-native.d.cts} +19 -15
- package/dist/native/{index.d.ts → index.react-native.d.ts} +19 -15
- package/dist/native/{index.js → index.react-native.js} +179 -60
- package/dist/{spark-wallet-NxG55m7K.d.cts → spark-wallet-BuFrUWeE.d.cts} +4 -3
- package/dist/{spark-wallet-jwNvWvpK.d.ts → spark-wallet-CE5PYiIb.d.ts} +4 -3
- package/dist/{spark-wallet.browser-Cg4fB-Nm.d.ts → spark-wallet.browser-BwYkkOBU.d.ts} +1 -1
- package/dist/{spark-wallet.browser-Db7Y95Kt.d.cts → spark-wallet.browser-DC3jdQPW.d.cts} +1 -1
- package/dist/{spark-wallet.node-DB3ZqtJG.d.ts → spark-wallet.node-C9d2W-Nb.d.ts} +1 -1
- package/dist/{spark-wallet.node-HEG2ahNd.d.cts → spark-wallet.node-CR_zNxmy.d.cts} +1 -1
- package/dist/tests/test-utils.cjs +168 -51
- package/dist/tests/test-utils.d.cts +4 -4
- package/dist/tests/test-utils.d.ts +4 -4
- package/dist/tests/test-utils.js +4 -4
- package/dist/{token-transactions-B2-BO7Oz.d.ts → token-transactions-BZoJuvuE.d.ts} +1 -1
- package/dist/{token-transactions-BAN68xwg.d.cts → token-transactions-I_OFIoNH.d.cts} +1 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +14 -4
- package/src/graphql/client.ts +6 -9
- package/src/graphql/mutations/CompleteCoopExit.ts +1 -1
- package/src/graphql/mutations/RequestCoopExit.ts +3 -1
- package/src/graphql/mutations/RequestLightningSend.ts +3 -1
- package/src/graphql/objects/CompleteCoopExitInput.ts +22 -33
- package/src/graphql/objects/RequestCoopExitInput.ts +39 -45
- package/src/graphql/objects/RequestLightningSendInput.ts +31 -39
- package/src/index.react-native.ts +21 -0
- package/src/services/config.ts +2 -2
- package/src/services/connection/connection.ts +10 -0
- package/src/services/coop-exit.ts +5 -1
- package/src/services/token-transactions.ts +8 -8
- package/src/spark-wallet/spark-wallet.browser.ts +0 -1
- package/src/spark-wallet/spark-wallet.react-native.ts +5 -3
- package/src/spark-wallet/spark-wallet.ts +56 -9
- package/src/tests/integration/coop-exit.test.ts +2 -0
- package/src/tests/integration/lightning.test.ts +5 -1
- package/src/tests/integration/ssp/coop-exit-validation.test.ts +5 -6
- package/src/tests/integration/ssp/static_deposit.test.ts +45 -35
- package/src/tests/optimize.test.ts +45 -0
- package/src/tests/token-outputs.test.ts +60 -1
- package/src/tests/utils/test-faucet.ts +12 -8
- package/src/utils/optimize.ts +226 -0
- package/src/native/index.ts +0 -21
package/dist/debug.cjs
CHANGED
|
@@ -1044,12 +1044,12 @@ var init_spark_bindings = __esm({
|
|
|
1044
1044
|
});
|
|
1045
1045
|
|
|
1046
1046
|
// src/utils/logging.ts
|
|
1047
|
-
var
|
|
1047
|
+
var import_core12, LOGGER_NAMES, SparkSdkLogger;
|
|
1048
1048
|
var init_logging = __esm({
|
|
1049
1049
|
"src/utils/logging.ts"() {
|
|
1050
1050
|
"use strict";
|
|
1051
1051
|
init_buffer();
|
|
1052
|
-
|
|
1052
|
+
import_core12 = require("@lightsparkdev/core");
|
|
1053
1053
|
LOGGER_NAMES = {
|
|
1054
1054
|
wasm: "wasm"
|
|
1055
1055
|
};
|
|
@@ -1057,7 +1057,7 @@ var init_logging = __esm({
|
|
|
1057
1057
|
static loggers = /* @__PURE__ */ new Map();
|
|
1058
1058
|
static get(name) {
|
|
1059
1059
|
if (!this.loggers.has(name)) {
|
|
1060
|
-
this.loggers.set(name, new
|
|
1060
|
+
this.loggers.set(name, new import_core12.Logger(name));
|
|
1061
1061
|
}
|
|
1062
1062
|
return this.loggers.get(name);
|
|
1063
1063
|
}
|
|
@@ -1111,30 +1111,30 @@ function signFrost({
|
|
|
1111
1111
|
adaptorPubKey
|
|
1112
1112
|
}) {
|
|
1113
1113
|
const logMsg = JSON.stringify({
|
|
1114
|
-
message: (0,
|
|
1114
|
+
message: (0, import_utils17.bytesToHex)(message),
|
|
1115
1115
|
keyPackage: {
|
|
1116
|
-
secretKey: (0,
|
|
1117
|
-
publicKey: (0,
|
|
1118
|
-
verifyingKey: (0,
|
|
1116
|
+
secretKey: (0, import_utils17.bytesToHex)(keyPackage.secretKey),
|
|
1117
|
+
publicKey: (0, import_utils17.bytesToHex)(keyPackage.publicKey),
|
|
1118
|
+
verifyingKey: (0, import_utils17.bytesToHex)(keyPackage.verifyingKey)
|
|
1119
1119
|
},
|
|
1120
1120
|
nonce: {
|
|
1121
|
-
hiding: (0,
|
|
1122
|
-
binding: (0,
|
|
1121
|
+
hiding: (0, import_utils17.bytesToHex)(nonce.hiding),
|
|
1122
|
+
binding: (0, import_utils17.bytesToHex)(nonce.binding)
|
|
1123
1123
|
},
|
|
1124
1124
|
selfCommitment: {
|
|
1125
|
-
hiding: (0,
|
|
1126
|
-
binding: (0,
|
|
1125
|
+
hiding: (0, import_utils17.bytesToHex)(selfCommitment.hiding),
|
|
1126
|
+
binding: (0, import_utils17.bytesToHex)(selfCommitment.binding)
|
|
1127
1127
|
},
|
|
1128
1128
|
statechainCommitments: Object.fromEntries(
|
|
1129
1129
|
Object.entries(statechainCommitments ?? {}).map(([k, v]) => [
|
|
1130
1130
|
k,
|
|
1131
1131
|
{
|
|
1132
|
-
hiding: (0,
|
|
1133
|
-
binding: (0,
|
|
1132
|
+
hiding: (0, import_utils17.bytesToHex)(v.hiding),
|
|
1133
|
+
binding: (0, import_utils17.bytesToHex)(v.binding)
|
|
1134
1134
|
}
|
|
1135
1135
|
])
|
|
1136
1136
|
),
|
|
1137
|
-
adaptorPubKey: adaptorPubKey ? (0,
|
|
1137
|
+
adaptorPubKey: adaptorPubKey ? (0, import_utils17.bytesToHex)(adaptorPubKey) : void 0
|
|
1138
1138
|
});
|
|
1139
1139
|
SparkSdkLogger.get(LOGGER_NAMES.wasm).trace("signFrost", logMsg);
|
|
1140
1140
|
const result = wasm_sign_frost(
|
|
@@ -1147,7 +1147,7 @@ function signFrost({
|
|
|
1147
1147
|
);
|
|
1148
1148
|
SparkSdkLogger.get(LOGGER_NAMES.wasm).trace(
|
|
1149
1149
|
"signFrost result",
|
|
1150
|
-
(0,
|
|
1150
|
+
(0, import_utils17.bytesToHex)(result)
|
|
1151
1151
|
);
|
|
1152
1152
|
return result;
|
|
1153
1153
|
}
|
|
@@ -1163,36 +1163,36 @@ function aggregateFrost({
|
|
|
1163
1163
|
adaptorPubKey
|
|
1164
1164
|
}) {
|
|
1165
1165
|
const logMsg = JSON.stringify({
|
|
1166
|
-
message: (0,
|
|
1166
|
+
message: (0, import_utils17.bytesToHex)(message),
|
|
1167
1167
|
statechainCommitments: Object.fromEntries(
|
|
1168
1168
|
Object.entries(statechainCommitments ?? {}).map(([k, v]) => [
|
|
1169
1169
|
k,
|
|
1170
1170
|
{
|
|
1171
|
-
hiding: (0,
|
|
1172
|
-
binding: (0,
|
|
1171
|
+
hiding: (0, import_utils17.bytesToHex)(v.hiding),
|
|
1172
|
+
binding: (0, import_utils17.bytesToHex)(v.binding)
|
|
1173
1173
|
}
|
|
1174
1174
|
])
|
|
1175
1175
|
),
|
|
1176
1176
|
selfCommitment: {
|
|
1177
|
-
hiding: (0,
|
|
1178
|
-
binding: (0,
|
|
1177
|
+
hiding: (0, import_utils17.bytesToHex)(selfCommitment.hiding),
|
|
1178
|
+
binding: (0, import_utils17.bytesToHex)(selfCommitment.binding)
|
|
1179
1179
|
},
|
|
1180
1180
|
statechainSignatures: Object.fromEntries(
|
|
1181
1181
|
Object.entries(statechainSignatures ?? {}).map(([k, v]) => [
|
|
1182
1182
|
k,
|
|
1183
|
-
(0,
|
|
1183
|
+
(0, import_utils17.bytesToHex)(v)
|
|
1184
1184
|
])
|
|
1185
1185
|
),
|
|
1186
|
-
selfSignature: (0,
|
|
1186
|
+
selfSignature: (0, import_utils17.bytesToHex)(selfSignature),
|
|
1187
1187
|
statechainPublicKeys: Object.fromEntries(
|
|
1188
1188
|
Object.entries(statechainPublicKeys ?? {}).map(([k, v]) => [
|
|
1189
1189
|
k,
|
|
1190
|
-
(0,
|
|
1190
|
+
(0, import_utils17.bytesToHex)(v)
|
|
1191
1191
|
])
|
|
1192
1192
|
),
|
|
1193
|
-
selfPublicKey: (0,
|
|
1194
|
-
verifyingKey: (0,
|
|
1195
|
-
adaptorPubKey: adaptorPubKey ? (0,
|
|
1193
|
+
selfPublicKey: (0, import_utils17.bytesToHex)(selfPublicKey),
|
|
1194
|
+
verifyingKey: (0, import_utils17.bytesToHex)(verifyingKey),
|
|
1195
|
+
adaptorPubKey: adaptorPubKey ? (0, import_utils17.bytesToHex)(adaptorPubKey) : void 0
|
|
1196
1196
|
});
|
|
1197
1197
|
SparkSdkLogger.get(LOGGER_NAMES.wasm).trace("aggregateFrost", logMsg);
|
|
1198
1198
|
const result = wasm_aggregate_frost(
|
|
@@ -1208,7 +1208,7 @@ function aggregateFrost({
|
|
|
1208
1208
|
);
|
|
1209
1209
|
SparkSdkLogger.get(LOGGER_NAMES.wasm).trace(
|
|
1210
1210
|
"aggregateFrost result",
|
|
1211
|
-
(0,
|
|
1211
|
+
(0, import_utils17.bytesToHex)(result)
|
|
1212
1212
|
);
|
|
1213
1213
|
return result;
|
|
1214
1214
|
}
|
|
@@ -1230,12 +1230,12 @@ function decryptEcies({
|
|
|
1230
1230
|
}) {
|
|
1231
1231
|
return decrypt_ecies(encryptedMsg, privateKey);
|
|
1232
1232
|
}
|
|
1233
|
-
var
|
|
1233
|
+
var import_utils17;
|
|
1234
1234
|
var init_wasm = __esm({
|
|
1235
1235
|
"src/spark_bindings/wasm/index.ts"() {
|
|
1236
1236
|
"use strict";
|
|
1237
1237
|
init_buffer();
|
|
1238
|
-
|
|
1238
|
+
import_utils17 = require("@noble/curves/utils");
|
|
1239
1239
|
init_spark_bindings();
|
|
1240
1240
|
init_logging();
|
|
1241
1241
|
}
|
|
@@ -1382,6 +1382,28 @@ var import_sha2 = require("@noble/hashes/sha2");
|
|
|
1382
1382
|
// src/errors/index.ts
|
|
1383
1383
|
init_buffer();
|
|
1384
1384
|
|
|
1385
|
+
// src/utils/fetch.ts
|
|
1386
|
+
init_buffer();
|
|
1387
|
+
var fetchImpl = typeof window !== "undefined" && window.fetch ? window.fetch.bind(window) : globalThis.fetch ? globalThis.fetch.bind(globalThis) : null;
|
|
1388
|
+
var Headers = globalThis.Headers ?? null;
|
|
1389
|
+
var getFetch = () => {
|
|
1390
|
+
if (!fetchImpl) {
|
|
1391
|
+
throw new Error(
|
|
1392
|
+
"Fetch implementation is not set. Please set it using setFetch()."
|
|
1393
|
+
);
|
|
1394
|
+
}
|
|
1395
|
+
if (!Headers) {
|
|
1396
|
+
throw new Error(
|
|
1397
|
+
"Headers implementation is not set. Please set it using setFetch()."
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
const val = {
|
|
1401
|
+
fetch: fetchImpl,
|
|
1402
|
+
Headers
|
|
1403
|
+
};
|
|
1404
|
+
return val;
|
|
1405
|
+
};
|
|
1406
|
+
|
|
1385
1407
|
// src/graphql/mutations/ClaimStaticDeposit.ts
|
|
1386
1408
|
init_buffer();
|
|
1387
1409
|
|
|
@@ -1747,7 +1769,7 @@ fragment CoopExitRequestFragment on CoopExitRequest {
|
|
|
1747
1769
|
var CompleteCoopExit = `
|
|
1748
1770
|
mutation CompleteCoopExit(
|
|
1749
1771
|
$user_outbound_transfer_external_id: UUID!
|
|
1750
|
-
$coop_exit_request_id: ID
|
|
1772
|
+
$coop_exit_request_id: ID
|
|
1751
1773
|
) {
|
|
1752
1774
|
complete_coop_exit(input: {
|
|
1753
1775
|
user_outbound_transfer_external_id: $user_outbound_transfer_external_id
|
|
@@ -1962,11 +1984,12 @@ var RequestCoopExit = `
|
|
|
1962
1984
|
mutation RequestCoopExit(
|
|
1963
1985
|
$leaf_external_ids: [UUID!]!
|
|
1964
1986
|
$withdrawal_address: String!
|
|
1965
|
-
$idempotency_key: String
|
|
1987
|
+
$idempotency_key: String
|
|
1966
1988
|
$exit_speed: ExitSpeed!
|
|
1967
1989
|
$withdraw_all: Boolean
|
|
1968
1990
|
$fee_leaf_external_ids: [UUID!]
|
|
1969
1991
|
$fee_quote_id: ID
|
|
1992
|
+
$user_outbound_transfer_external_id: UUID
|
|
1970
1993
|
) {
|
|
1971
1994
|
request_coop_exit(
|
|
1972
1995
|
input: {
|
|
@@ -1977,6 +2000,7 @@ var RequestCoopExit = `
|
|
|
1977
2000
|
withdraw_all: $withdraw_all
|
|
1978
2001
|
fee_leaf_external_ids: $fee_leaf_external_ids
|
|
1979
2002
|
fee_quote_id: $fee_quote_id
|
|
2003
|
+
user_outbound_transfer_external_id: $user_outbound_transfer_external_id
|
|
1980
2004
|
}
|
|
1981
2005
|
) {
|
|
1982
2006
|
request {
|
|
@@ -2195,13 +2219,15 @@ fragment LightningSendRequestFragment on LightningSendRequest {
|
|
|
2195
2219
|
var RequestLightningSend = `
|
|
2196
2220
|
mutation RequestLightningSend(
|
|
2197
2221
|
$encoded_invoice: String!
|
|
2198
|
-
$idempotency_key: String
|
|
2222
|
+
$idempotency_key: String
|
|
2199
2223
|
$amount_sats: Long
|
|
2224
|
+
$user_outbound_transfer_external_id: UUID
|
|
2200
2225
|
) {
|
|
2201
2226
|
request_lightning_send(input: {
|
|
2202
2227
|
encoded_invoice: $encoded_invoice
|
|
2203
2228
|
idempotency_key: $idempotency_key
|
|
2204
2229
|
amount_sats: $amount_sats
|
|
2230
|
+
user_outbound_transfer_external_id: $user_outbound_transfer_external_id
|
|
2205
2231
|
}) {
|
|
2206
2232
|
request {
|
|
2207
2233
|
...LightningSendRequestFragment
|
|
@@ -2934,28 +2960,6 @@ var UserRequest2 = `
|
|
|
2934
2960
|
${FRAGMENT14}
|
|
2935
2961
|
`;
|
|
2936
2962
|
|
|
2937
|
-
// src/utils/fetch.ts
|
|
2938
|
-
init_buffer();
|
|
2939
|
-
var fetchImpl = typeof window !== "undefined" && window.fetch ? window.fetch.bind(window) : globalThis.fetch ? globalThis.fetch.bind(globalThis) : null;
|
|
2940
|
-
var Headers = globalThis.Headers ?? null;
|
|
2941
|
-
var getFetch = () => {
|
|
2942
|
-
if (!fetchImpl) {
|
|
2943
|
-
throw new Error(
|
|
2944
|
-
"Fetch implementation is not set. Please set it using setFetch()."
|
|
2945
|
-
);
|
|
2946
|
-
}
|
|
2947
|
-
if (!Headers) {
|
|
2948
|
-
throw new Error(
|
|
2949
|
-
"Headers implementation is not set. Please set it using setFetch()."
|
|
2950
|
-
);
|
|
2951
|
-
}
|
|
2952
|
-
const val = {
|
|
2953
|
-
fetch: fetchImpl,
|
|
2954
|
-
Headers
|
|
2955
|
-
};
|
|
2956
|
-
return val;
|
|
2957
|
-
};
|
|
2958
|
-
|
|
2959
2963
|
// src/graphql/client.ts
|
|
2960
2964
|
var SspClient = class {
|
|
2961
2965
|
requester;
|
|
@@ -3058,14 +3062,12 @@ var SspClient = class {
|
|
|
3058
3062
|
throw new Error("Not implemented");
|
|
3059
3063
|
}
|
|
3060
3064
|
async completeCoopExit({
|
|
3061
|
-
userOutboundTransferExternalId
|
|
3062
|
-
coopExitRequestId
|
|
3065
|
+
userOutboundTransferExternalId
|
|
3063
3066
|
}) {
|
|
3064
3067
|
return await this.executeRawQuery({
|
|
3065
3068
|
queryPayload: CompleteCoopExit,
|
|
3066
3069
|
variables: {
|
|
3067
|
-
user_outbound_transfer_external_id: userOutboundTransferExternalId
|
|
3068
|
-
coop_exit_request_id: coopExitRequestId
|
|
3070
|
+
user_outbound_transfer_external_id: userOutboundTransferExternalId
|
|
3069
3071
|
},
|
|
3070
3072
|
constructObject: (response) => {
|
|
3071
3073
|
return CoopExitRequestFromJson(response.complete_coop_exit.request);
|
|
@@ -3075,29 +3077,28 @@ var SspClient = class {
|
|
|
3075
3077
|
async requestCoopExit({
|
|
3076
3078
|
leafExternalIds,
|
|
3077
3079
|
withdrawalAddress,
|
|
3078
|
-
idempotencyKey,
|
|
3079
3080
|
exitSpeed,
|
|
3080
3081
|
feeLeafExternalIds,
|
|
3081
3082
|
feeQuoteId,
|
|
3082
|
-
withdrawAll
|
|
3083
|
+
withdrawAll,
|
|
3084
|
+
userOutboundTransferExternalId
|
|
3083
3085
|
}) {
|
|
3084
3086
|
return await this.executeRawQuery({
|
|
3085
3087
|
queryPayload: RequestCoopExit,
|
|
3086
3088
|
variables: {
|
|
3087
3089
|
leaf_external_ids: leafExternalIds,
|
|
3088
3090
|
withdrawal_address: withdrawalAddress,
|
|
3089
|
-
idempotency_key: idempotencyKey,
|
|
3090
3091
|
exit_speed: exitSpeed,
|
|
3091
3092
|
fee_leaf_external_ids: feeLeafExternalIds,
|
|
3092
3093
|
fee_quote_id: feeQuoteId,
|
|
3093
|
-
withdraw_all: withdrawAll
|
|
3094
|
+
withdraw_all: withdrawAll,
|
|
3095
|
+
user_outbound_transfer_external_id: userOutboundTransferExternalId
|
|
3094
3096
|
},
|
|
3095
3097
|
constructObject: (response) => {
|
|
3096
3098
|
return CoopExitRequestFromJson(response.request_coop_exit.request);
|
|
3097
3099
|
}
|
|
3098
3100
|
});
|
|
3099
3101
|
}
|
|
3100
|
-
// TODO: Lets name this better
|
|
3101
3102
|
async requestLightningReceive({
|
|
3102
3103
|
amountSats,
|
|
3103
3104
|
network,
|
|
@@ -3129,15 +3130,15 @@ var SspClient = class {
|
|
|
3129
3130
|
}
|
|
3130
3131
|
async requestLightningSend({
|
|
3131
3132
|
encodedInvoice,
|
|
3132
|
-
|
|
3133
|
-
|
|
3133
|
+
amountSats,
|
|
3134
|
+
userOutboundTransferExternalId
|
|
3134
3135
|
}) {
|
|
3135
3136
|
return await this.executeRawQuery({
|
|
3136
3137
|
queryPayload: RequestLightningSend,
|
|
3137
3138
|
variables: {
|
|
3138
3139
|
encoded_invoice: encodedInvoice,
|
|
3139
|
-
|
|
3140
|
-
|
|
3140
|
+
amount_sats: amountSats,
|
|
3141
|
+
user_outbound_transfer_external_id: userOutboundTransferExternalId
|
|
3141
3142
|
},
|
|
3142
3143
|
constructObject: (response) => {
|
|
3143
3144
|
return LightningSendRequestFromJson(
|
|
@@ -19085,1247 +19086,426 @@ function isSet3(value) {
|
|
|
19085
19086
|
// src/services/config.ts
|
|
19086
19087
|
init_buffer();
|
|
19087
19088
|
|
|
19088
|
-
// src/
|
|
19089
|
-
init_buffer();
|
|
19090
|
-
var import_secp256k14 = require("@bitcoinerlab/secp256k1");
|
|
19091
|
-
var import_secp256k15 = require("@noble/curves/secp256k1");
|
|
19092
|
-
var import_utils5 = require("@noble/curves/utils");
|
|
19093
|
-
var import_sha22 = require("@noble/hashes/sha2");
|
|
19094
|
-
var import_bip32 = require("@scure/bip32");
|
|
19095
|
-
var import_bip39 = require("@scure/bip39");
|
|
19096
|
-
var import_english = require("@scure/bip39/wordlists/english");
|
|
19097
|
-
var import_utils6 = require("@scure/btc-signer/utils");
|
|
19098
|
-
var ecies = __toESM(require("eciesjs"), 1);
|
|
19099
|
-
|
|
19100
|
-
// src/constants.ts
|
|
19101
|
-
init_buffer();
|
|
19102
|
-
var import_core10 = require("@lightsparkdev/core");
|
|
19103
|
-
var isReactNative = "navigator" in globalThis && navigator.product === "ReactNative";
|
|
19104
|
-
var isBun = "Bun" in globalThis;
|
|
19105
|
-
var isWebExtension = (
|
|
19106
|
-
/* globalThis.chrome actually exists in extension contexts for all browsers for legacy reasons: */
|
|
19107
|
-
"chrome" in globalThis && globalThis.chrome.runtime?.id
|
|
19108
|
-
);
|
|
19109
|
-
var userAgent = "navigator" in globalThis ? globalThis.navigator.userAgent || "unknown-user-agent" : void 0;
|
|
19110
|
-
var packageVersion = true ? "0.3.6" : "unknown";
|
|
19111
|
-
var baseEnvStr = "unknown";
|
|
19112
|
-
if (isBun) {
|
|
19113
|
-
const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
|
|
19114
|
-
baseEnvStr = `bun/${bunVersion}`;
|
|
19115
|
-
} else if (import_core10.isNode) {
|
|
19116
|
-
baseEnvStr = `node/${globalThis.process.version}`;
|
|
19117
|
-
} else if (isReactNative) {
|
|
19118
|
-
baseEnvStr = "react-native";
|
|
19119
|
-
} else if (import_core10.isBare) {
|
|
19120
|
-
const bareVersion = Bare.version;
|
|
19121
|
-
baseEnvStr = `bare/${bareVersion}`;
|
|
19122
|
-
} else if (isWebExtension) {
|
|
19123
|
-
const protocol = "location" in globalThis ? globalThis.location.protocol : "";
|
|
19124
|
-
const extScriptType = "window" in globalThis ? "content-script" : "background-script";
|
|
19125
|
-
baseEnvStr = `web-extension/${protocol.replace(":", "")}/${extScriptType}/${userAgent}`;
|
|
19126
|
-
} else {
|
|
19127
|
-
baseEnvStr = `browser/${userAgent}`;
|
|
19128
|
-
}
|
|
19129
|
-
var clientEnv = `js-spark-sdk/${packageVersion} ${baseEnvStr}`;
|
|
19130
|
-
|
|
19131
|
-
// src/utils/keys.ts
|
|
19089
|
+
// src/utils/network.ts
|
|
19132
19090
|
init_buffer();
|
|
19133
|
-
var
|
|
19134
|
-
var
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
|
|
19138
|
-
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
|
|
19144
|
-
|
|
19145
|
-
|
|
19146
|
-
|
|
19147
|
-
|
|
19148
|
-
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
19152
|
-
|
|
19153
|
-
|
|
19154
|
-
|
|
19155
|
-
|
|
19156
|
-
|
|
19157
|
-
|
|
19158
|
-
|
|
19159
|
-
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
const pubkeyPoint = import_secp256k1.secp256k1.Point.fromHex(pubkey);
|
|
19163
|
-
const privTweek = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(tweak);
|
|
19164
|
-
const pubTweek = import_secp256k1.secp256k1.getPublicKey(privTweek, true);
|
|
19165
|
-
const tweekPoint = import_secp256k1.secp256k1.Point.fromHex(pubTweek);
|
|
19166
|
-
return pubkeyPoint.add(tweekPoint).toBytes(true);
|
|
19167
|
-
}
|
|
19168
|
-
function subtractPublicKeys(a, b) {
|
|
19169
|
-
if (a.length !== 33 || b.length !== 33) {
|
|
19170
|
-
throw new ValidationError("Public keys must be 33 bytes", {
|
|
19171
|
-
field: "publicKeys",
|
|
19172
|
-
value: `a: ${a.length}, b: ${b.length}`,
|
|
19173
|
-
expected: 33
|
|
19174
|
-
});
|
|
19175
|
-
}
|
|
19176
|
-
const pubkeyA = import_secp256k1.secp256k1.Point.fromHex(a);
|
|
19177
|
-
const pubkeyB = import_secp256k1.secp256k1.Point.fromHex(b);
|
|
19178
|
-
return pubkeyA.subtract(pubkeyB).toBytes(true);
|
|
19179
|
-
}
|
|
19180
|
-
function addPrivateKeys(a, b) {
|
|
19181
|
-
if (a.length !== 32 || b.length !== 32) {
|
|
19182
|
-
throw new ValidationError("Private keys must be 32 bytes", {
|
|
19183
|
-
field: "privateKeys",
|
|
19184
|
-
value: `a: ${a.length}, b: ${b.length}`,
|
|
19185
|
-
expected: 32
|
|
19186
|
-
});
|
|
19187
|
-
}
|
|
19188
|
-
const privA = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(a);
|
|
19189
|
-
const privB = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(b);
|
|
19190
|
-
const sum = (privA + privB) % import_secp256k1.secp256k1.CURVE.n;
|
|
19191
|
-
return (0, import_utils2.numberToBytesBE)(sum, 32);
|
|
19192
|
-
}
|
|
19193
|
-
function subtractPrivateKeys(a, b) {
|
|
19194
|
-
if (a.length !== 32 || b.length !== 32) {
|
|
19195
|
-
throw new ValidationError("Private keys must be 32 bytes", {
|
|
19196
|
-
field: "privateKeys",
|
|
19197
|
-
value: `a: ${a.length}, b: ${b.length}`,
|
|
19198
|
-
expected: 32
|
|
19199
|
-
});
|
|
19091
|
+
var btc = __toESM(require("@scure/btc-signer"), 1);
|
|
19092
|
+
var import_base2 = require("@scure/base");
|
|
19093
|
+
var Network2 = /* @__PURE__ */ ((Network5) => {
|
|
19094
|
+
Network5[Network5["MAINNET"] = 0] = "MAINNET";
|
|
19095
|
+
Network5[Network5["TESTNET"] = 1] = "TESTNET";
|
|
19096
|
+
Network5[Network5["SIGNET"] = 2] = "SIGNET";
|
|
19097
|
+
Network5[Network5["REGTEST"] = 3] = "REGTEST";
|
|
19098
|
+
Network5[Network5["LOCAL"] = 4] = "LOCAL";
|
|
19099
|
+
return Network5;
|
|
19100
|
+
})(Network2 || {});
|
|
19101
|
+
var NetworkToProto = {
|
|
19102
|
+
[0 /* MAINNET */]: 1 /* MAINNET */,
|
|
19103
|
+
[1 /* TESTNET */]: 3 /* TESTNET */,
|
|
19104
|
+
[2 /* SIGNET */]: 4 /* SIGNET */,
|
|
19105
|
+
[3 /* REGTEST */]: 2 /* REGTEST */,
|
|
19106
|
+
[4 /* LOCAL */]: 2 /* REGTEST */
|
|
19107
|
+
};
|
|
19108
|
+
var protoToNetwork = (protoNetwork) => {
|
|
19109
|
+
switch (protoNetwork) {
|
|
19110
|
+
case 1 /* MAINNET */:
|
|
19111
|
+
return 0 /* MAINNET */;
|
|
19112
|
+
case 3 /* TESTNET */:
|
|
19113
|
+
return 1 /* TESTNET */;
|
|
19114
|
+
case 4 /* SIGNET */:
|
|
19115
|
+
return 2 /* SIGNET */;
|
|
19116
|
+
case 2 /* REGTEST */:
|
|
19117
|
+
return 3 /* REGTEST */;
|
|
19118
|
+
default:
|
|
19119
|
+
return void 0;
|
|
19200
19120
|
}
|
|
19201
|
-
|
|
19202
|
-
|
|
19203
|
-
|
|
19204
|
-
|
|
19205
|
-
|
|
19206
|
-
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
19211
|
-
|
|
19212
|
-
|
|
19213
|
-
|
|
19121
|
+
};
|
|
19122
|
+
var NetworkConfig = {
|
|
19123
|
+
[0 /* MAINNET */]: btc.NETWORK,
|
|
19124
|
+
[1 /* TESTNET */]: btc.TEST_NETWORK,
|
|
19125
|
+
[2 /* SIGNET */]: btc.TEST_NETWORK,
|
|
19126
|
+
[3 /* REGTEST */]: { ...btc.TEST_NETWORK, bech32: "bcrt" },
|
|
19127
|
+
[4 /* LOCAL */]: { ...btc.TEST_NETWORK, bech32: "bcrt" }
|
|
19128
|
+
};
|
|
19129
|
+
var getNetwork = (network) => NetworkConfig[network];
|
|
19130
|
+
function getNetworkFromAddress(address) {
|
|
19131
|
+
try {
|
|
19132
|
+
const bechAddress = address;
|
|
19133
|
+
const decoded = (() => {
|
|
19134
|
+
try {
|
|
19135
|
+
return import_base2.bech32.decode(bechAddress);
|
|
19136
|
+
} catch (_) {
|
|
19137
|
+
return import_base2.bech32m.decode(bechAddress);
|
|
19138
|
+
}
|
|
19139
|
+
})();
|
|
19140
|
+
if (decoded.prefix === "bc") {
|
|
19141
|
+
return "MAINNET" /* MAINNET */;
|
|
19142
|
+
} else if (decoded.prefix === "bcrt") {
|
|
19143
|
+
return "REGTEST" /* REGTEST */;
|
|
19214
19144
|
}
|
|
19215
|
-
|
|
19216
|
-
|
|
19217
|
-
|
|
19218
|
-
|
|
19219
|
-
|
|
19220
|
-
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19145
|
+
} catch (err) {
|
|
19146
|
+
throw new ValidationError(
|
|
19147
|
+
"Invalid Bitcoin address",
|
|
19148
|
+
{
|
|
19149
|
+
field: "address",
|
|
19150
|
+
value: address,
|
|
19151
|
+
expected: "Valid Bech32 address with prefix 'bc' or 'bcrt'"
|
|
19152
|
+
},
|
|
19153
|
+
err instanceof Error ? err : void 0
|
|
19154
|
+
);
|
|
19225
19155
|
}
|
|
19226
|
-
|
|
19227
|
-
|
|
19156
|
+
return null;
|
|
19157
|
+
}
|
|
19158
|
+
function getNetworkFromString(network) {
|
|
19159
|
+
const net = (network ?? "REGTEST").toUpperCase();
|
|
19160
|
+
if (net === "MAINNET") return 0 /* MAINNET */;
|
|
19161
|
+
if (net === "TESTNET") return 1 /* TESTNET */;
|
|
19162
|
+
if (net === "SIGNET") return 2 /* SIGNET */;
|
|
19163
|
+
if (net === "LOCAL") return 4 /* LOCAL */;
|
|
19164
|
+
return 3 /* REGTEST */;
|
|
19228
19165
|
}
|
|
19229
19166
|
|
|
19230
|
-
// src/
|
|
19167
|
+
// src/services/wallet-config.ts
|
|
19231
19168
|
init_buffer();
|
|
19232
|
-
var import_secp256k12 = require("@noble/curves/secp256k1");
|
|
19233
|
-
var import_utils3 = require("@noble/curves/utils");
|
|
19234
19169
|
|
|
19235
|
-
// src/
|
|
19170
|
+
// src/tests/isHermeticTest.ts
|
|
19236
19171
|
init_buffer();
|
|
19237
|
-
var
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19242
|
-
|
|
19172
|
+
var isHermeticTest = Boolean(
|
|
19173
|
+
typeof process !== "undefined" && process?.env?.HERMETIC_TEST === "true"
|
|
19174
|
+
);
|
|
19175
|
+
|
|
19176
|
+
// src/services/wallet-config.ts
|
|
19177
|
+
var SSP_IDENTITY_PUBLIC_KEYS = {
|
|
19178
|
+
LOCAL: "028c094a432d46a0ac95349d792c2e3730bd60c29188db716f56a99e39b95338b4",
|
|
19179
|
+
REGTEST: {
|
|
19180
|
+
PROD: "022bf283544b16c0622daecb79422007d167eca6ce9f0c98c0c49833b1f7170bfe"
|
|
19181
|
+
},
|
|
19182
|
+
MAINNET: {
|
|
19183
|
+
PROD: "023e33e2920326f64ea31058d44777442d97d7d5cbfcf54e3060bc1695e5261c93"
|
|
19243
19184
|
}
|
|
19244
|
-
return cryptoImpl;
|
|
19245
19185
|
};
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
|
|
19257
|
-
|
|
19186
|
+
var URL_CONFIG = {
|
|
19187
|
+
LOCAL: {
|
|
19188
|
+
SSP: "http://127.0.0.1:5000",
|
|
19189
|
+
ELECTRS: "http://127.0.0.1:30000"
|
|
19190
|
+
},
|
|
19191
|
+
REGTEST: {
|
|
19192
|
+
PROD: {
|
|
19193
|
+
SSP: "https://api.lightspark.com",
|
|
19194
|
+
ELECTRS: "https://regtest-mempool.us-west-2.sparkinfra.net/api"
|
|
19195
|
+
}
|
|
19196
|
+
},
|
|
19197
|
+
MAINNET: {
|
|
19198
|
+
PROD: {
|
|
19199
|
+
SSP: "https://api.lightspark.com",
|
|
19200
|
+
ELECTRS: "https://mempool.space/api"
|
|
19258
19201
|
}
|
|
19259
19202
|
}
|
|
19260
|
-
}
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19203
|
+
};
|
|
19204
|
+
var ELECTRS_CREDENTIALS = {
|
|
19205
|
+
username: "spark-sdk",
|
|
19206
|
+
password: "mCMk1JqlBNtetUNy"
|
|
19207
|
+
};
|
|
19208
|
+
function getElectrsUrl(network) {
|
|
19209
|
+
switch (network) {
|
|
19210
|
+
case "LOCAL":
|
|
19211
|
+
return isHermeticTest ? "http://mempool.minikube.local/api" : URL_CONFIG.LOCAL.ELECTRS;
|
|
19212
|
+
case "REGTEST":
|
|
19213
|
+
return URL_CONFIG.REGTEST.PROD.ELECTRS;
|
|
19214
|
+
case "MAINNET":
|
|
19215
|
+
return URL_CONFIG.MAINNET.PROD.ELECTRS;
|
|
19216
|
+
default:
|
|
19217
|
+
return URL_CONFIG.LOCAL.ELECTRS;
|
|
19271
19218
|
}
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19219
|
+
}
|
|
19220
|
+
function getSspIdentityPublicKey(network) {
|
|
19221
|
+
switch (network) {
|
|
19222
|
+
case "LOCAL":
|
|
19223
|
+
return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
|
|
19224
|
+
case "REGTEST":
|
|
19225
|
+
return SSP_IDENTITY_PUBLIC_KEYS.REGTEST.PROD;
|
|
19226
|
+
case "MAINNET":
|
|
19227
|
+
return SSP_IDENTITY_PUBLIC_KEYS.MAINNET.PROD;
|
|
19228
|
+
default:
|
|
19229
|
+
return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
|
|
19278
19230
|
}
|
|
19279
|
-
return (old_s % m + m) % m;
|
|
19280
19231
|
}
|
|
19281
|
-
function
|
|
19282
|
-
|
|
19283
|
-
|
|
19284
|
-
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
}
|
|
19292
|
-
const xPow = x ** BigInt(i) % polynomial.fieldModulus;
|
|
19293
|
-
result = (result + xPow * coeff) % polynomial.fieldModulus;
|
|
19232
|
+
function getSspUrl(network) {
|
|
19233
|
+
switch (network) {
|
|
19234
|
+
case "LOCAL":
|
|
19235
|
+
return isHermeticTest ? "http://app.minikube.local" : URL_CONFIG.LOCAL.SSP;
|
|
19236
|
+
case "REGTEST":
|
|
19237
|
+
return URL_CONFIG.REGTEST.PROD.SSP;
|
|
19238
|
+
case "MAINNET":
|
|
19239
|
+
return URL_CONFIG.MAINNET.PROD.SSP;
|
|
19240
|
+
default:
|
|
19241
|
+
return URL_CONFIG.LOCAL.SSP;
|
|
19294
19242
|
}
|
|
19295
|
-
return result;
|
|
19296
19243
|
}
|
|
19297
|
-
function
|
|
19298
|
-
|
|
19299
|
-
|
|
19300
|
-
|
|
19301
|
-
value: "0",
|
|
19302
|
-
expected: "Non-zero value"
|
|
19303
|
-
});
|
|
19244
|
+
function getSspSchemaEndpoint(network) {
|
|
19245
|
+
switch (network) {
|
|
19246
|
+
case "LOCAL":
|
|
19247
|
+
return "graphql/spark/rc";
|
|
19304
19248
|
}
|
|
19305
|
-
|
|
19306
|
-
return numerator * inverse % fieldModulus;
|
|
19249
|
+
return;
|
|
19307
19250
|
}
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19251
|
+
var PROD_PUBKEYS = [
|
|
19252
|
+
"03dfbdff4b6332c220f8fa2ba8ed496c698ceada563fa01b67d9983bfc5c95e763",
|
|
19253
|
+
"03e625e9768651c9be268e287245cc33f96a68ce9141b0b4769205db027ee8ed77",
|
|
19254
|
+
"022eda13465a59205413086130a65dc0ed1b8f8e51937043161f8be0c369b1a410"
|
|
19255
|
+
];
|
|
19256
|
+
function getLocalFrostSignerAddress() {
|
|
19257
|
+
return isHermeticTest ? "localhost:9999" : "unix:///tmp/frost_0.sock";
|
|
19258
|
+
}
|
|
19259
|
+
var BASE_CONFIG = {
|
|
19260
|
+
network: "LOCAL",
|
|
19261
|
+
coordinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
19262
|
+
frostSignerAddress: getLocalFrostSignerAddress(),
|
|
19263
|
+
threshold: 2,
|
|
19264
|
+
signingOperators: getLocalSigningOperators(),
|
|
19265
|
+
tokenSignatures: "SCHNORR",
|
|
19266
|
+
tokenValidityDurationSeconds: 180,
|
|
19267
|
+
electrsUrl: getElectrsUrl("LOCAL"),
|
|
19268
|
+
expectedWithdrawBondSats: 1e4,
|
|
19269
|
+
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
19270
|
+
sspClientOptions: {
|
|
19271
|
+
baseUrl: getSspUrl("LOCAL"),
|
|
19272
|
+
identityPublicKey: getSspIdentityPublicKey("LOCAL"),
|
|
19273
|
+
schemaEndpoint: getSspSchemaEndpoint("LOCAL")
|
|
19274
|
+
},
|
|
19275
|
+
signerWithPreExistingKeys: false,
|
|
19276
|
+
console: {
|
|
19277
|
+
otel: false
|
|
19318
19278
|
}
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19279
|
+
};
|
|
19280
|
+
var LOCAL_WALLET_CONFIG = {
|
|
19281
|
+
...BASE_CONFIG,
|
|
19282
|
+
threshold: 3
|
|
19283
|
+
};
|
|
19284
|
+
var LOCAL_WALLET_CONFIG_SCHNORR = {
|
|
19285
|
+
...LOCAL_WALLET_CONFIG,
|
|
19286
|
+
threshold: 3
|
|
19287
|
+
// 3 for issuance tests.
|
|
19288
|
+
};
|
|
19289
|
+
var LOCAL_WALLET_CONFIG_ECDSA = {
|
|
19290
|
+
...LOCAL_WALLET_CONFIG,
|
|
19291
|
+
tokenSignatures: "ECDSA",
|
|
19292
|
+
threshold: 3
|
|
19293
|
+
// 3 for issuance tests.
|
|
19294
|
+
};
|
|
19295
|
+
var REGTEST_WALLET_CONFIG = {
|
|
19296
|
+
...BASE_CONFIG,
|
|
19297
|
+
network: "REGTEST",
|
|
19298
|
+
signingOperators: getSigningOperators(),
|
|
19299
|
+
electrsUrl: getElectrsUrl("REGTEST"),
|
|
19300
|
+
expectedWithdrawBondSats: 1e4,
|
|
19301
|
+
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
19302
|
+
sspClientOptions: {
|
|
19303
|
+
baseUrl: getSspUrl("REGTEST"),
|
|
19304
|
+
identityPublicKey: getSspIdentityPublicKey("REGTEST")
|
|
19326
19305
|
}
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19306
|
+
};
|
|
19307
|
+
var MAINNET_WALLET_CONFIG = {
|
|
19308
|
+
...BASE_CONFIG,
|
|
19309
|
+
network: "MAINNET",
|
|
19310
|
+
signingOperators: getSigningOperators(),
|
|
19311
|
+
electrsUrl: getElectrsUrl("MAINNET"),
|
|
19312
|
+
expectedWithdrawBondSats: 1e4,
|
|
19313
|
+
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
19314
|
+
sspClientOptions: {
|
|
19315
|
+
baseUrl: getSspUrl("MAINNET"),
|
|
19316
|
+
identityPublicKey: getSspIdentityPublicKey("MAINNET")
|
|
19338
19317
|
}
|
|
19318
|
+
};
|
|
19319
|
+
var WalletConfig = {
|
|
19320
|
+
LOCAL: LOCAL_WALLET_CONFIG,
|
|
19321
|
+
LOCAL_SCHNORR: LOCAL_WALLET_CONFIG_SCHNORR,
|
|
19322
|
+
LOCAL_ECDSA: LOCAL_WALLET_CONFIG_ECDSA,
|
|
19323
|
+
REGTEST: REGTEST_WALLET_CONFIG,
|
|
19324
|
+
MAINNET: MAINNET_WALLET_CONFIG
|
|
19325
|
+
};
|
|
19326
|
+
function getSigningOperators() {
|
|
19339
19327
|
return {
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19328
|
+
"0000000000000000000000000000000000000000000000000000000000000001": {
|
|
19329
|
+
id: 0,
|
|
19330
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
19331
|
+
address: "https://0.spark.lightspark.com",
|
|
19332
|
+
identityPublicKey: PROD_PUBKEYS[0]
|
|
19333
|
+
},
|
|
19334
|
+
"0000000000000000000000000000000000000000000000000000000000000002": {
|
|
19335
|
+
id: 1,
|
|
19336
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
19337
|
+
address: "https://1.spark.lightspark.com",
|
|
19338
|
+
identityPublicKey: PROD_PUBKEYS[1]
|
|
19339
|
+
},
|
|
19340
|
+
"0000000000000000000000000000000000000000000000000000000000000003": {
|
|
19341
|
+
id: 2,
|
|
19342
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
19343
|
+
address: "https://2.spark.flashnet.xyz",
|
|
19344
|
+
identityPublicKey: PROD_PUBKEYS[2]
|
|
19345
|
+
}
|
|
19343
19346
|
};
|
|
19344
19347
|
}
|
|
19345
|
-
function
|
|
19346
|
-
const
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
threshold
|
|
19348
|
+
function getLocalSigningOperators() {
|
|
19349
|
+
const addresses = Array.from(
|
|
19350
|
+
{ length: 5 },
|
|
19351
|
+
(_, i) => isHermeticTest ? `https://${i}.spark.minikube.local` : `https://localhost:${i + 8535}`
|
|
19350
19352
|
);
|
|
19351
|
-
const
|
|
19352
|
-
|
|
19353
|
-
|
|
19354
|
-
|
|
19355
|
-
|
|
19356
|
-
|
|
19357
|
-
|
|
19358
|
-
share
|
|
19359
|
-
});
|
|
19360
|
-
}
|
|
19361
|
-
return shares;
|
|
19362
|
-
}
|
|
19363
|
-
function splitSecretWithProofs(secret, fieldModulus, threshold, numberOfShares) {
|
|
19364
|
-
const polynomial = generatePolynomialForSecretSharing(
|
|
19365
|
-
fieldModulus,
|
|
19366
|
-
secret,
|
|
19367
|
-
threshold
|
|
19368
|
-
);
|
|
19369
|
-
const shares = [];
|
|
19370
|
-
for (let i = 1; i <= numberOfShares; i++) {
|
|
19371
|
-
const share = evaluatePolynomial(polynomial, BigInt(i));
|
|
19372
|
-
shares.push({
|
|
19373
|
-
fieldModulus,
|
|
19374
|
-
threshold,
|
|
19375
|
-
index: BigInt(i),
|
|
19376
|
-
share,
|
|
19377
|
-
proofs: polynomial.proofs
|
|
19378
|
-
});
|
|
19379
|
-
}
|
|
19380
|
-
return shares;
|
|
19381
|
-
}
|
|
19382
|
-
function recoverSecret(shares) {
|
|
19383
|
-
if (shares.length === 0) return 0n;
|
|
19384
|
-
const threshold = shares[0]?.threshold;
|
|
19385
|
-
const fieldModulus = shares[0]?.fieldModulus;
|
|
19386
|
-
if (!threshold || !fieldModulus) {
|
|
19387
|
-
throw new ValidationError("Shares are not valid", {
|
|
19388
|
-
field: "shares",
|
|
19389
|
-
value: "Missing threshold or fieldModulus",
|
|
19390
|
-
expected: "Valid shares with threshold and fieldModulus"
|
|
19391
|
-
});
|
|
19392
|
-
}
|
|
19393
|
-
if (shares.length < threshold) {
|
|
19394
|
-
throw new ValidationError("Not enough shares to recover secret", {
|
|
19395
|
-
field: "shares",
|
|
19396
|
-
value: shares.length,
|
|
19397
|
-
expected: `At least ${threshold} shares`
|
|
19398
|
-
});
|
|
19399
|
-
}
|
|
19400
|
-
let result = 0n;
|
|
19401
|
-
for (const share of shares) {
|
|
19402
|
-
const coeff = computerLagrangeCoefficients(share.index, shares);
|
|
19403
|
-
const item = share.share * coeff % fieldModulus;
|
|
19404
|
-
result = (result + item) % fieldModulus;
|
|
19405
|
-
}
|
|
19406
|
-
return result;
|
|
19407
|
-
}
|
|
19408
|
-
function validateShare(share) {
|
|
19409
|
-
const targetPubkey = import_secp256k12.secp256k1.Point.fromPrivateKey(share.share).toBytes(
|
|
19410
|
-
true
|
|
19411
|
-
);
|
|
19412
|
-
let resultPubkey = share.proofs[0];
|
|
19413
|
-
if (!resultPubkey) {
|
|
19414
|
-
throw new ValidationError("Result pubkey is not valid", {
|
|
19415
|
-
field: "resultPubkey",
|
|
19416
|
-
value: "null",
|
|
19417
|
-
expected: "Valid public key bytes"
|
|
19418
|
-
});
|
|
19419
|
-
}
|
|
19420
|
-
for (let i = 1; i < share.proofs.length; i++) {
|
|
19421
|
-
const pubkey = share.proofs[i];
|
|
19422
|
-
if (!pubkey) {
|
|
19423
|
-
throw new ValidationError("Pubkey is not valid", {
|
|
19424
|
-
field: "pubkey",
|
|
19425
|
-
value: "null",
|
|
19426
|
-
expected: "Valid public key bytes"
|
|
19427
|
-
});
|
|
19428
|
-
}
|
|
19429
|
-
const value = share.index ** BigInt(i) % share.fieldModulus;
|
|
19430
|
-
const scaledPoint = import_secp256k12.secp256k1.Point.fromHex(pubkey).multiply(value);
|
|
19431
|
-
resultPubkey = import_secp256k12.secp256k1.Point.fromHex(resultPubkey).add(scaledPoint).toBytes(true);
|
|
19432
|
-
}
|
|
19433
|
-
if (!(0, import_utils3.equalBytes)(resultPubkey, targetPubkey)) {
|
|
19434
|
-
throw new ValidationError("Share is not valid", {
|
|
19435
|
-
field: "share",
|
|
19436
|
-
value: "Invalid proof",
|
|
19437
|
-
expected: "Valid share with matching proofs"
|
|
19438
|
-
});
|
|
19439
|
-
}
|
|
19440
|
-
}
|
|
19441
|
-
function bigIntToPrivateKey(value) {
|
|
19442
|
-
const hex = value.toString(16).padStart(64, "0");
|
|
19443
|
-
const bytes2 = new Uint8Array(32);
|
|
19444
|
-
for (let i = 0; i < 32; i++) {
|
|
19445
|
-
bytes2[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
19446
|
-
}
|
|
19447
|
-
return bytes2;
|
|
19448
|
-
}
|
|
19449
|
-
|
|
19450
|
-
// src/utils/signing.ts
|
|
19451
|
-
init_buffer();
|
|
19452
|
-
var import_secp256k13 = require("@noble/curves/secp256k1");
|
|
19453
|
-
function getRandomSigningNonce() {
|
|
19454
|
-
const binding = import_secp256k13.secp256k1.utils.randomPrivateKey();
|
|
19455
|
-
const hiding = import_secp256k13.secp256k1.utils.randomPrivateKey();
|
|
19456
|
-
return createSigningNonce(binding, hiding);
|
|
19457
|
-
}
|
|
19458
|
-
function createSigningNonce(binding, hiding) {
|
|
19459
|
-
if (binding.length !== 32 || hiding.length !== 32) {
|
|
19460
|
-
throw new ValidationError("Invalid nonce length", {
|
|
19461
|
-
field: "nonce",
|
|
19462
|
-
value: `binding: ${binding.length}, hiding: ${hiding.length}`,
|
|
19463
|
-
expected: "Both binding and hiding should be 32 bytes"
|
|
19464
|
-
});
|
|
19465
|
-
}
|
|
19466
|
-
return {
|
|
19467
|
-
binding,
|
|
19468
|
-
hiding
|
|
19469
|
-
};
|
|
19470
|
-
}
|
|
19471
|
-
function getSigningCommitmentFromNonce(nonce) {
|
|
19472
|
-
const bindingPubKey = import_secp256k13.secp256k1.getPublicKey(nonce.binding, true);
|
|
19473
|
-
const hidingPubKey = import_secp256k13.secp256k1.getPublicKey(nonce.hiding, true);
|
|
19474
|
-
return {
|
|
19475
|
-
binding: bindingPubKey,
|
|
19476
|
-
hiding: hidingPubKey
|
|
19477
|
-
};
|
|
19478
|
-
}
|
|
19479
|
-
function encodeSigningNonceToBytes(nonce) {
|
|
19480
|
-
return new Uint8Array([...nonce.binding, ...nonce.hiding]);
|
|
19481
|
-
}
|
|
19482
|
-
function decodeBytesToSigningNonce(bytes2) {
|
|
19483
|
-
if (bytes2.length !== 64) {
|
|
19484
|
-
throw new ValidationError("Invalid nonce length", {
|
|
19485
|
-
field: "bytes",
|
|
19486
|
-
value: bytes2.length,
|
|
19487
|
-
expected: "64 bytes (32 bytes for binding + 32 bytes for hiding)"
|
|
19488
|
-
});
|
|
19489
|
-
}
|
|
19490
|
-
return {
|
|
19491
|
-
binding: bytes2.slice(32, 64),
|
|
19492
|
-
hiding: bytes2.slice(0, 32)
|
|
19493
|
-
};
|
|
19494
|
-
}
|
|
19495
|
-
function createSigningCommitment(binding, hiding) {
|
|
19496
|
-
if (binding.length !== 33 || hiding.length !== 33) {
|
|
19497
|
-
throw new ValidationError("Invalid nonce commitment length", {
|
|
19498
|
-
field: "commitment",
|
|
19499
|
-
value: `binding: ${binding.length}, hiding: ${hiding.length}`,
|
|
19500
|
-
expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
|
|
19501
|
-
});
|
|
19502
|
-
}
|
|
19503
|
-
return {
|
|
19504
|
-
binding,
|
|
19505
|
-
hiding
|
|
19506
|
-
};
|
|
19507
|
-
}
|
|
19508
|
-
function encodeSigningCommitmentToBytes(commitment) {
|
|
19509
|
-
if (commitment.binding.length !== 33 || commitment.hiding.length !== 33) {
|
|
19510
|
-
throw new ValidationError("Invalid nonce commitment length", {
|
|
19511
|
-
field: "commitment",
|
|
19512
|
-
value: `binding: ${commitment.binding.length}, hiding: ${commitment.hiding.length}`,
|
|
19513
|
-
expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
|
|
19514
|
-
});
|
|
19515
|
-
}
|
|
19516
|
-
return new Uint8Array([...commitment.binding, ...commitment.hiding]);
|
|
19517
|
-
}
|
|
19518
|
-
function decodeBytesToSigningCommitment(bytes2) {
|
|
19519
|
-
if (bytes2.length !== 66) {
|
|
19520
|
-
throw new ValidationError("Invalid nonce commitment length", {
|
|
19521
|
-
field: "bytes",
|
|
19522
|
-
value: bytes2.length,
|
|
19523
|
-
expected: "66 bytes (33 bytes for binding + 33 bytes for hiding)"
|
|
19524
|
-
});
|
|
19525
|
-
}
|
|
19353
|
+
const pubkeys = [
|
|
19354
|
+
"0322ca18fc489ae25418a0e768273c2c61cabb823edfb14feb891e9bec62016510",
|
|
19355
|
+
"0341727a6c41b168f07eb50865ab8c397a53c7eef628ac1020956b705e43b6cb27",
|
|
19356
|
+
"0305ab8d485cc752394de4981f8a5ae004f2becfea6f432c9a59d5022d8764f0a6",
|
|
19357
|
+
"0352aef4d49439dedd798ac4aef1e7ebef95f569545b647a25338398c1247ffdea",
|
|
19358
|
+
"02c05c88cc8fc181b1ba30006df6a4b0597de6490e24514fbdd0266d2b9cd3d0ba"
|
|
19359
|
+
];
|
|
19526
19360
|
return {
|
|
19527
|
-
|
|
19528
|
-
|
|
19361
|
+
"0000000000000000000000000000000000000000000000000000000000000001": {
|
|
19362
|
+
id: 0,
|
|
19363
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
19364
|
+
address: addresses[0],
|
|
19365
|
+
identityPublicKey: pubkeys[0]
|
|
19366
|
+
},
|
|
19367
|
+
"0000000000000000000000000000000000000000000000000000000000000002": {
|
|
19368
|
+
id: 1,
|
|
19369
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
19370
|
+
address: addresses[1],
|
|
19371
|
+
identityPublicKey: pubkeys[1]
|
|
19372
|
+
},
|
|
19373
|
+
"0000000000000000000000000000000000000000000000000000000000000003": {
|
|
19374
|
+
id: 2,
|
|
19375
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
19376
|
+
address: addresses[2],
|
|
19377
|
+
identityPublicKey: pubkeys[2]
|
|
19378
|
+
},
|
|
19379
|
+
"0000000000000000000000000000000000000000000000000000000000000004": {
|
|
19380
|
+
id: 3,
|
|
19381
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000004",
|
|
19382
|
+
address: addresses[3],
|
|
19383
|
+
identityPublicKey: pubkeys[3]
|
|
19384
|
+
},
|
|
19385
|
+
"0000000000000000000000000000000000000000000000000000000000000005": {
|
|
19386
|
+
id: 4,
|
|
19387
|
+
identifier: "0000000000000000000000000000000000000000000000000000000000000005",
|
|
19388
|
+
address: addresses[4],
|
|
19389
|
+
identityPublicKey: pubkeys[4]
|
|
19390
|
+
}
|
|
19529
19391
|
};
|
|
19530
19392
|
}
|
|
19531
19393
|
|
|
19532
|
-
// src/
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19394
|
+
// src/services/config.ts
|
|
19395
|
+
var WalletConfigService = class {
|
|
19396
|
+
config;
|
|
19397
|
+
signer;
|
|
19398
|
+
sspClientOptions;
|
|
19399
|
+
constructor(options = {}, signer) {
|
|
19400
|
+
const network = options?.network ?? "REGTEST";
|
|
19401
|
+
this.config = {
|
|
19402
|
+
...this.getDefaultConfig(Network2[network]),
|
|
19403
|
+
...options
|
|
19404
|
+
};
|
|
19405
|
+
this.signer = signer;
|
|
19406
|
+
this.sspClientOptions = this.config.sspClientOptions;
|
|
19543
19407
|
}
|
|
19544
|
-
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
19550
|
-
|
|
19551
|
-
|
|
19552
|
-
field: "hdkey",
|
|
19553
|
-
value: seed
|
|
19554
|
-
});
|
|
19408
|
+
getDefaultConfig(network) {
|
|
19409
|
+
switch (network) {
|
|
19410
|
+
case 0 /* MAINNET */:
|
|
19411
|
+
return WalletConfig.MAINNET;
|
|
19412
|
+
case 3 /* REGTEST */:
|
|
19413
|
+
return WalletConfig.REGTEST;
|
|
19414
|
+
default:
|
|
19415
|
+
return WalletConfig.LOCAL;
|
|
19555
19416
|
}
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
const
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
|
|
19562
|
-
"Failed to derive all required keys from seed",
|
|
19417
|
+
}
|
|
19418
|
+
getCoordinatorAddress() {
|
|
19419
|
+
const coordinator = this.config.signingOperators[this.config.coordinatorIdentifier];
|
|
19420
|
+
if (!coordinator) {
|
|
19421
|
+
throw new ConfigurationError(
|
|
19422
|
+
"Coordinator not found in signing operators",
|
|
19563
19423
|
{
|
|
19564
|
-
|
|
19424
|
+
configKey: "signingOperators"
|
|
19565
19425
|
}
|
|
19566
19426
|
);
|
|
19567
19427
|
}
|
|
19568
|
-
return
|
|
19569
|
-
identityKey: {
|
|
19570
|
-
privateKey: identityKey.privateKey,
|
|
19571
|
-
publicKey: identityKey.publicKey
|
|
19572
|
-
},
|
|
19573
|
-
signingHDKey: {
|
|
19574
|
-
hdKey: signingKey,
|
|
19575
|
-
privateKey: signingKey.privateKey,
|
|
19576
|
-
publicKey: signingKey.publicKey
|
|
19577
|
-
},
|
|
19578
|
-
depositKey: {
|
|
19579
|
-
privateKey: depositKey.privateKey,
|
|
19580
|
-
publicKey: depositKey.publicKey
|
|
19581
|
-
},
|
|
19582
|
-
staticDepositHDKey: {
|
|
19583
|
-
hdKey: staticDepositKey,
|
|
19584
|
-
privateKey: staticDepositKey.privateKey,
|
|
19585
|
-
publicKey: staticDepositKey.publicKey
|
|
19586
|
-
}
|
|
19587
|
-
};
|
|
19428
|
+
return coordinator.address;
|
|
19588
19429
|
}
|
|
19589
|
-
|
|
19590
|
-
|
|
19591
|
-
identityKey = null;
|
|
19592
|
-
signingKey = null;
|
|
19593
|
-
depositKey = null;
|
|
19594
|
-
staticDepositKey = null;
|
|
19595
|
-
commitmentToNonceMap = /* @__PURE__ */ new Map();
|
|
19596
|
-
keysGenerator;
|
|
19597
|
-
constructor({
|
|
19598
|
-
sparkKeysGenerator
|
|
19599
|
-
} = {}) {
|
|
19600
|
-
this.keysGenerator = sparkKeysGenerator ?? new DefaultSparkKeysGenerator();
|
|
19430
|
+
getSigningOperators() {
|
|
19431
|
+
return this.config.signingOperators;
|
|
19601
19432
|
}
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
throw new ValidationError("Private key not initialized", {
|
|
19605
|
-
field: "signingKey"
|
|
19606
|
-
});
|
|
19607
|
-
}
|
|
19608
|
-
const view = new DataView(hash.buffer);
|
|
19609
|
-
const amount = view.getUint32(0, false) % HARDENED_OFFSET + HARDENED_OFFSET;
|
|
19610
|
-
const newPrivateKey = this.signingKey?.deriveChild(amount).privateKey;
|
|
19611
|
-
if (!newPrivateKey) {
|
|
19612
|
-
throw new ValidationError("Failed to recover signing key", {
|
|
19613
|
-
field: "privateKey"
|
|
19614
|
-
});
|
|
19615
|
-
}
|
|
19616
|
-
return newPrivateKey;
|
|
19433
|
+
getThreshold() {
|
|
19434
|
+
return this.config.threshold;
|
|
19617
19435
|
}
|
|
19618
|
-
|
|
19619
|
-
|
|
19620
|
-
throw new ConfigurationError("Identity key not initialized", {
|
|
19621
|
-
configKey: "identityKey"
|
|
19622
|
-
});
|
|
19623
|
-
}
|
|
19624
|
-
const receiverEciesPrivKey = ecies.PrivateKey.fromHex(
|
|
19625
|
-
(0, import_utils5.bytesToHex)(this.identityKey.privateKey)
|
|
19626
|
-
);
|
|
19627
|
-
const privateKey = ecies.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
|
|
19628
|
-
return privateKey;
|
|
19436
|
+
getCoordinatorIdentifier() {
|
|
19437
|
+
return this.config.coordinatorIdentifier;
|
|
19629
19438
|
}
|
|
19630
|
-
|
|
19631
|
-
|
|
19632
|
-
case "leaf" /* LEAF */:
|
|
19633
|
-
return this.deriveSigningKey((0, import_sha22.sha256)(keyDerivation.path));
|
|
19634
|
-
case "deposit" /* DEPOSIT */:
|
|
19635
|
-
return this.depositKey?.privateKey ?? new Uint8Array();
|
|
19636
|
-
case "static_deposit" /* STATIC_DEPOSIT */:
|
|
19637
|
-
return this.getStaticDepositSecretKey(keyDerivation.path);
|
|
19638
|
-
case "ecies" /* ECIES */:
|
|
19639
|
-
return this.decryptEciesToPrivateKey(keyDerivation.path);
|
|
19640
|
-
case "random" /* RANDOM */:
|
|
19641
|
-
return import_secp256k15.secp256k1.utils.randomPrivateKey();
|
|
19642
|
-
}
|
|
19439
|
+
getExpectedWithdrawBondSats() {
|
|
19440
|
+
return this.config.expectedWithdrawBondSats;
|
|
19643
19441
|
}
|
|
19644
|
-
|
|
19645
|
-
|
|
19646
|
-
throw new ValidationError("Private key not set", {
|
|
19647
|
-
field: "identityKey"
|
|
19648
|
-
});
|
|
19649
|
-
}
|
|
19650
|
-
const signature = import_secp256k15.schnorr.sign(message, this.identityKey.privateKey);
|
|
19651
|
-
return signature;
|
|
19442
|
+
getExpectedWithdrawRelativeBlockLocktime() {
|
|
19443
|
+
return this.config.expectedWithdrawRelativeBlockLocktime;
|
|
19652
19444
|
}
|
|
19653
|
-
|
|
19654
|
-
if (
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19445
|
+
getSspNetwork() {
|
|
19446
|
+
if (this.config.network === "MAINNET") {
|
|
19447
|
+
return "MAINNET" /* MAINNET */;
|
|
19448
|
+
} else if (this.config.network === "REGTEST") {
|
|
19449
|
+
return "REGTEST" /* REGTEST */;
|
|
19450
|
+
} else if (this.config.network === "TESTNET") {
|
|
19451
|
+
return "TESTNET" /* TESTNET */;
|
|
19452
|
+
} else if (this.config.network === "SIGNET") {
|
|
19453
|
+
return "SIGNET" /* SIGNET */;
|
|
19658
19454
|
}
|
|
19659
|
-
return
|
|
19455
|
+
return "FUTURE_VALUE" /* FUTURE_VALUE */;
|
|
19660
19456
|
}
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
throw new ValidationError("Deposit key is not set", {
|
|
19664
|
-
field: "depositKey"
|
|
19665
|
-
});
|
|
19666
|
-
}
|
|
19667
|
-
return this.depositKey.publicKey;
|
|
19457
|
+
getNetwork() {
|
|
19458
|
+
return Network2[this.config.network];
|
|
19668
19459
|
}
|
|
19669
|
-
|
|
19670
|
-
|
|
19671
|
-
return import_secp256k15.secp256k1.getPublicKey(staticDepositKey);
|
|
19460
|
+
getNetworkType() {
|
|
19461
|
+
return this.config.network;
|
|
19672
19462
|
}
|
|
19673
|
-
|
|
19674
|
-
|
|
19675
|
-
throw new ValidationError("Static deposit key is not set", {
|
|
19676
|
-
field: "staticDepositKey"
|
|
19677
|
-
});
|
|
19678
|
-
}
|
|
19679
|
-
const staticDepositKey = this.staticDepositKey.deriveChild(
|
|
19680
|
-
HARDENED_OFFSET + idx
|
|
19681
|
-
);
|
|
19682
|
-
if (!staticDepositKey?.privateKey) {
|
|
19683
|
-
throw new ValidationError("Static deposit key is not set", {
|
|
19684
|
-
field: "staticDepositKey"
|
|
19685
|
-
});
|
|
19686
|
-
}
|
|
19687
|
-
return staticDepositKey.privateKey;
|
|
19463
|
+
getNetworkProto() {
|
|
19464
|
+
return NetworkToProto[Network2[this.config.network]];
|
|
19688
19465
|
}
|
|
19689
|
-
|
|
19690
|
-
return
|
|
19466
|
+
getTokenSignatures() {
|
|
19467
|
+
return this.config.tokenSignatures;
|
|
19691
19468
|
}
|
|
19692
|
-
|
|
19693
|
-
return
|
|
19469
|
+
getTokenValidityDurationSeconds() {
|
|
19470
|
+
return this.config.tokenValidityDurationSeconds;
|
|
19694
19471
|
}
|
|
19695
|
-
|
|
19696
|
-
|
|
19697
|
-
return import_secp256k15.secp256k1.getPublicKey(privateKey);
|
|
19472
|
+
getElectrsUrl() {
|
|
19473
|
+
return this.config.electrsUrl;
|
|
19698
19474
|
}
|
|
19699
|
-
|
|
19700
|
-
|
|
19701
|
-
const secondPrivateKey = this.deriveSigningKey((0, import_sha22.sha256)(second));
|
|
19702
|
-
const resultPrivKey = subtractPrivateKeys(
|
|
19703
|
-
firstPrivateKey,
|
|
19704
|
-
secondPrivateKey
|
|
19705
|
-
);
|
|
19706
|
-
const resultPubKey = import_secp256k15.secp256k1.getPublicKey(resultPrivKey);
|
|
19707
|
-
return resultPubKey;
|
|
19475
|
+
getSspBaseUrl() {
|
|
19476
|
+
return this.config.sspClientOptions.baseUrl;
|
|
19708
19477
|
}
|
|
19709
|
-
|
|
19710
|
-
|
|
19711
|
-
second,
|
|
19712
|
-
curveOrder,
|
|
19713
|
-
threshold,
|
|
19714
|
-
numShares
|
|
19715
|
-
}) {
|
|
19716
|
-
const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
|
|
19717
|
-
const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
|
|
19718
|
-
const resultPrivKey = subtractPrivateKeys(
|
|
19719
|
-
firstPrivateKey,
|
|
19720
|
-
secondPrivateKey
|
|
19721
|
-
);
|
|
19722
|
-
return await this.splitSecretWithProofs({
|
|
19723
|
-
secret: resultPrivKey,
|
|
19724
|
-
curveOrder,
|
|
19725
|
-
threshold,
|
|
19726
|
-
numShares
|
|
19727
|
-
});
|
|
19478
|
+
getSspIdentityPublicKey() {
|
|
19479
|
+
return this.config.sspClientOptions.identityPublicKey;
|
|
19728
19480
|
}
|
|
19729
|
-
|
|
19730
|
-
first,
|
|
19731
|
-
second,
|
|
19732
|
-
curveOrder,
|
|
19733
|
-
threshold,
|
|
19734
|
-
numShares,
|
|
19735
|
-
receiverPublicKey
|
|
19736
|
-
}) {
|
|
19737
|
-
const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
|
|
19738
|
-
const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
|
|
19739
|
-
const resultPrivKey = subtractPrivateKeys(
|
|
19740
|
-
firstPrivateKey,
|
|
19741
|
-
secondPrivateKey
|
|
19742
|
-
);
|
|
19481
|
+
getConsoleOptions() {
|
|
19743
19482
|
return {
|
|
19744
|
-
|
|
19745
|
-
secret: resultPrivKey,
|
|
19746
|
-
curveOrder,
|
|
19747
|
-
threshold,
|
|
19748
|
-
numShares
|
|
19749
|
-
}),
|
|
19750
|
-
secretCipher: ecies.encrypt(receiverPublicKey, secondPrivateKey)
|
|
19483
|
+
...this.config.console
|
|
19751
19484
|
};
|
|
19752
19485
|
}
|
|
19753
|
-
|
|
19754
|
-
|
|
19755
|
-
|
|
19756
|
-
|
|
19757
|
-
|
|
19758
|
-
|
|
19759
|
-
|
|
19760
|
-
|
|
19761
|
-
|
|
19762
|
-
|
|
19763
|
-
|
|
19764
|
-
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
|
|
19768
|
-
|
|
19769
|
-
|
|
19770
|
-
}) {
|
|
19771
|
-
const SparkFrost = await getSparkFrostModule();
|
|
19772
|
-
if (!SparkFrost) {
|
|
19773
|
-
throw new ValidationError("SparkFrost module not found", {
|
|
19774
|
-
field: "SparkFrost"
|
|
19775
|
-
});
|
|
19486
|
+
};
|
|
19487
|
+
|
|
19488
|
+
// src/services/connection/connection.ts
|
|
19489
|
+
init_buffer();
|
|
19490
|
+
var import_core10 = require("@lightsparkdev/core");
|
|
19491
|
+
var import_sha22 = require("@noble/hashes/sha2");
|
|
19492
|
+
|
|
19493
|
+
// src/proto/spark_authn.ts
|
|
19494
|
+
init_buffer();
|
|
19495
|
+
var import_wire5 = require("@bufbuild/protobuf/wire");
|
|
19496
|
+
function createBaseChallenge() {
|
|
19497
|
+
return { version: 0, timestamp: 0, nonce: new Uint8Array(0), publicKey: new Uint8Array(0) };
|
|
19498
|
+
}
|
|
19499
|
+
var Challenge = {
|
|
19500
|
+
encode(message, writer = new import_wire5.BinaryWriter()) {
|
|
19501
|
+
if (message.version !== 0) {
|
|
19502
|
+
writer.uint32(8).int32(message.version);
|
|
19776
19503
|
}
|
|
19777
|
-
|
|
19778
|
-
|
|
19779
|
-
throw new ValidationError("Private key not found for public key", {
|
|
19780
|
-
field: "privateKey"
|
|
19781
|
-
});
|
|
19504
|
+
if (message.timestamp !== 0) {
|
|
19505
|
+
writer.uint32(16).int64(message.timestamp);
|
|
19782
19506
|
}
|
|
19783
|
-
|
|
19784
|
-
|
|
19785
|
-
if (!nonce) {
|
|
19786
|
-
throw new ValidationError("Nonce not found for commitment", {
|
|
19787
|
-
field: "nonce"
|
|
19788
|
-
});
|
|
19789
|
-
}
|
|
19790
|
-
const keyPackage = {
|
|
19791
|
-
secretKey: signingPrivateKey,
|
|
19792
|
-
publicKey,
|
|
19793
|
-
verifyingKey
|
|
19794
|
-
};
|
|
19795
|
-
const logMessage = (0, import_utils5.bytesToHex)(message);
|
|
19796
|
-
const result = await SparkFrost.signFrost({
|
|
19797
|
-
message,
|
|
19798
|
-
keyPackage,
|
|
19799
|
-
nonce,
|
|
19800
|
-
selfCommitment: commitment,
|
|
19801
|
-
statechainCommitments,
|
|
19802
|
-
adaptorPubKey
|
|
19803
|
-
});
|
|
19804
|
-
return result;
|
|
19805
|
-
}
|
|
19806
|
-
async aggregateFrost({
|
|
19807
|
-
message,
|
|
19808
|
-
publicKey,
|
|
19809
|
-
verifyingKey,
|
|
19810
|
-
selfCommitment,
|
|
19811
|
-
statechainCommitments,
|
|
19812
|
-
adaptorPubKey,
|
|
19813
|
-
selfSignature,
|
|
19814
|
-
statechainSignatures,
|
|
19815
|
-
statechainPublicKeys
|
|
19816
|
-
}) {
|
|
19817
|
-
const SparkFrost = await getSparkFrostModule();
|
|
19818
|
-
if (!SparkFrost) {
|
|
19819
|
-
throw new ValidationError("SparkFrost module not found", {
|
|
19820
|
-
field: "SparkFrost"
|
|
19821
|
-
});
|
|
19822
|
-
}
|
|
19823
|
-
return SparkFrost.aggregateFrost({
|
|
19824
|
-
message,
|
|
19825
|
-
statechainSignatures,
|
|
19826
|
-
statechainPublicKeys,
|
|
19827
|
-
verifyingKey,
|
|
19828
|
-
statechainCommitments,
|
|
19829
|
-
selfCommitment: selfCommitment.commitment,
|
|
19830
|
-
selfPublicKey: publicKey,
|
|
19831
|
-
selfSignature,
|
|
19832
|
-
adaptorPubKey
|
|
19833
|
-
});
|
|
19834
|
-
}
|
|
19835
|
-
async createSparkWalletFromSeed(seed, accountNumber) {
|
|
19836
|
-
if (typeof seed === "string") {
|
|
19837
|
-
seed = (0, import_utils5.hexToBytes)(seed);
|
|
19838
|
-
}
|
|
19839
|
-
const {
|
|
19840
|
-
identityKey,
|
|
19841
|
-
signingHDKey: signingKey,
|
|
19842
|
-
depositKey,
|
|
19843
|
-
staticDepositHDKey: staticDepositKey
|
|
19844
|
-
} = await this.keysGenerator.deriveKeysFromSeed(seed, accountNumber ?? 0);
|
|
19845
|
-
this.identityKey = identityKey;
|
|
19846
|
-
this.depositKey = depositKey;
|
|
19847
|
-
this.signingKey = signingKey.hdKey;
|
|
19848
|
-
this.staticDepositKey = staticDepositKey.hdKey;
|
|
19849
|
-
return (0, import_utils5.bytesToHex)(identityKey.publicKey);
|
|
19850
|
-
}
|
|
19851
|
-
async signMessageWithIdentityKey(message, compact) {
|
|
19852
|
-
if (!this.identityKey?.privateKey) {
|
|
19853
|
-
throw new ConfigurationError("Identity key not initialized", {
|
|
19854
|
-
configKey: "identityKey"
|
|
19855
|
-
});
|
|
19856
|
-
}
|
|
19857
|
-
const signature = import_secp256k15.secp256k1.sign(message, this.identityKey.privateKey);
|
|
19858
|
-
if (compact) {
|
|
19859
|
-
return signature.toCompactRawBytes();
|
|
19860
|
-
}
|
|
19861
|
-
return signature.toDERRawBytes();
|
|
19862
|
-
}
|
|
19863
|
-
async decryptEcies(ciphertext) {
|
|
19864
|
-
if (!this.identityKey?.privateKey) {
|
|
19865
|
-
throw new ConfigurationError("Identity key not initialized", {
|
|
19866
|
-
configKey: "identityKey"
|
|
19867
|
-
});
|
|
19868
|
-
}
|
|
19869
|
-
const receiverEciesPrivKey = ecies.PrivateKey.fromHex(
|
|
19870
|
-
(0, import_utils5.bytesToHex)(this.identityKey.privateKey)
|
|
19871
|
-
);
|
|
19872
|
-
const privateKey = ecies.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
|
|
19873
|
-
const publicKey = import_secp256k15.secp256k1.getPublicKey(privateKey);
|
|
19874
|
-
return publicKey;
|
|
19875
|
-
}
|
|
19876
|
-
async getRandomSigningCommitment() {
|
|
19877
|
-
const nonce = getRandomSigningNonce();
|
|
19878
|
-
const commitment = getSigningCommitmentFromNonce(nonce);
|
|
19879
|
-
this.commitmentToNonceMap.set(commitment, nonce);
|
|
19880
|
-
return {
|
|
19881
|
-
commitment
|
|
19882
|
-
};
|
|
19883
|
-
}
|
|
19884
|
-
async validateMessageWithIdentityKey(message, signature) {
|
|
19885
|
-
if (!this.identityKey?.publicKey) {
|
|
19886
|
-
throw new ConfigurationError("Identity key not initialized", {
|
|
19887
|
-
configKey: "identityKey"
|
|
19888
|
-
});
|
|
19889
|
-
}
|
|
19890
|
-
return import_secp256k15.secp256k1.verify(signature, message, this.identityKey.publicKey);
|
|
19891
|
-
}
|
|
19892
|
-
signTransactionIndex(tx, index, publicKey) {
|
|
19893
|
-
let privateKey;
|
|
19894
|
-
if ((0, import_utils5.equalBytes)(publicKey, this.identityKey?.publicKey ?? new Uint8Array())) {
|
|
19895
|
-
privateKey = this.identityKey?.privateKey;
|
|
19896
|
-
} else if ((0, import_utils5.equalBytes)(publicKey, this.depositKey?.publicKey ?? new Uint8Array())) {
|
|
19897
|
-
privateKey = this.depositKey?.privateKey;
|
|
19898
|
-
}
|
|
19899
|
-
if (!privateKey) {
|
|
19900
|
-
throw new ValidationError("Private key not found for public key", {
|
|
19901
|
-
field: "privateKey",
|
|
19902
|
-
value: (0, import_utils5.bytesToHex)(publicKey)
|
|
19903
|
-
});
|
|
19904
|
-
}
|
|
19905
|
-
tx.signIdx(privateKey, index);
|
|
19906
|
-
}
|
|
19907
|
-
};
|
|
19908
|
-
|
|
19909
|
-
// src/utils/network.ts
|
|
19910
|
-
init_buffer();
|
|
19911
|
-
var btc = __toESM(require("@scure/btc-signer"), 1);
|
|
19912
|
-
var import_base2 = require("@scure/base");
|
|
19913
|
-
var Network2 = /* @__PURE__ */ ((Network5) => {
|
|
19914
|
-
Network5[Network5["MAINNET"] = 0] = "MAINNET";
|
|
19915
|
-
Network5[Network5["TESTNET"] = 1] = "TESTNET";
|
|
19916
|
-
Network5[Network5["SIGNET"] = 2] = "SIGNET";
|
|
19917
|
-
Network5[Network5["REGTEST"] = 3] = "REGTEST";
|
|
19918
|
-
Network5[Network5["LOCAL"] = 4] = "LOCAL";
|
|
19919
|
-
return Network5;
|
|
19920
|
-
})(Network2 || {});
|
|
19921
|
-
var NetworkToProto = {
|
|
19922
|
-
[0 /* MAINNET */]: 1 /* MAINNET */,
|
|
19923
|
-
[1 /* TESTNET */]: 3 /* TESTNET */,
|
|
19924
|
-
[2 /* SIGNET */]: 4 /* SIGNET */,
|
|
19925
|
-
[3 /* REGTEST */]: 2 /* REGTEST */,
|
|
19926
|
-
[4 /* LOCAL */]: 2 /* REGTEST */
|
|
19927
|
-
};
|
|
19928
|
-
var protoToNetwork = (protoNetwork) => {
|
|
19929
|
-
switch (protoNetwork) {
|
|
19930
|
-
case 1 /* MAINNET */:
|
|
19931
|
-
return 0 /* MAINNET */;
|
|
19932
|
-
case 3 /* TESTNET */:
|
|
19933
|
-
return 1 /* TESTNET */;
|
|
19934
|
-
case 4 /* SIGNET */:
|
|
19935
|
-
return 2 /* SIGNET */;
|
|
19936
|
-
case 2 /* REGTEST */:
|
|
19937
|
-
return 3 /* REGTEST */;
|
|
19938
|
-
default:
|
|
19939
|
-
return void 0;
|
|
19940
|
-
}
|
|
19941
|
-
};
|
|
19942
|
-
var NetworkConfig = {
|
|
19943
|
-
[0 /* MAINNET */]: btc.NETWORK,
|
|
19944
|
-
[1 /* TESTNET */]: btc.TEST_NETWORK,
|
|
19945
|
-
[2 /* SIGNET */]: btc.TEST_NETWORK,
|
|
19946
|
-
[3 /* REGTEST */]: { ...btc.TEST_NETWORK, bech32: "bcrt" },
|
|
19947
|
-
[4 /* LOCAL */]: { ...btc.TEST_NETWORK, bech32: "bcrt" }
|
|
19948
|
-
};
|
|
19949
|
-
var getNetwork = (network) => NetworkConfig[network];
|
|
19950
|
-
function getNetworkFromAddress(address) {
|
|
19951
|
-
try {
|
|
19952
|
-
const bechAddress = address;
|
|
19953
|
-
const decoded = (() => {
|
|
19954
|
-
try {
|
|
19955
|
-
return import_base2.bech32.decode(bechAddress);
|
|
19956
|
-
} catch (_) {
|
|
19957
|
-
return import_base2.bech32m.decode(bechAddress);
|
|
19958
|
-
}
|
|
19959
|
-
})();
|
|
19960
|
-
if (decoded.prefix === "bc") {
|
|
19961
|
-
return "MAINNET" /* MAINNET */;
|
|
19962
|
-
} else if (decoded.prefix === "bcrt") {
|
|
19963
|
-
return "REGTEST" /* REGTEST */;
|
|
19964
|
-
}
|
|
19965
|
-
} catch (err) {
|
|
19966
|
-
throw new ValidationError(
|
|
19967
|
-
"Invalid Bitcoin address",
|
|
19968
|
-
{
|
|
19969
|
-
field: "address",
|
|
19970
|
-
value: address,
|
|
19971
|
-
expected: "Valid Bech32 address with prefix 'bc' or 'bcrt'"
|
|
19972
|
-
},
|
|
19973
|
-
err instanceof Error ? err : void 0
|
|
19974
|
-
);
|
|
19975
|
-
}
|
|
19976
|
-
return null;
|
|
19977
|
-
}
|
|
19978
|
-
function getNetworkFromString(network) {
|
|
19979
|
-
const net = (network ?? "REGTEST").toUpperCase();
|
|
19980
|
-
if (net === "MAINNET") return 0 /* MAINNET */;
|
|
19981
|
-
if (net === "TESTNET") return 1 /* TESTNET */;
|
|
19982
|
-
if (net === "SIGNET") return 2 /* SIGNET */;
|
|
19983
|
-
if (net === "LOCAL") return 4 /* LOCAL */;
|
|
19984
|
-
return 3 /* REGTEST */;
|
|
19985
|
-
}
|
|
19986
|
-
|
|
19987
|
-
// src/services/wallet-config.ts
|
|
19988
|
-
init_buffer();
|
|
19989
|
-
|
|
19990
|
-
// src/tests/isHermeticTest.ts
|
|
19991
|
-
init_buffer();
|
|
19992
|
-
var isHermeticTest = Boolean(
|
|
19993
|
-
typeof process !== "undefined" && process?.env?.HERMETIC_TEST === "true"
|
|
19994
|
-
);
|
|
19995
|
-
|
|
19996
|
-
// src/services/wallet-config.ts
|
|
19997
|
-
var SSP_IDENTITY_PUBLIC_KEYS = {
|
|
19998
|
-
LOCAL: "028c094a432d46a0ac95349d792c2e3730bd60c29188db716f56a99e39b95338b4",
|
|
19999
|
-
REGTEST: {
|
|
20000
|
-
PROD: "022bf283544b16c0622daecb79422007d167eca6ce9f0c98c0c49833b1f7170bfe"
|
|
20001
|
-
},
|
|
20002
|
-
MAINNET: {
|
|
20003
|
-
PROD: "023e33e2920326f64ea31058d44777442d97d7d5cbfcf54e3060bc1695e5261c93"
|
|
20004
|
-
}
|
|
20005
|
-
};
|
|
20006
|
-
var URL_CONFIG = {
|
|
20007
|
-
LOCAL: {
|
|
20008
|
-
SSP: "http://127.0.0.1:5000",
|
|
20009
|
-
ELECTRS: "http://127.0.0.1:30000"
|
|
20010
|
-
},
|
|
20011
|
-
REGTEST: {
|
|
20012
|
-
PROD: {
|
|
20013
|
-
SSP: "https://api.lightspark.com",
|
|
20014
|
-
ELECTRS: "https://regtest-mempool.us-west-2.sparkinfra.net/api"
|
|
20015
|
-
}
|
|
20016
|
-
},
|
|
20017
|
-
MAINNET: {
|
|
20018
|
-
PROD: {
|
|
20019
|
-
SSP: "https://api.lightspark.com",
|
|
20020
|
-
ELECTRS: "https://mempool.space/api"
|
|
20021
|
-
}
|
|
20022
|
-
}
|
|
20023
|
-
};
|
|
20024
|
-
var ELECTRS_CREDENTIALS = {
|
|
20025
|
-
username: "spark-sdk",
|
|
20026
|
-
password: "mCMk1JqlBNtetUNy"
|
|
20027
|
-
};
|
|
20028
|
-
function getElectrsUrl(network) {
|
|
20029
|
-
switch (network) {
|
|
20030
|
-
case "LOCAL":
|
|
20031
|
-
return isHermeticTest ? "http://mempool.minikube.local/api" : URL_CONFIG.LOCAL.ELECTRS;
|
|
20032
|
-
case "REGTEST":
|
|
20033
|
-
return URL_CONFIG.REGTEST.PROD.ELECTRS;
|
|
20034
|
-
case "MAINNET":
|
|
20035
|
-
return URL_CONFIG.MAINNET.PROD.ELECTRS;
|
|
20036
|
-
default:
|
|
20037
|
-
return URL_CONFIG.LOCAL.ELECTRS;
|
|
20038
|
-
}
|
|
20039
|
-
}
|
|
20040
|
-
function getSspIdentityPublicKey(network) {
|
|
20041
|
-
switch (network) {
|
|
20042
|
-
case "LOCAL":
|
|
20043
|
-
return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
|
|
20044
|
-
case "REGTEST":
|
|
20045
|
-
return SSP_IDENTITY_PUBLIC_KEYS.REGTEST.PROD;
|
|
20046
|
-
case "MAINNET":
|
|
20047
|
-
return SSP_IDENTITY_PUBLIC_KEYS.MAINNET.PROD;
|
|
20048
|
-
default:
|
|
20049
|
-
return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
|
|
20050
|
-
}
|
|
20051
|
-
}
|
|
20052
|
-
function getSspUrl(network) {
|
|
20053
|
-
switch (network) {
|
|
20054
|
-
case "LOCAL":
|
|
20055
|
-
return isHermeticTest ? "http://app.minikube.local" : URL_CONFIG.LOCAL.SSP;
|
|
20056
|
-
case "REGTEST":
|
|
20057
|
-
return URL_CONFIG.REGTEST.PROD.SSP;
|
|
20058
|
-
case "MAINNET":
|
|
20059
|
-
return URL_CONFIG.MAINNET.PROD.SSP;
|
|
20060
|
-
default:
|
|
20061
|
-
return URL_CONFIG.LOCAL.SSP;
|
|
20062
|
-
}
|
|
20063
|
-
}
|
|
20064
|
-
function getSspSchemaEndpoint(network) {
|
|
20065
|
-
switch (network) {
|
|
20066
|
-
case "LOCAL":
|
|
20067
|
-
return "graphql/spark/rc";
|
|
20068
|
-
}
|
|
20069
|
-
return;
|
|
20070
|
-
}
|
|
20071
|
-
var PROD_PUBKEYS = [
|
|
20072
|
-
"03dfbdff4b6332c220f8fa2ba8ed496c698ceada563fa01b67d9983bfc5c95e763",
|
|
20073
|
-
"03e625e9768651c9be268e287245cc33f96a68ce9141b0b4769205db027ee8ed77",
|
|
20074
|
-
"022eda13465a59205413086130a65dc0ed1b8f8e51937043161f8be0c369b1a410"
|
|
20075
|
-
];
|
|
20076
|
-
function getLocalFrostSignerAddress() {
|
|
20077
|
-
return isHermeticTest ? "localhost:9999" : "unix:///tmp/frost_0.sock";
|
|
20078
|
-
}
|
|
20079
|
-
var BASE_CONFIG = {
|
|
20080
|
-
network: "LOCAL",
|
|
20081
|
-
coordinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
20082
|
-
frostSignerAddress: getLocalFrostSignerAddress(),
|
|
20083
|
-
threshold: 2,
|
|
20084
|
-
signingOperators: getLocalSigningOperators(),
|
|
20085
|
-
tokenSignatures: "SCHNORR",
|
|
20086
|
-
tokenValidityDurationSeconds: 180,
|
|
20087
|
-
electrsUrl: getElectrsUrl("LOCAL"),
|
|
20088
|
-
expectedWithdrawBondSats: 1e4,
|
|
20089
|
-
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
20090
|
-
sspClientOptions: {
|
|
20091
|
-
baseUrl: getSspUrl("LOCAL"),
|
|
20092
|
-
identityPublicKey: getSspIdentityPublicKey("LOCAL"),
|
|
20093
|
-
schemaEndpoint: getSspSchemaEndpoint("LOCAL")
|
|
20094
|
-
},
|
|
20095
|
-
signerWithPreExistingKeys: false,
|
|
20096
|
-
console: {
|
|
20097
|
-
otel: false
|
|
20098
|
-
}
|
|
20099
|
-
};
|
|
20100
|
-
var LOCAL_WALLET_CONFIG = {
|
|
20101
|
-
...BASE_CONFIG,
|
|
20102
|
-
threshold: 3
|
|
20103
|
-
};
|
|
20104
|
-
var LOCAL_WALLET_CONFIG_SCHNORR = {
|
|
20105
|
-
...LOCAL_WALLET_CONFIG,
|
|
20106
|
-
threshold: 3
|
|
20107
|
-
// 3 for issuance tests.
|
|
20108
|
-
};
|
|
20109
|
-
var LOCAL_WALLET_CONFIG_ECDSA = {
|
|
20110
|
-
...LOCAL_WALLET_CONFIG,
|
|
20111
|
-
tokenSignatures: "ECDSA",
|
|
20112
|
-
threshold: 3
|
|
20113
|
-
// 3 for issuance tests.
|
|
20114
|
-
};
|
|
20115
|
-
var REGTEST_WALLET_CONFIG = {
|
|
20116
|
-
...BASE_CONFIG,
|
|
20117
|
-
network: "REGTEST",
|
|
20118
|
-
signingOperators: getSigningOperators(),
|
|
20119
|
-
electrsUrl: getElectrsUrl("REGTEST"),
|
|
20120
|
-
expectedWithdrawBondSats: 1e4,
|
|
20121
|
-
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
20122
|
-
sspClientOptions: {
|
|
20123
|
-
baseUrl: getSspUrl("REGTEST"),
|
|
20124
|
-
identityPublicKey: getSspIdentityPublicKey("REGTEST")
|
|
20125
|
-
}
|
|
20126
|
-
};
|
|
20127
|
-
var MAINNET_WALLET_CONFIG = {
|
|
20128
|
-
...BASE_CONFIG,
|
|
20129
|
-
network: "MAINNET",
|
|
20130
|
-
signingOperators: getSigningOperators(),
|
|
20131
|
-
electrsUrl: getElectrsUrl("MAINNET"),
|
|
20132
|
-
expectedWithdrawBondSats: 1e4,
|
|
20133
|
-
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
20134
|
-
sspClientOptions: {
|
|
20135
|
-
baseUrl: getSspUrl("MAINNET"),
|
|
20136
|
-
identityPublicKey: getSspIdentityPublicKey("MAINNET")
|
|
20137
|
-
}
|
|
20138
|
-
};
|
|
20139
|
-
var WalletConfig = {
|
|
20140
|
-
LOCAL: LOCAL_WALLET_CONFIG,
|
|
20141
|
-
LOCAL_SCHNORR: LOCAL_WALLET_CONFIG_SCHNORR,
|
|
20142
|
-
LOCAL_ECDSA: LOCAL_WALLET_CONFIG_ECDSA,
|
|
20143
|
-
REGTEST: REGTEST_WALLET_CONFIG,
|
|
20144
|
-
MAINNET: MAINNET_WALLET_CONFIG
|
|
20145
|
-
};
|
|
20146
|
-
function getSigningOperators() {
|
|
20147
|
-
return {
|
|
20148
|
-
"0000000000000000000000000000000000000000000000000000000000000001": {
|
|
20149
|
-
id: 0,
|
|
20150
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
20151
|
-
address: "https://0.spark.lightspark.com",
|
|
20152
|
-
identityPublicKey: PROD_PUBKEYS[0]
|
|
20153
|
-
},
|
|
20154
|
-
"0000000000000000000000000000000000000000000000000000000000000002": {
|
|
20155
|
-
id: 1,
|
|
20156
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
20157
|
-
address: "https://1.spark.lightspark.com",
|
|
20158
|
-
identityPublicKey: PROD_PUBKEYS[1]
|
|
20159
|
-
},
|
|
20160
|
-
"0000000000000000000000000000000000000000000000000000000000000003": {
|
|
20161
|
-
id: 2,
|
|
20162
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
20163
|
-
address: "https://2.spark.flashnet.xyz",
|
|
20164
|
-
identityPublicKey: PROD_PUBKEYS[2]
|
|
20165
|
-
}
|
|
20166
|
-
};
|
|
20167
|
-
}
|
|
20168
|
-
function getLocalSigningOperators() {
|
|
20169
|
-
const addresses = Array.from(
|
|
20170
|
-
{ length: 5 },
|
|
20171
|
-
(_, i) => isHermeticTest ? `https://${i}.spark.minikube.local` : `https://localhost:${i + 8535}`
|
|
20172
|
-
);
|
|
20173
|
-
const pubkeys = [
|
|
20174
|
-
"0322ca18fc489ae25418a0e768273c2c61cabb823edfb14feb891e9bec62016510",
|
|
20175
|
-
"0341727a6c41b168f07eb50865ab8c397a53c7eef628ac1020956b705e43b6cb27",
|
|
20176
|
-
"0305ab8d485cc752394de4981f8a5ae004f2becfea6f432c9a59d5022d8764f0a6",
|
|
20177
|
-
"0352aef4d49439dedd798ac4aef1e7ebef95f569545b647a25338398c1247ffdea",
|
|
20178
|
-
"02c05c88cc8fc181b1ba30006df6a4b0597de6490e24514fbdd0266d2b9cd3d0ba"
|
|
20179
|
-
];
|
|
20180
|
-
return {
|
|
20181
|
-
"0000000000000000000000000000000000000000000000000000000000000001": {
|
|
20182
|
-
id: 0,
|
|
20183
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
20184
|
-
address: addresses[0],
|
|
20185
|
-
identityPublicKey: pubkeys[0]
|
|
20186
|
-
},
|
|
20187
|
-
"0000000000000000000000000000000000000000000000000000000000000002": {
|
|
20188
|
-
id: 1,
|
|
20189
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000002",
|
|
20190
|
-
address: addresses[1],
|
|
20191
|
-
identityPublicKey: pubkeys[1]
|
|
20192
|
-
},
|
|
20193
|
-
"0000000000000000000000000000000000000000000000000000000000000003": {
|
|
20194
|
-
id: 2,
|
|
20195
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000003",
|
|
20196
|
-
address: addresses[2],
|
|
20197
|
-
identityPublicKey: pubkeys[2]
|
|
20198
|
-
},
|
|
20199
|
-
"0000000000000000000000000000000000000000000000000000000000000004": {
|
|
20200
|
-
id: 3,
|
|
20201
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000004",
|
|
20202
|
-
address: addresses[3],
|
|
20203
|
-
identityPublicKey: pubkeys[3]
|
|
20204
|
-
},
|
|
20205
|
-
"0000000000000000000000000000000000000000000000000000000000000005": {
|
|
20206
|
-
id: 4,
|
|
20207
|
-
identifier: "0000000000000000000000000000000000000000000000000000000000000005",
|
|
20208
|
-
address: addresses[4],
|
|
20209
|
-
identityPublicKey: pubkeys[4]
|
|
20210
|
-
}
|
|
20211
|
-
};
|
|
20212
|
-
}
|
|
20213
|
-
|
|
20214
|
-
// src/services/config.ts
|
|
20215
|
-
var WalletConfigService = class {
|
|
20216
|
-
config;
|
|
20217
|
-
signer;
|
|
20218
|
-
sspClientOptions;
|
|
20219
|
-
constructor(options, signer) {
|
|
20220
|
-
const network = options?.network ?? "REGTEST";
|
|
20221
|
-
this.config = {
|
|
20222
|
-
...this.getDefaultConfig(Network2[network]),
|
|
20223
|
-
...options
|
|
20224
|
-
};
|
|
20225
|
-
this.signer = signer ?? new DefaultSparkSigner();
|
|
20226
|
-
this.sspClientOptions = this.config.sspClientOptions;
|
|
20227
|
-
}
|
|
20228
|
-
getDefaultConfig(network) {
|
|
20229
|
-
switch (network) {
|
|
20230
|
-
case 0 /* MAINNET */:
|
|
20231
|
-
return WalletConfig.MAINNET;
|
|
20232
|
-
case 3 /* REGTEST */:
|
|
20233
|
-
return WalletConfig.REGTEST;
|
|
20234
|
-
default:
|
|
20235
|
-
return WalletConfig.LOCAL;
|
|
20236
|
-
}
|
|
20237
|
-
}
|
|
20238
|
-
getCoordinatorAddress() {
|
|
20239
|
-
const coordinator = this.config.signingOperators[this.config.coordinatorIdentifier];
|
|
20240
|
-
if (!coordinator) {
|
|
20241
|
-
throw new ConfigurationError(
|
|
20242
|
-
"Coordinator not found in signing operators",
|
|
20243
|
-
{
|
|
20244
|
-
configKey: "signingOperators"
|
|
20245
|
-
}
|
|
20246
|
-
);
|
|
20247
|
-
}
|
|
20248
|
-
return coordinator.address;
|
|
20249
|
-
}
|
|
20250
|
-
getSigningOperators() {
|
|
20251
|
-
return this.config.signingOperators;
|
|
20252
|
-
}
|
|
20253
|
-
getThreshold() {
|
|
20254
|
-
return this.config.threshold;
|
|
20255
|
-
}
|
|
20256
|
-
getCoordinatorIdentifier() {
|
|
20257
|
-
return this.config.coordinatorIdentifier;
|
|
20258
|
-
}
|
|
20259
|
-
getExpectedWithdrawBondSats() {
|
|
20260
|
-
return this.config.expectedWithdrawBondSats;
|
|
20261
|
-
}
|
|
20262
|
-
getExpectedWithdrawRelativeBlockLocktime() {
|
|
20263
|
-
return this.config.expectedWithdrawRelativeBlockLocktime;
|
|
20264
|
-
}
|
|
20265
|
-
getSspNetwork() {
|
|
20266
|
-
if (this.config.network === "MAINNET") {
|
|
20267
|
-
return "MAINNET" /* MAINNET */;
|
|
20268
|
-
} else if (this.config.network === "REGTEST") {
|
|
20269
|
-
return "REGTEST" /* REGTEST */;
|
|
20270
|
-
} else if (this.config.network === "TESTNET") {
|
|
20271
|
-
return "TESTNET" /* TESTNET */;
|
|
20272
|
-
} else if (this.config.network === "SIGNET") {
|
|
20273
|
-
return "SIGNET" /* SIGNET */;
|
|
20274
|
-
}
|
|
20275
|
-
return "FUTURE_VALUE" /* FUTURE_VALUE */;
|
|
20276
|
-
}
|
|
20277
|
-
getNetwork() {
|
|
20278
|
-
return Network2[this.config.network];
|
|
20279
|
-
}
|
|
20280
|
-
getNetworkType() {
|
|
20281
|
-
return this.config.network;
|
|
20282
|
-
}
|
|
20283
|
-
getNetworkProto() {
|
|
20284
|
-
return NetworkToProto[Network2[this.config.network]];
|
|
20285
|
-
}
|
|
20286
|
-
getTokenSignatures() {
|
|
20287
|
-
return this.config.tokenSignatures;
|
|
20288
|
-
}
|
|
20289
|
-
getTokenValidityDurationSeconds() {
|
|
20290
|
-
return this.config.tokenValidityDurationSeconds;
|
|
20291
|
-
}
|
|
20292
|
-
getElectrsUrl() {
|
|
20293
|
-
return this.config.electrsUrl;
|
|
20294
|
-
}
|
|
20295
|
-
getSspBaseUrl() {
|
|
20296
|
-
return this.config.sspClientOptions.baseUrl;
|
|
20297
|
-
}
|
|
20298
|
-
getSspIdentityPublicKey() {
|
|
20299
|
-
return this.config.sspClientOptions.identityPublicKey;
|
|
20300
|
-
}
|
|
20301
|
-
getConsoleOptions() {
|
|
20302
|
-
return {
|
|
20303
|
-
...this.config.console
|
|
20304
|
-
};
|
|
20305
|
-
}
|
|
20306
|
-
};
|
|
20307
|
-
|
|
20308
|
-
// src/services/connection/connection.ts
|
|
20309
|
-
init_buffer();
|
|
20310
|
-
var import_core12 = require("@lightsparkdev/core");
|
|
20311
|
-
var import_sha23 = require("@noble/hashes/sha2");
|
|
20312
|
-
|
|
20313
|
-
// src/proto/spark_authn.ts
|
|
20314
|
-
init_buffer();
|
|
20315
|
-
var import_wire5 = require("@bufbuild/protobuf/wire");
|
|
20316
|
-
function createBaseChallenge() {
|
|
20317
|
-
return { version: 0, timestamp: 0, nonce: new Uint8Array(0), publicKey: new Uint8Array(0) };
|
|
20318
|
-
}
|
|
20319
|
-
var Challenge = {
|
|
20320
|
-
encode(message, writer = new import_wire5.BinaryWriter()) {
|
|
20321
|
-
if (message.version !== 0) {
|
|
20322
|
-
writer.uint32(8).int32(message.version);
|
|
20323
|
-
}
|
|
20324
|
-
if (message.timestamp !== 0) {
|
|
20325
|
-
writer.uint32(16).int64(message.timestamp);
|
|
20326
|
-
}
|
|
20327
|
-
if (message.nonce.length !== 0) {
|
|
20328
|
-
writer.uint32(26).bytes(message.nonce);
|
|
19507
|
+
if (message.nonce.length !== 0) {
|
|
19508
|
+
writer.uint32(26).bytes(message.nonce);
|
|
20329
19509
|
}
|
|
20330
19510
|
if (message.publicKey.length !== 0) {
|
|
20331
19511
|
writer.uint32(34).bytes(message.publicKey);
|
|
@@ -23751,7 +22931,7 @@ var ConnectionManager = class {
|
|
|
23751
22931
|
const challengeBytes = Challenge.encode(
|
|
23752
22932
|
challengeResp.protectedChallenge.challenge
|
|
23753
22933
|
).finish();
|
|
23754
|
-
const hash = (0,
|
|
22934
|
+
const hash = (0, import_sha22.sha256)(challengeBytes);
|
|
23755
22935
|
const derSignatureBytes = await this.config.signer.signMessageWithIdentityKey(hash);
|
|
23756
22936
|
const verifyResp = await sparkAuthnClient.verify_challenge({
|
|
23757
22937
|
protectedChallenge: challengeResp.protectedChallenge,
|
|
@@ -23761,7 +22941,7 @@ var ConnectionManager = class {
|
|
|
23761
22941
|
sparkAuthnClient.close?.();
|
|
23762
22942
|
return verifyResp.sessionToken;
|
|
23763
22943
|
} catch (error) {
|
|
23764
|
-
if ((0,
|
|
22944
|
+
if ((0, import_core10.isError)(error)) {
|
|
23765
22945
|
sparkAuthnClient?.close?.();
|
|
23766
22946
|
if (error.message.includes("challenge expired")) {
|
|
23767
22947
|
console.warn(
|
|
@@ -23770,6 +22950,13 @@ var ConnectionManager = class {
|
|
|
23770
22950
|
lastError = error;
|
|
23771
22951
|
continue;
|
|
23772
22952
|
}
|
|
22953
|
+
if (error.message.includes("UNAVAILABLE: No connection established.")) {
|
|
22954
|
+
console.warn(
|
|
22955
|
+
`Authentication attempt ${attempt + 1} failed due to unavailable status, retrying...`
|
|
22956
|
+
);
|
|
22957
|
+
lastError = error;
|
|
22958
|
+
continue;
|
|
22959
|
+
}
|
|
23773
22960
|
throw new AuthenticationError(
|
|
23774
22961
|
"Authentication failed",
|
|
23775
22962
|
{
|
|
@@ -23820,7 +23007,7 @@ var ConnectionManager = class {
|
|
|
23820
23007
|
return void 0;
|
|
23821
23008
|
}
|
|
23822
23009
|
async *handleMiddlewareError(error, address, call, metadata, options) {
|
|
23823
|
-
if ((0,
|
|
23010
|
+
if ((0, import_core10.isError)(error)) {
|
|
23824
23011
|
if (error.message.includes("token has expired")) {
|
|
23825
23012
|
const newAuthToken = await this.authenticate(address);
|
|
23826
23013
|
const clientData = this.clients.get(address);
|
|
@@ -23848,9 +23035,9 @@ var import_uuidv72 = require("uuidv7");
|
|
|
23848
23035
|
|
|
23849
23036
|
// src/utils/bitcoin.ts
|
|
23850
23037
|
init_buffer();
|
|
23851
|
-
var
|
|
23852
|
-
var
|
|
23853
|
-
var
|
|
23038
|
+
var import_secp256k1 = require("@noble/curves/secp256k1");
|
|
23039
|
+
var import_utils2 = require("@noble/curves/utils");
|
|
23040
|
+
var import_sha23 = require("@noble/hashes/sha2");
|
|
23854
23041
|
var btc2 = __toESM(require("@scure/btc-signer"), 1);
|
|
23855
23042
|
function computeTaprootKeyNoScript(pubkey) {
|
|
23856
23043
|
if (pubkey.length !== 32) {
|
|
@@ -23860,10 +23047,10 @@ function computeTaprootKeyNoScript(pubkey) {
|
|
|
23860
23047
|
expected: 32
|
|
23861
23048
|
});
|
|
23862
23049
|
}
|
|
23863
|
-
const taggedHash =
|
|
23864
|
-
const tweak = (0,
|
|
23865
|
-
const P =
|
|
23866
|
-
const Q = P.add(
|
|
23050
|
+
const taggedHash = import_secp256k1.schnorr.utils.taggedHash("TapTweak", pubkey);
|
|
23051
|
+
const tweak = (0, import_utils2.bytesToNumberBE)(taggedHash);
|
|
23052
|
+
const P = import_secp256k1.schnorr.utils.lift_x(import_secp256k1.schnorr.utils.bytesToNumberBE(pubkey));
|
|
23053
|
+
const Q = P.add(import_secp256k1.secp256k1.Point.fromPrivateKey(tweak));
|
|
23867
23054
|
return Q.toBytes();
|
|
23868
23055
|
}
|
|
23869
23056
|
function getP2TRScriptFromPublicKey(pubKey, network) {
|
|
@@ -23874,7 +23061,7 @@ function getP2TRScriptFromPublicKey(pubKey, network) {
|
|
|
23874
23061
|
expected: 33
|
|
23875
23062
|
});
|
|
23876
23063
|
}
|
|
23877
|
-
const internalKey =
|
|
23064
|
+
const internalKey = import_secp256k1.secp256k1.Point.fromHex(pubKey);
|
|
23878
23065
|
const script = btc2.p2tr(
|
|
23879
23066
|
internalKey.toBytes().slice(1, 33),
|
|
23880
23067
|
void 0,
|
|
@@ -23896,7 +23083,7 @@ function getP2TRAddressFromPublicKey(pubKey, network) {
|
|
|
23896
23083
|
expected: 33
|
|
23897
23084
|
});
|
|
23898
23085
|
}
|
|
23899
|
-
const internalKey =
|
|
23086
|
+
const internalKey = import_secp256k1.secp256k1.Point.fromHex(pubKey);
|
|
23900
23087
|
const address = btc2.p2tr(
|
|
23901
23088
|
internalKey.toBytes().slice(1, 33),
|
|
23902
23089
|
void 0,
|
|
@@ -23914,7 +23101,7 @@ function getP2TRAddressFromPkScript(pkScript, network) {
|
|
|
23914
23101
|
if (pkScript.length !== 34 || pkScript[0] !== 81 || pkScript[1] !== 32) {
|
|
23915
23102
|
throw new ValidationError("Invalid pkscript", {
|
|
23916
23103
|
field: "pkScript",
|
|
23917
|
-
value: (0,
|
|
23104
|
+
value: (0, import_utils2.bytesToHex)(pkScript),
|
|
23918
23105
|
expected: "34 bytes starting with 0x51 0x20"
|
|
23919
23106
|
});
|
|
23920
23107
|
}
|
|
@@ -23939,7 +23126,7 @@ function getP2WPKHAddressFromPublicKey(pubKey, network) {
|
|
|
23939
23126
|
return address;
|
|
23940
23127
|
}
|
|
23941
23128
|
function getTxFromRawTxHex(rawTxHex) {
|
|
23942
|
-
const txBytes = (0,
|
|
23129
|
+
const txBytes = (0, import_utils2.hexToBytes)(rawTxHex);
|
|
23943
23130
|
const tx = btc2.Transaction.fromRaw(txBytes, {
|
|
23944
23131
|
allowUnknownOutputs: true
|
|
23945
23132
|
});
|
|
@@ -23986,10 +23173,10 @@ function getSigHashFromTx(tx, inputIndex, prevOutput) {
|
|
|
23986
23173
|
);
|
|
23987
23174
|
}
|
|
23988
23175
|
function getTxId(tx) {
|
|
23989
|
-
return (0,
|
|
23176
|
+
return (0, import_utils2.bytesToHex)((0, import_sha23.sha256)((0, import_sha23.sha256)(tx.toBytes(true))).reverse());
|
|
23990
23177
|
}
|
|
23991
23178
|
function getTxIdNoReverse(tx) {
|
|
23992
|
-
return (0,
|
|
23179
|
+
return (0, import_utils2.bytesToHex)((0, import_sha23.sha256)((0, import_sha23.sha256)(tx.toBytes(true))));
|
|
23993
23180
|
}
|
|
23994
23181
|
function getTxEstimatedVbytesSizeByNumberOfInputsOutputs(numInputs, numOutputs) {
|
|
23995
23182
|
const TX_OVERHEAD = 10;
|
|
@@ -24337,17 +23524,20 @@ function getEphemeralAnchorOutput() {
|
|
|
24337
23524
|
|
|
24338
23525
|
// src/services/transfer.ts
|
|
24339
23526
|
init_buffer();
|
|
24340
|
-
var
|
|
24341
|
-
var
|
|
24342
|
-
var
|
|
23527
|
+
var import_secp256k12 = require("@noble/curves/secp256k1");
|
|
23528
|
+
var import_utils4 = require("@noble/curves/utils");
|
|
23529
|
+
var import_sha25 = require("@noble/hashes/sha2");
|
|
24343
23530
|
var import_btc_signer2 = require("@scure/btc-signer");
|
|
24344
|
-
var
|
|
23531
|
+
var ecies = __toESM(require("eciesjs"), 1);
|
|
24345
23532
|
var import_uuidv7 = require("uuidv7");
|
|
24346
23533
|
|
|
23534
|
+
// src/signer/types.ts
|
|
23535
|
+
init_buffer();
|
|
23536
|
+
|
|
24347
23537
|
// src/utils/transfer_package.ts
|
|
24348
23538
|
init_buffer();
|
|
24349
|
-
var
|
|
24350
|
-
var
|
|
23539
|
+
var import_utils3 = require("@noble/curves/utils");
|
|
23540
|
+
var import_sha24 = require("@noble/hashes/sha2");
|
|
24351
23541
|
function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
24352
23542
|
const encryptedPayload = transferPackage.keyTweakPackage;
|
|
24353
23543
|
const pairs = Object.entries(
|
|
@@ -24355,7 +23545,7 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
24355
23545
|
).map(([key, value]) => ({ key, value }));
|
|
24356
23546
|
pairs.sort((a, b) => a.key.localeCompare(b.key));
|
|
24357
23547
|
const encoder = new TextEncoder();
|
|
24358
|
-
let message = (0,
|
|
23548
|
+
let message = (0, import_utils3.hexToBytes)(transferID.replaceAll("-", ""));
|
|
24359
23549
|
for (const pair of pairs) {
|
|
24360
23550
|
const keyPart = encoder.encode(pair.key + ":");
|
|
24361
23551
|
const separator = encoder.encode(";");
|
|
@@ -24366,7 +23556,7 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
24366
23556
|
...separator
|
|
24367
23557
|
]);
|
|
24368
23558
|
}
|
|
24369
|
-
return (0,
|
|
23559
|
+
return (0, import_sha24.sha256)(message);
|
|
24370
23560
|
}
|
|
24371
23561
|
|
|
24372
23562
|
// src/services/transfer.ts
|
|
@@ -24504,8 +23694,8 @@ var BaseTransferService = class {
|
|
|
24504
23694
|
if (!operator) {
|
|
24505
23695
|
throw new ValidationError("Operator not found");
|
|
24506
23696
|
}
|
|
24507
|
-
const soPublicKey =
|
|
24508
|
-
const encryptedProto =
|
|
23697
|
+
const soPublicKey = ecies.PublicKey.fromHex(operator.identityPublicKey);
|
|
23698
|
+
const encryptedProto = ecies.encrypt(
|
|
24509
23699
|
soPublicKey.toBytes(),
|
|
24510
23700
|
protoToEncryptBinary
|
|
24511
23701
|
);
|
|
@@ -24636,8 +23826,8 @@ var BaseTransferService = class {
|
|
|
24636
23826
|
return nodeSignatures;
|
|
24637
23827
|
}
|
|
24638
23828
|
async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
24639
|
-
const receiverEciesPubKey =
|
|
24640
|
-
(0,
|
|
23829
|
+
const receiverEciesPubKey = ecies.PublicKey.fromHex(
|
|
23830
|
+
(0, import_utils4.bytesToHex)(receiverIdentityPubkey)
|
|
24641
23831
|
);
|
|
24642
23832
|
const leavesTweaksMap = /* @__PURE__ */ new Map();
|
|
24643
23833
|
for (const leaf of leaves) {
|
|
@@ -24667,7 +23857,7 @@ var BaseTransferService = class {
|
|
|
24667
23857
|
first: leaf.keyDerivation,
|
|
24668
23858
|
second: leaf.newKeyDerivation,
|
|
24669
23859
|
receiverPublicKey: receiverEciesPubKey.toBytes(),
|
|
24670
|
-
curveOrder:
|
|
23860
|
+
curveOrder: import_secp256k12.secp256k1.CURVE.n,
|
|
24671
23861
|
threshold: this.config.getThreshold(),
|
|
24672
23862
|
numShares: Object.keys(signingOperators).length
|
|
24673
23863
|
});
|
|
@@ -24677,8 +23867,8 @@ var BaseTransferService = class {
|
|
|
24677
23867
|
if (!share) {
|
|
24678
23868
|
throw new Error(`Share not found for operator ${operator.id}`);
|
|
24679
23869
|
}
|
|
24680
|
-
const pubkeyTweak =
|
|
24681
|
-
(0,
|
|
23870
|
+
const pubkeyTweak = import_secp256k12.secp256k1.getPublicKey(
|
|
23871
|
+
(0, import_utils4.numberToBytesBE)(share.share, 32),
|
|
24682
23872
|
true
|
|
24683
23873
|
);
|
|
24684
23874
|
pubkeySharesTweak.set(identifier, pubkeyTweak);
|
|
@@ -24689,7 +23879,7 @@ var BaseTransferService = class {
|
|
|
24689
23879
|
...encoder.encode(transferID),
|
|
24690
23880
|
...secretCipher
|
|
24691
23881
|
]);
|
|
24692
|
-
const payloadHash = (0,
|
|
23882
|
+
const payloadHash = (0, import_sha25.sha256)(payload);
|
|
24693
23883
|
const signature = await this.config.signer.signMessageWithIdentityKey(
|
|
24694
23884
|
payloadHash,
|
|
24695
23885
|
true
|
|
@@ -24703,7 +23893,7 @@ var BaseTransferService = class {
|
|
|
24703
23893
|
leafTweaksMap.set(identifier, {
|
|
24704
23894
|
leafId: leaf.leaf.id,
|
|
24705
23895
|
secretShareTweak: {
|
|
24706
|
-
secretShare: (0,
|
|
23896
|
+
secretShare: (0, import_utils4.numberToBytesBE)(share.share, 32),
|
|
24707
23897
|
proofs: share.proofs
|
|
24708
23898
|
},
|
|
24709
23899
|
pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak),
|
|
@@ -24726,7 +23916,7 @@ var BaseTransferService = class {
|
|
|
24726
23916
|
return void 0;
|
|
24727
23917
|
}
|
|
24728
23918
|
compareTransfers(transfer1, transfer2) {
|
|
24729
|
-
return transfer1.id === transfer2.id && (0,
|
|
23919
|
+
return transfer1.id === transfer2.id && (0, import_utils4.equalBytes)(
|
|
24730
23920
|
transfer1.senderIdentityPublicKey,
|
|
24731
23921
|
transfer2.senderIdentityPublicKey
|
|
24732
23922
|
) && transfer1.status === transfer2.status && transfer1.totalValue === transfer2.totalValue && transfer1.expiryTime?.getTime() === transfer2.expiryTime?.getTime() && transfer1.leaves.length === transfer2.leaves.length;
|
|
@@ -24808,8 +23998,8 @@ var TransferService = class extends BaseTransferService {
|
|
|
24808
23998
|
...transferIdBytes,
|
|
24809
23999
|
...leaf.secretCipher
|
|
24810
24000
|
]);
|
|
24811
|
-
const payloadHash = (0,
|
|
24812
|
-
if (!
|
|
24001
|
+
const payloadHash = (0, import_sha25.sha256)(payload);
|
|
24002
|
+
if (!import_secp256k12.secp256k1.verify(
|
|
24813
24003
|
leaf.signature,
|
|
24814
24004
|
payloadHash,
|
|
24815
24005
|
transfer.senderIdentityPublicKey
|
|
@@ -24973,7 +24163,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
24973
24163
|
}
|
|
24974
24164
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
24975
24165
|
const cpfpNodeOutPoint = {
|
|
24976
|
-
txid: (0,
|
|
24166
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
|
|
24977
24167
|
index: 0
|
|
24978
24168
|
};
|
|
24979
24169
|
let directNodeTx;
|
|
@@ -24981,7 +24171,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
24981
24171
|
if (leaf.leaf.directTx.length > 0) {
|
|
24982
24172
|
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
24983
24173
|
directNodeOutPoint = {
|
|
24984
|
-
txid: (0,
|
|
24174
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(directNodeTx)),
|
|
24985
24175
|
index: 0
|
|
24986
24176
|
};
|
|
24987
24177
|
}
|
|
@@ -25103,7 +24293,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
25103
24293
|
{
|
|
25104
24294
|
first: leaf.keyDerivation,
|
|
25105
24295
|
second: leaf.newKeyDerivation,
|
|
25106
|
-
curveOrder:
|
|
24296
|
+
curveOrder: import_secp256k12.secp256k1.CURVE.n,
|
|
25107
24297
|
threshold: this.config.getThreshold(),
|
|
25108
24298
|
numShares: Object.keys(signingOperators).length
|
|
25109
24299
|
}
|
|
@@ -25114,8 +24304,8 @@ var TransferService = class extends BaseTransferService {
|
|
|
25114
24304
|
if (!share) {
|
|
25115
24305
|
throw new Error(`Share not found for operator ${operator.id}`);
|
|
25116
24306
|
}
|
|
25117
|
-
const pubkeyTweak =
|
|
25118
|
-
(0,
|
|
24307
|
+
const pubkeyTweak = import_secp256k12.secp256k1.getPublicKey(
|
|
24308
|
+
(0, import_utils4.numberToBytesBE)(share.share, 32)
|
|
25119
24309
|
);
|
|
25120
24310
|
pubkeySharesTweak.set(identifier, pubkeyTweak);
|
|
25121
24311
|
}
|
|
@@ -25128,7 +24318,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
25128
24318
|
leafTweaksMap.set(identifier, {
|
|
25129
24319
|
leafId: leaf.leaf.id,
|
|
25130
24320
|
secretShareTweak: {
|
|
25131
|
-
secretShare: (0,
|
|
24321
|
+
secretShare: (0, import_utils4.numberToBytesBE)(share.share, 32),
|
|
25132
24322
|
proofs: share.proofs
|
|
25133
24323
|
},
|
|
25134
24324
|
pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak)
|
|
@@ -25296,13 +24486,13 @@ var TransferService = class extends BaseTransferService {
|
|
|
25296
24486
|
});
|
|
25297
24487
|
}
|
|
25298
24488
|
const newCpfpRefundOutPoint = {
|
|
25299
|
-
txid: (0,
|
|
24489
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(cpfpNodeTx)),
|
|
25300
24490
|
index: 0
|
|
25301
24491
|
};
|
|
25302
24492
|
let newDirectRefundOutPoint;
|
|
25303
24493
|
if (newDirectNodeTx) {
|
|
25304
24494
|
newDirectRefundOutPoint = {
|
|
25305
|
-
txid: (0,
|
|
24495
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
25306
24496
|
index: 0
|
|
25307
24497
|
};
|
|
25308
24498
|
}
|
|
@@ -25430,7 +24620,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
25430
24620
|
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
25431
24621
|
const refundSequence = refundTx.getInput(0).sequence || 0;
|
|
25432
24622
|
const newNodeOutPoint = {
|
|
25433
|
-
txid: (0,
|
|
24623
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
|
|
25434
24624
|
index: 0
|
|
25435
24625
|
};
|
|
25436
24626
|
const {
|
|
@@ -25467,13 +24657,13 @@ var TransferService = class extends BaseTransferService {
|
|
|
25467
24657
|
});
|
|
25468
24658
|
}
|
|
25469
24659
|
const newCpfpRefundOutPoint = {
|
|
25470
|
-
txid: (0,
|
|
24660
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(newNodeTx)),
|
|
25471
24661
|
index: 0
|
|
25472
24662
|
};
|
|
25473
24663
|
let newDirectRefundOutPoint;
|
|
25474
24664
|
if (newDirectNodeTx) {
|
|
25475
24665
|
newDirectRefundOutPoint = {
|
|
25476
|
-
txid: (0,
|
|
24666
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
25477
24667
|
index: 0
|
|
25478
24668
|
};
|
|
25479
24669
|
}
|
|
@@ -25707,13 +24897,13 @@ var TransferService = class extends BaseTransferService {
|
|
|
25707
24897
|
};
|
|
25708
24898
|
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
25709
24899
|
const cpfpRefundOutPoint = {
|
|
25710
|
-
txid: (0,
|
|
24900
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
|
|
25711
24901
|
index: 0
|
|
25712
24902
|
};
|
|
25713
24903
|
let directRefundOutPoint;
|
|
25714
24904
|
if (directNodeTx) {
|
|
25715
24905
|
directRefundOutPoint = {
|
|
25716
|
-
txid: (0,
|
|
24906
|
+
txid: (0, import_utils4.hexToBytes)(getTxId(directNodeTx)),
|
|
25717
24907
|
index: 0
|
|
25718
24908
|
};
|
|
25719
24909
|
}
|
|
@@ -25835,7 +25025,8 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25835
25025
|
leaves,
|
|
25836
25026
|
exitTxId,
|
|
25837
25027
|
connectorOutputs,
|
|
25838
|
-
receiverPubKey
|
|
25028
|
+
receiverPubKey,
|
|
25029
|
+
transferId
|
|
25839
25030
|
}) {
|
|
25840
25031
|
const {
|
|
25841
25032
|
transfer,
|
|
@@ -25846,7 +25037,8 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25846
25037
|
leaves,
|
|
25847
25038
|
exitTxId,
|
|
25848
25039
|
connectorOutputs,
|
|
25849
|
-
receiverPubKey
|
|
25040
|
+
receiverPubKey,
|
|
25041
|
+
transferId
|
|
25850
25042
|
);
|
|
25851
25043
|
const transferTweak = await this.deliverTransferPackage(
|
|
25852
25044
|
transfer,
|
|
@@ -25927,7 +25119,7 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25927
25119
|
directFromCpfpRefundTx
|
|
25928
25120
|
};
|
|
25929
25121
|
}
|
|
25930
|
-
async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey) {
|
|
25122
|
+
async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey, transferId) {
|
|
25931
25123
|
if (leaves.length !== connectorOutputs.length) {
|
|
25932
25124
|
throw new ValidationError(
|
|
25933
25125
|
"Mismatch between leaves and connector outputs",
|
|
@@ -26031,7 +25223,7 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
26031
25223
|
try {
|
|
26032
25224
|
response = await sparkClient.cooperative_exit_v2({
|
|
26033
25225
|
transfer: {
|
|
26034
|
-
transferId
|
|
25226
|
+
transferId,
|
|
26035
25227
|
leavesToSend: signingJobs,
|
|
26036
25228
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
26037
25229
|
receiverIdentityPublicKey: receiverPubKey,
|
|
@@ -26087,15 +25279,114 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
26087
25279
|
|
|
26088
25280
|
// src/services/deposit.ts
|
|
26089
25281
|
init_buffer();
|
|
26090
|
-
var
|
|
26091
|
-
var
|
|
26092
|
-
var
|
|
25282
|
+
var import_secp256k14 = require("@noble/curves/secp256k1");
|
|
25283
|
+
var import_sha27 = require("@noble/hashes/sha2");
|
|
25284
|
+
var import_utils6 = require("@noble/hashes/utils");
|
|
26093
25285
|
var import_btc_signer4 = require("@scure/btc-signer");
|
|
26094
|
-
var
|
|
25286
|
+
var import_utils7 = require("@scure/btc-signer/utils");
|
|
25287
|
+
|
|
25288
|
+
// src/utils/keys.ts
|
|
25289
|
+
init_buffer();
|
|
25290
|
+
var import_secp256k13 = require("@noble/curves/secp256k1");
|
|
25291
|
+
var import_utils5 = require("@noble/curves/utils");
|
|
25292
|
+
function addPublicKeys(a, b) {
|
|
25293
|
+
if (a.length !== 33 || b.length !== 33) {
|
|
25294
|
+
throw new ValidationError("Public keys must be 33 bytes", {
|
|
25295
|
+
field: "publicKeys",
|
|
25296
|
+
value: `a: ${a.length}, b: ${b.length}`,
|
|
25297
|
+
expected: 33
|
|
25298
|
+
});
|
|
25299
|
+
}
|
|
25300
|
+
const pubkeyA = import_secp256k13.secp256k1.Point.fromHex(a);
|
|
25301
|
+
const pubkeyB = import_secp256k13.secp256k1.Point.fromHex(b);
|
|
25302
|
+
return pubkeyA.add(pubkeyB).toBytes(true);
|
|
25303
|
+
}
|
|
25304
|
+
function applyAdditiveTweakToPublicKey(pubkey, tweak) {
|
|
25305
|
+
if (pubkey.length !== 33) {
|
|
25306
|
+
throw new ValidationError("Public key must be 33 bytes", {
|
|
25307
|
+
field: "pubkey",
|
|
25308
|
+
value: pubkey.length,
|
|
25309
|
+
expected: 33
|
|
25310
|
+
});
|
|
25311
|
+
}
|
|
25312
|
+
if (tweak.length !== 32) {
|
|
25313
|
+
throw new ValidationError("Tweak must be 32 bytes", {
|
|
25314
|
+
field: "tweak",
|
|
25315
|
+
value: tweak.length,
|
|
25316
|
+
expected: 32
|
|
25317
|
+
});
|
|
25318
|
+
}
|
|
25319
|
+
const pubkeyPoint = import_secp256k13.secp256k1.Point.fromHex(pubkey);
|
|
25320
|
+
const privTweek = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(tweak);
|
|
25321
|
+
const pubTweek = import_secp256k13.secp256k1.getPublicKey(privTweek, true);
|
|
25322
|
+
const tweekPoint = import_secp256k13.secp256k1.Point.fromHex(pubTweek);
|
|
25323
|
+
return pubkeyPoint.add(tweekPoint).toBytes(true);
|
|
25324
|
+
}
|
|
25325
|
+
function subtractPublicKeys(a, b) {
|
|
25326
|
+
if (a.length !== 33 || b.length !== 33) {
|
|
25327
|
+
throw new ValidationError("Public keys must be 33 bytes", {
|
|
25328
|
+
field: "publicKeys",
|
|
25329
|
+
value: `a: ${a.length}, b: ${b.length}`,
|
|
25330
|
+
expected: 33
|
|
25331
|
+
});
|
|
25332
|
+
}
|
|
25333
|
+
const pubkeyA = import_secp256k13.secp256k1.Point.fromHex(a);
|
|
25334
|
+
const pubkeyB = import_secp256k13.secp256k1.Point.fromHex(b);
|
|
25335
|
+
return pubkeyA.subtract(pubkeyB).toBytes(true);
|
|
25336
|
+
}
|
|
25337
|
+
function addPrivateKeys(a, b) {
|
|
25338
|
+
if (a.length !== 32 || b.length !== 32) {
|
|
25339
|
+
throw new ValidationError("Private keys must be 32 bytes", {
|
|
25340
|
+
field: "privateKeys",
|
|
25341
|
+
value: `a: ${a.length}, b: ${b.length}`,
|
|
25342
|
+
expected: 32
|
|
25343
|
+
});
|
|
25344
|
+
}
|
|
25345
|
+
const privA = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(a);
|
|
25346
|
+
const privB = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(b);
|
|
25347
|
+
const sum2 = (privA + privB) % import_secp256k13.secp256k1.CURVE.n;
|
|
25348
|
+
return (0, import_utils5.numberToBytesBE)(sum2, 32);
|
|
25349
|
+
}
|
|
25350
|
+
function subtractPrivateKeys(a, b) {
|
|
25351
|
+
if (a.length !== 32 || b.length !== 32) {
|
|
25352
|
+
throw new ValidationError("Private keys must be 32 bytes", {
|
|
25353
|
+
field: "privateKeys",
|
|
25354
|
+
value: `a: ${a.length}, b: ${b.length}`,
|
|
25355
|
+
expected: 32
|
|
25356
|
+
});
|
|
25357
|
+
}
|
|
25358
|
+
const privA = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(a);
|
|
25359
|
+
const privB = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(b);
|
|
25360
|
+
const sum2 = (import_secp256k13.secp256k1.CURVE.n - privB + privA) % import_secp256k13.secp256k1.CURVE.n;
|
|
25361
|
+
return (0, import_utils5.numberToBytesBE)(sum2, 32);
|
|
25362
|
+
}
|
|
25363
|
+
function sumOfPrivateKeys(keys) {
|
|
25364
|
+
return keys.reduce((sum2, key) => {
|
|
25365
|
+
if (key.length !== 32) {
|
|
25366
|
+
throw new ValidationError("Private keys must be 32 bytes", {
|
|
25367
|
+
field: "privateKey",
|
|
25368
|
+
value: key.length,
|
|
25369
|
+
expected: 32
|
|
25370
|
+
});
|
|
25371
|
+
}
|
|
25372
|
+
return addPrivateKeys(sum2, key);
|
|
25373
|
+
});
|
|
25374
|
+
}
|
|
25375
|
+
function lastKeyWithTarget(target, keys) {
|
|
25376
|
+
if (target.length !== 32) {
|
|
25377
|
+
throw new ValidationError("Target must be 32 bytes", {
|
|
25378
|
+
field: "target",
|
|
25379
|
+
value: target.length,
|
|
25380
|
+
expected: 32
|
|
25381
|
+
});
|
|
25382
|
+
}
|
|
25383
|
+
const sum2 = sumOfPrivateKeys(keys);
|
|
25384
|
+
return subtractPrivateKeys(target, sum2);
|
|
25385
|
+
}
|
|
26095
25386
|
|
|
26096
25387
|
// src/utils/proof.ts
|
|
26097
25388
|
init_buffer();
|
|
26098
|
-
var
|
|
25389
|
+
var import_sha26 = require("@noble/hashes/sha2");
|
|
26099
25390
|
function proofOfPossessionMessageHashForDepositAddress(userPubkey, operatorPubkey, depositAddress) {
|
|
26100
25391
|
const encoder = new TextEncoder();
|
|
26101
25392
|
const depositAddressBytes = encoder.encode(depositAddress);
|
|
@@ -26104,7 +25395,7 @@ function proofOfPossessionMessageHashForDepositAddress(userPubkey, operatorPubke
|
|
|
26104
25395
|
...operatorPubkey,
|
|
26105
25396
|
...depositAddressBytes
|
|
26106
25397
|
]);
|
|
26107
|
-
return (0,
|
|
25398
|
+
return (0, import_sha26.sha256)(proofMsg);
|
|
26108
25399
|
}
|
|
26109
25400
|
|
|
26110
25401
|
// src/services/deposit.ts
|
|
@@ -26140,7 +25431,7 @@ var DepositService = class {
|
|
|
26140
25431
|
void 0,
|
|
26141
25432
|
getNetwork(this.config.getNetwork())
|
|
26142
25433
|
).tweakedPubkey;
|
|
26143
|
-
const isVerified =
|
|
25434
|
+
const isVerified = import_secp256k14.schnorr.verify(
|
|
26144
25435
|
address.depositAddressProof.proofOfPossessionSignature,
|
|
26145
25436
|
msg,
|
|
26146
25437
|
taprootKey
|
|
@@ -26154,12 +25445,12 @@ var DepositService = class {
|
|
|
26154
25445
|
}
|
|
26155
25446
|
);
|
|
26156
25447
|
}
|
|
26157
|
-
const addrHash = (0,
|
|
25448
|
+
const addrHash = (0, import_sha27.sha256)(address.address);
|
|
26158
25449
|
for (const operator of Object.values(this.config.getSigningOperators())) {
|
|
26159
25450
|
if (operator.identifier === this.config.getCoordinatorIdentifier() && !verifyCoordinatorProof) {
|
|
26160
25451
|
continue;
|
|
26161
25452
|
}
|
|
26162
|
-
const operatorPubkey2 = (0,
|
|
25453
|
+
const operatorPubkey2 = (0, import_utils6.hexToBytes)(operator.identityPublicKey);
|
|
26163
25454
|
const operatorSig = address.depositAddressProof.addressSignatures[operator.identifier];
|
|
26164
25455
|
if (!operatorSig) {
|
|
26165
25456
|
throw new ValidationError("Operator signature not found", {
|
|
@@ -26167,8 +25458,8 @@ var DepositService = class {
|
|
|
26167
25458
|
value: operator.identifier
|
|
26168
25459
|
});
|
|
26169
25460
|
}
|
|
26170
|
-
const sig =
|
|
26171
|
-
const isVerified2 =
|
|
25461
|
+
const sig = import_secp256k14.secp256k1.Signature.fromDER(operatorSig);
|
|
25462
|
+
const isVerified2 = import_secp256k14.secp256k1.verify(
|
|
26172
25463
|
sig.toCompactRawBytes(),
|
|
26173
25464
|
addrHash,
|
|
26174
25465
|
operatorPubkey2
|
|
@@ -26288,7 +25579,7 @@ var DepositService = class {
|
|
|
26288
25579
|
});
|
|
26289
25580
|
}
|
|
26290
25581
|
const depositOutPoint = {
|
|
26291
|
-
txid: (0,
|
|
25582
|
+
txid: (0, import_utils6.hexToBytes)(getTxId(depositTx)),
|
|
26292
25583
|
index: vout
|
|
26293
25584
|
};
|
|
26294
25585
|
const depositTxOut = {
|
|
@@ -26307,8 +25598,8 @@ var DepositService = class {
|
|
|
26307
25598
|
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
26308
25599
|
sequence: INITIAL_SEQUENCE,
|
|
26309
25600
|
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
26310
|
-
input: { txid: (0,
|
|
26311
|
-
directInput: { txid: (0,
|
|
25601
|
+
input: { txid: (0, import_utils6.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
25602
|
+
directInput: { txid: (0, import_utils6.hexToBytes)(getTxId(directRootTx)), index: 0 },
|
|
26312
25603
|
amountSats: amount,
|
|
26313
25604
|
receivingPubkey: signingPubKey,
|
|
26314
25605
|
network: this.config.getNetwork()
|
|
@@ -26438,7 +25729,7 @@ var DepositService = class {
|
|
|
26438
25729
|
}
|
|
26439
25730
|
);
|
|
26440
25731
|
}
|
|
26441
|
-
if (!(0,
|
|
25732
|
+
if (!(0, import_utils7.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
26442
25733
|
throw new ValidationError("Verifying key mismatch", {
|
|
26443
25734
|
field: "verifyingKey",
|
|
26444
25735
|
value: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
@@ -26602,7 +25893,7 @@ var DepositService = class {
|
|
|
26602
25893
|
});
|
|
26603
25894
|
}
|
|
26604
25895
|
const depositOutPoint = {
|
|
26605
|
-
txid: (0,
|
|
25896
|
+
txid: (0, import_utils6.hexToBytes)(getTxId(depositTx)),
|
|
26606
25897
|
index: vout
|
|
26607
25898
|
};
|
|
26608
25899
|
const depositTxOut = {
|
|
@@ -26615,7 +25906,7 @@ var DepositService = class {
|
|
|
26615
25906
|
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
26616
25907
|
const { cpfpRefundTx } = createRefundTxs({
|
|
26617
25908
|
sequence: INITIAL_SEQUENCE,
|
|
26618
|
-
input: { txid: (0,
|
|
25909
|
+
input: { txid: (0, import_utils6.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
26619
25910
|
amountSats: amount,
|
|
26620
25911
|
receivingPubkey: signingPubKey,
|
|
26621
25912
|
network: this.config.getNetwork()
|
|
@@ -26685,7 +25976,7 @@ var DepositService = class {
|
|
|
26685
25976
|
}
|
|
26686
25977
|
);
|
|
26687
25978
|
}
|
|
26688
|
-
if (!(0,
|
|
25979
|
+
if (!(0, import_utils7.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
26689
25980
|
throw new ValidationError("Verifying key mismatch", {
|
|
26690
25981
|
field: "verifyingKey",
|
|
26691
25982
|
value: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
@@ -26761,11 +26052,23 @@ var DepositService = class {
|
|
|
26761
26052
|
|
|
26762
26053
|
// src/services/lightning.ts
|
|
26763
26054
|
init_buffer();
|
|
26764
|
-
var
|
|
26765
|
-
var
|
|
26766
|
-
var
|
|
26055
|
+
var import_secp256k15 = require("@noble/curves/secp256k1");
|
|
26056
|
+
var import_utils8 = require("@noble/curves/utils");
|
|
26057
|
+
var import_sha28 = require("@noble/hashes/sha2");
|
|
26767
26058
|
var import_uuidv73 = require("uuidv7");
|
|
26768
26059
|
|
|
26060
|
+
// src/utils/crypto.ts
|
|
26061
|
+
init_buffer();
|
|
26062
|
+
var cryptoImpl = globalThis.crypto ?? null;
|
|
26063
|
+
var getCrypto = () => {
|
|
26064
|
+
if (!cryptoImpl) {
|
|
26065
|
+
throw new Error(
|
|
26066
|
+
"Crypto implementation is not set. Please set it using setCrypto()."
|
|
26067
|
+
);
|
|
26068
|
+
}
|
|
26069
|
+
return cryptoImpl;
|
|
26070
|
+
};
|
|
26071
|
+
|
|
26769
26072
|
// src/services/bolt11-spark.ts
|
|
26770
26073
|
init_buffer();
|
|
26771
26074
|
var import_light_bolt11_decoder = require("light-bolt11-decoder");
|
|
@@ -26848,8 +26151,8 @@ var LightningService = class {
|
|
|
26848
26151
|
}) {
|
|
26849
26152
|
const crypto = getCrypto();
|
|
26850
26153
|
const randBytes = crypto.getRandomValues(new Uint8Array(32));
|
|
26851
|
-
const preimage = (0,
|
|
26852
|
-
(0,
|
|
26154
|
+
const preimage = (0, import_utils8.numberToBytesBE)(
|
|
26155
|
+
(0, import_utils8.bytesToNumberBE)(randBytes) % import_secp256k15.secp256k1.CURVE.n,
|
|
26853
26156
|
32
|
|
26854
26157
|
);
|
|
26855
26158
|
return await this.createLightningInvoiceWithPreImage({
|
|
@@ -26869,7 +26172,7 @@ var LightningService = class {
|
|
|
26869
26172
|
receiverIdentityPubkey,
|
|
26870
26173
|
descriptionHash
|
|
26871
26174
|
}) {
|
|
26872
|
-
const paymentHash = (0,
|
|
26175
|
+
const paymentHash = (0, import_sha28.sha256)(preimage);
|
|
26873
26176
|
const invoice = await invoiceCreator(
|
|
26874
26177
|
amountSats,
|
|
26875
26178
|
paymentHash,
|
|
@@ -26886,7 +26189,7 @@ var LightningService = class {
|
|
|
26886
26189
|
}
|
|
26887
26190
|
const shares = await this.config.signer.splitSecretWithProofs({
|
|
26888
26191
|
secret: preimage,
|
|
26889
|
-
curveOrder:
|
|
26192
|
+
curveOrder: import_secp256k15.secp256k1.CURVE.n,
|
|
26890
26193
|
threshold: this.config.getThreshold(),
|
|
26891
26194
|
numShares: Object.keys(this.config.getSigningOperators()).length
|
|
26892
26195
|
});
|
|
@@ -26904,12 +26207,12 @@ var LightningService = class {
|
|
|
26904
26207
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
26905
26208
|
operator.address
|
|
26906
26209
|
);
|
|
26907
|
-
const userIdentityPublicKey = receiverIdentityPubkey ? (0,
|
|
26210
|
+
const userIdentityPublicKey = receiverIdentityPubkey ? (0, import_utils8.hexToBytes)(receiverIdentityPubkey) : await this.config.signer.getIdentityPublicKey();
|
|
26908
26211
|
try {
|
|
26909
26212
|
await sparkClient.store_preimage_share({
|
|
26910
26213
|
paymentHash,
|
|
26911
26214
|
preimageShare: {
|
|
26912
|
-
secretShare: (0,
|
|
26215
|
+
secretShare: (0, import_utils8.numberToBytesBE)(share.share, 32),
|
|
26913
26216
|
proofs: share.proofs
|
|
26914
26217
|
},
|
|
26915
26218
|
threshold: this.config.getThreshold(),
|
|
@@ -27078,7 +26381,7 @@ var LightningService = class {
|
|
|
27078
26381
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
27079
26382
|
this.config.getCoordinatorAddress()
|
|
27080
26383
|
);
|
|
27081
|
-
const paymentHash = (0,
|
|
26384
|
+
const paymentHash = (0, import_sha28.sha256)(preimage);
|
|
27082
26385
|
let response;
|
|
27083
26386
|
try {
|
|
27084
26387
|
response = await sparkClient.provide_preimage({
|
|
@@ -27110,21 +26413,21 @@ var LightningService = class {
|
|
|
27110
26413
|
|
|
27111
26414
|
// src/services/token-transactions.ts
|
|
27112
26415
|
init_buffer();
|
|
27113
|
-
var
|
|
27114
|
-
var
|
|
26416
|
+
var import_utils12 = require("@noble/curves/utils");
|
|
26417
|
+
var import_utils13 = require("@noble/hashes/utils");
|
|
27115
26418
|
|
|
27116
26419
|
// src/utils/address.ts
|
|
27117
26420
|
init_buffer();
|
|
27118
26421
|
var import_wire7 = require("@bufbuild/protobuf/wire");
|
|
27119
|
-
var
|
|
27120
|
-
var
|
|
27121
|
-
var
|
|
26422
|
+
var import_secp256k16 = require("@noble/curves/secp256k1");
|
|
26423
|
+
var import_utils9 = require("@noble/curves/utils");
|
|
26424
|
+
var import_utils10 = require("@noble/hashes/utils");
|
|
27122
26425
|
var import_base3 = require("@scure/base");
|
|
27123
26426
|
var import_uuidv74 = require("uuidv7");
|
|
27124
26427
|
|
|
27125
26428
|
// src/utils/invoice-hashing.ts
|
|
27126
26429
|
init_buffer();
|
|
27127
|
-
var
|
|
26430
|
+
var import_sha29 = require("@noble/hashes/sha2");
|
|
27128
26431
|
function HashSparkInvoice(sparkInvoiceFields, receiverPublicKey, network) {
|
|
27129
26432
|
if (!sparkInvoiceFields) {
|
|
27130
26433
|
throw new Error("Missing sparkInvoiceFields");
|
|
@@ -27161,20 +26464,20 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27161
26464
|
}
|
|
27162
26465
|
const { version, id, paymentType, memo, senderPublicKey, expiryTime } = sparkInvoiceFields;
|
|
27163
26466
|
const allHashes = [];
|
|
27164
|
-
const versionHashObj =
|
|
26467
|
+
const versionHashObj = import_sha29.sha256.create();
|
|
27165
26468
|
const versionBytes = uint32be(version);
|
|
27166
26469
|
versionHashObj.update(versionBytes);
|
|
27167
26470
|
allHashes.push(versionHashObj.digest());
|
|
27168
|
-
const idHashObj =
|
|
26471
|
+
const idHashObj = import_sha29.sha256.create();
|
|
27169
26472
|
if (!id || id.length !== 16) {
|
|
27170
26473
|
throw new Error("invoice id must be exactly 16 bytes");
|
|
27171
26474
|
}
|
|
27172
26475
|
idHashObj.update(id);
|
|
27173
26476
|
allHashes.push(idHashObj.digest());
|
|
27174
|
-
const networkHashObj =
|
|
26477
|
+
const networkHashObj = import_sha29.sha256.create();
|
|
27175
26478
|
hashNetworkMagicInto(networkHashObj, network);
|
|
27176
26479
|
allHashes.push(networkHashObj.digest());
|
|
27177
|
-
const receiverPubKeyHashObj =
|
|
26480
|
+
const receiverPubKeyHashObj = import_sha29.sha256.create();
|
|
27178
26481
|
if (!receiverPublicKey || receiverPublicKey.length !== 33) {
|
|
27179
26482
|
throw new Error("receiver public key must be exactly 33 bytes");
|
|
27180
26483
|
}
|
|
@@ -27183,10 +26486,10 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27183
26486
|
switch (paymentType?.$case) {
|
|
27184
26487
|
case "tokensPayment": {
|
|
27185
26488
|
const tp = paymentType.tokensPayment;
|
|
27186
|
-
const discrHash =
|
|
26489
|
+
const discrHash = import_sha29.sha256.create();
|
|
27187
26490
|
discrHash.update(new Uint8Array([1]));
|
|
27188
26491
|
allHashes.push(discrHash.digest());
|
|
27189
|
-
const tokenIdHash =
|
|
26492
|
+
const tokenIdHash = import_sha29.sha256.create();
|
|
27190
26493
|
const tokenIdentifier = tp.tokenIdentifier;
|
|
27191
26494
|
if (!tokenIdentifier || tokenIdentifier.length === 0) {
|
|
27192
26495
|
tokenIdHash.update(new Uint8Array(32));
|
|
@@ -27197,7 +26500,7 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27197
26500
|
tokenIdHash.update(tokenIdentifier);
|
|
27198
26501
|
}
|
|
27199
26502
|
allHashes.push(tokenIdHash.digest());
|
|
27200
|
-
const amountHash =
|
|
26503
|
+
const amountHash = import_sha29.sha256.create();
|
|
27201
26504
|
const amount = tp.amount;
|
|
27202
26505
|
if (amount && amount.length > 16) {
|
|
27203
26506
|
throw new Error("token amount exceeds 16 bytes");
|
|
@@ -27210,10 +26513,10 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27210
26513
|
}
|
|
27211
26514
|
case "satsPayment": {
|
|
27212
26515
|
const sp = paymentType.satsPayment;
|
|
27213
|
-
const discrHash =
|
|
26516
|
+
const discrHash = import_sha29.sha256.create();
|
|
27214
26517
|
discrHash.update(new Uint8Array([2]));
|
|
27215
26518
|
allHashes.push(discrHash.digest());
|
|
27216
|
-
const satsHash =
|
|
26519
|
+
const satsHash = import_sha29.sha256.create();
|
|
27217
26520
|
let sats = 0n;
|
|
27218
26521
|
if (sp && typeof sp.amount === "number" && sp.amount !== 0) {
|
|
27219
26522
|
sats = BigInt(sp.amount);
|
|
@@ -27226,12 +26529,12 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27226
26529
|
throw new Error("unsupported or missing payment type");
|
|
27227
26530
|
}
|
|
27228
26531
|
}
|
|
27229
|
-
const memoHashObj =
|
|
26532
|
+
const memoHashObj = import_sha29.sha256.create();
|
|
27230
26533
|
if (memo != null) {
|
|
27231
26534
|
memoHashObj.update(new TextEncoder().encode(memo));
|
|
27232
26535
|
}
|
|
27233
26536
|
allHashes.push(memoHashObj.digest());
|
|
27234
|
-
const senderPubKeyHashObj =
|
|
26537
|
+
const senderPubKeyHashObj = import_sha29.sha256.create();
|
|
27235
26538
|
const spk = senderPublicKey;
|
|
27236
26539
|
if (!spk || spk.length === 0) {
|
|
27237
26540
|
senderPubKeyHashObj.update(new Uint8Array(33));
|
|
@@ -27242,7 +26545,7 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27242
26545
|
senderPubKeyHashObj.update(spk);
|
|
27243
26546
|
}
|
|
27244
26547
|
allHashes.push(senderPubKeyHashObj.digest());
|
|
27245
|
-
const expiryHashObj =
|
|
26548
|
+
const expiryHashObj = import_sha29.sha256.create();
|
|
27246
26549
|
let exp = 0n;
|
|
27247
26550
|
if (expiryTime instanceof Date) {
|
|
27248
26551
|
const seconds = Math.floor(expiryTime.getTime() / 1e3);
|
|
@@ -27252,7 +26555,7 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
|
|
|
27252
26555
|
}
|
|
27253
26556
|
expiryHashObj.update(uint64be(exp));
|
|
27254
26557
|
allHashes.push(expiryHashObj.digest());
|
|
27255
|
-
const finalHash =
|
|
26558
|
+
const finalHash = import_sha29.sha256.create();
|
|
27256
26559
|
for (const hash of allHashes) {
|
|
27257
26560
|
finalHash.update(hash);
|
|
27258
26561
|
}
|
|
@@ -27276,7 +26579,7 @@ function bitcoinNetworkIdentifierFromNetwork(network) {
|
|
|
27276
26579
|
function hashNetworkMagicInto(hasher, network) {
|
|
27277
26580
|
const magic = bitcoinNetworkIdentifierFromNetwork(network);
|
|
27278
26581
|
const magicBE = uint32be(magic);
|
|
27279
|
-
hasher.update((0,
|
|
26582
|
+
hasher.update((0, import_sha29.sha256)(magicBE));
|
|
27280
26583
|
}
|
|
27281
26584
|
function uint32be(n) {
|
|
27282
26585
|
const b = new Uint8Array(4);
|
|
@@ -27311,7 +26614,7 @@ function encodeSparkAddress(payload) {
|
|
|
27311
26614
|
function encodeSparkAddressWithSignature(payload, signature) {
|
|
27312
26615
|
try {
|
|
27313
26616
|
isValidPublicKey(payload.identityPublicKey);
|
|
27314
|
-
const identityPublicKey = (0,
|
|
26617
|
+
const identityPublicKey = (0, import_utils10.hexToBytes)(payload.identityPublicKey);
|
|
27315
26618
|
let sparkInvoiceFields;
|
|
27316
26619
|
if (payload.sparkInvoiceFields) {
|
|
27317
26620
|
validateSparkInvoiceFields(payload.sparkInvoiceFields);
|
|
@@ -27355,8 +26658,8 @@ function decodeSparkAddress(address, network) {
|
|
|
27355
26658
|
const decoded = bech32mDecode(address);
|
|
27356
26659
|
const payload = SparkAddress.decode(import_base3.bech32m.fromWords(decoded.words));
|
|
27357
26660
|
const { identityPublicKey, sparkInvoiceFields, signature } = payload;
|
|
27358
|
-
const identityPubkeyHex = (0,
|
|
27359
|
-
const signatureHex = signature ? (0,
|
|
26661
|
+
const identityPubkeyHex = (0, import_utils10.bytesToHex)(identityPublicKey);
|
|
26662
|
+
const signatureHex = signature ? (0, import_utils10.bytesToHex)(signature) : void 0;
|
|
27360
26663
|
isValidPublicKey(identityPubkeyHex);
|
|
27361
26664
|
return {
|
|
27362
26665
|
identityPublicKey: identityPubkeyHex,
|
|
@@ -27366,10 +26669,10 @@ function decodeSparkAddress(address, network) {
|
|
|
27366
26669
|
id: import_uuidv74.UUID.ofInner(sparkInvoiceFields.id).toString(),
|
|
27367
26670
|
paymentType: sparkInvoiceFields.paymentType ? sparkInvoiceFields.paymentType.$case === "tokensPayment" ? {
|
|
27368
26671
|
type: "tokens",
|
|
27369
|
-
tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? (0,
|
|
26672
|
+
tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? (0, import_utils10.bytesToHex)(
|
|
27370
26673
|
sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier
|
|
27371
26674
|
) : void 0,
|
|
27372
|
-
amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? (0,
|
|
26675
|
+
amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? (0, import_utils9.bytesToNumberBE)(
|
|
27373
26676
|
sparkInvoiceFields.paymentType.tokensPayment.amount
|
|
27374
26677
|
) : void 0
|
|
27375
26678
|
} : sparkInvoiceFields.paymentType.$case === "satsPayment" ? {
|
|
@@ -27377,7 +26680,7 @@ function decodeSparkAddress(address, network) {
|
|
|
27377
26680
|
amount: sparkInvoiceFields.paymentType.satsPayment.amount
|
|
27378
26681
|
} : void 0 : void 0,
|
|
27379
26682
|
memo: sparkInvoiceFields.memo,
|
|
27380
|
-
senderPublicKey: sparkInvoiceFields.senderPublicKey ? (0,
|
|
26683
|
+
senderPublicKey: sparkInvoiceFields.senderPublicKey ? (0, import_utils10.bytesToHex)(sparkInvoiceFields.senderPublicKey) : void 0,
|
|
27381
26684
|
expiryTime: sparkInvoiceFields.expiryTime
|
|
27382
26685
|
},
|
|
27383
26686
|
signature: signatureHex
|
|
@@ -27443,7 +26746,7 @@ function isValidSparkAddress(address) {
|
|
|
27443
26746
|
}
|
|
27444
26747
|
function isValidPublicKey(publicKey) {
|
|
27445
26748
|
try {
|
|
27446
|
-
const point =
|
|
26749
|
+
const point = import_secp256k16.secp256k1.Point.fromHex(publicKey);
|
|
27447
26750
|
point.assertValidity();
|
|
27448
26751
|
} catch (error) {
|
|
27449
26752
|
throw new ValidationError(
|
|
@@ -27478,7 +26781,7 @@ function validateSparkInvoiceFields(sparkInvoiceFields) {
|
|
|
27478
26781
|
}
|
|
27479
26782
|
if (senderPublicKey) {
|
|
27480
26783
|
try {
|
|
27481
|
-
isValidPublicKey((0,
|
|
26784
|
+
isValidPublicKey((0, import_utils10.bytesToHex)(senderPublicKey));
|
|
27482
26785
|
} catch (error) {
|
|
27483
26786
|
throw new ValidationError(
|
|
27484
26787
|
"Invalid sender public key",
|
|
@@ -27529,7 +26832,7 @@ function validateSparkInvoiceFields(sparkInvoiceFields) {
|
|
|
27529
26832
|
value: tokensAmount
|
|
27530
26833
|
});
|
|
27531
26834
|
}
|
|
27532
|
-
const tokensAmountBigInt = (0,
|
|
26835
|
+
const tokensAmountBigInt = (0, import_utils9.bytesToNumberBE)(tokensAmount);
|
|
27533
26836
|
if (tokensAmountBigInt < 0 || tokensAmountBigInt > MAX_UINT128) {
|
|
27534
26837
|
throw new ValidationError(
|
|
27535
26838
|
"Asset amount must be between 0 and MAX_UINT128",
|
|
@@ -27596,10 +26899,10 @@ function validateSparkInvoiceSignature(invoice) {
|
|
|
27596
26899
|
identityPublicKey,
|
|
27597
26900
|
network
|
|
27598
26901
|
);
|
|
27599
|
-
const sec256k1PublicKey =
|
|
26902
|
+
const sec256k1PublicKey = import_secp256k16.secp256k1.Point.fromHex(identityPublicKey);
|
|
27600
26903
|
const compressed = sec256k1PublicKey.toBytes(true);
|
|
27601
26904
|
const xOnly = compressed.slice(1);
|
|
27602
|
-
const isValid =
|
|
26905
|
+
const isValid = import_secp256k16.schnorr.verify(signature, hash, xOnly);
|
|
27603
26906
|
if (!isValid) {
|
|
27604
26907
|
throw new ValidationError("Invalid signature", {
|
|
27605
26908
|
field: "signature",
|
|
@@ -27666,7 +26969,7 @@ function isSafeForNumber(bi) {
|
|
|
27666
26969
|
|
|
27667
26970
|
// src/utils/token-hashing.ts
|
|
27668
26971
|
init_buffer();
|
|
27669
|
-
var
|
|
26972
|
+
var import_sha210 = require("@noble/hashes/sha2");
|
|
27670
26973
|
var import_base4 = require("@scure/base");
|
|
27671
26974
|
function hashTokenTransaction(tokenTransaction, partialHash = false) {
|
|
27672
26975
|
switch (tokenTransaction.version) {
|
|
@@ -27688,7 +26991,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27688
26991
|
});
|
|
27689
26992
|
}
|
|
27690
26993
|
let allHashes = [];
|
|
27691
|
-
const versionHashObj =
|
|
26994
|
+
const versionHashObj = import_sha210.sha256.create();
|
|
27692
26995
|
const versionBytes = new Uint8Array(4);
|
|
27693
26996
|
new DataView(versionBytes.buffer).setUint32(
|
|
27694
26997
|
0,
|
|
@@ -27698,7 +27001,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27698
27001
|
);
|
|
27699
27002
|
versionHashObj.update(versionBytes);
|
|
27700
27003
|
allHashes.push(versionHashObj.digest());
|
|
27701
|
-
const typeHashObj =
|
|
27004
|
+
const typeHashObj = import_sha210.sha256.create();
|
|
27702
27005
|
const typeBytes = new Uint8Array(4);
|
|
27703
27006
|
let transactionType = 0;
|
|
27704
27007
|
if (tokenTransaction.tokenInputs?.$case === "mintInput") {
|
|
@@ -27729,7 +27032,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27729
27032
|
field: "tokenInputs.transferInput.outputsToSpend"
|
|
27730
27033
|
});
|
|
27731
27034
|
}
|
|
27732
|
-
const outputsLenHashObj2 =
|
|
27035
|
+
const outputsLenHashObj2 = import_sha210.sha256.create();
|
|
27733
27036
|
const outputsLenBytes2 = new Uint8Array(4);
|
|
27734
27037
|
new DataView(outputsLenBytes2.buffer).setUint32(
|
|
27735
27038
|
0,
|
|
@@ -27748,7 +27051,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27748
27051
|
index: i
|
|
27749
27052
|
});
|
|
27750
27053
|
}
|
|
27751
|
-
const hashObj2 =
|
|
27054
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
27752
27055
|
if (output.prevTokenTransactionHash) {
|
|
27753
27056
|
const prevHash = output.prevTokenTransactionHash;
|
|
27754
27057
|
if (output.prevTokenTransactionHash.length !== 32) {
|
|
@@ -27775,7 +27078,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27775
27078
|
allHashes.push(hashObj2.digest());
|
|
27776
27079
|
}
|
|
27777
27080
|
} else if (tokenTransaction.tokenInputs?.$case === "mintInput") {
|
|
27778
|
-
const hashObj2 =
|
|
27081
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
27779
27082
|
if (tokenTransaction.tokenInputs.mintInput.issuerPublicKey) {
|
|
27780
27083
|
const issuerPubKey = tokenTransaction.tokenInputs.mintInput.issuerPublicKey;
|
|
27781
27084
|
if (issuerPubKey.length === 0) {
|
|
@@ -27788,7 +27091,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27788
27091
|
}
|
|
27789
27092
|
hashObj2.update(issuerPubKey);
|
|
27790
27093
|
allHashes.push(hashObj2.digest());
|
|
27791
|
-
const tokenIdentifierHashObj =
|
|
27094
|
+
const tokenIdentifierHashObj = import_sha210.sha256.create();
|
|
27792
27095
|
if (tokenTransaction.tokenInputs.mintInput.tokenIdentifier) {
|
|
27793
27096
|
tokenIdentifierHashObj.update(
|
|
27794
27097
|
tokenTransaction.tokenInputs.mintInput.tokenIdentifier
|
|
@@ -27800,7 +27103,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27800
27103
|
}
|
|
27801
27104
|
} else if (tokenTransaction.tokenInputs?.$case === "createInput") {
|
|
27802
27105
|
const createInput = tokenTransaction.tokenInputs.createInput;
|
|
27803
|
-
const issuerPubKeyHashObj =
|
|
27106
|
+
const issuerPubKeyHashObj = import_sha210.sha256.create();
|
|
27804
27107
|
if (!createInput.issuerPublicKey || createInput.issuerPublicKey.length === 0) {
|
|
27805
27108
|
throw new ValidationError("issuer public key cannot be nil or empty", {
|
|
27806
27109
|
field: "tokenInputs.createInput.issuerPublicKey"
|
|
@@ -27808,7 +27111,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27808
27111
|
}
|
|
27809
27112
|
issuerPubKeyHashObj.update(createInput.issuerPublicKey);
|
|
27810
27113
|
allHashes.push(issuerPubKeyHashObj.digest());
|
|
27811
|
-
const tokenNameHashObj =
|
|
27114
|
+
const tokenNameHashObj = import_sha210.sha256.create();
|
|
27812
27115
|
if (!createInput.tokenName || createInput.tokenName.length === 0) {
|
|
27813
27116
|
throw new ValidationError("token name cannot be empty", {
|
|
27814
27117
|
field: "tokenInputs.createInput.tokenName"
|
|
@@ -27825,7 +27128,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27825
27128
|
const tokenNameEncoder = new TextEncoder();
|
|
27826
27129
|
tokenNameHashObj.update(tokenNameEncoder.encode(createInput.tokenName));
|
|
27827
27130
|
allHashes.push(tokenNameHashObj.digest());
|
|
27828
|
-
const tokenTickerHashObj =
|
|
27131
|
+
const tokenTickerHashObj = import_sha210.sha256.create();
|
|
27829
27132
|
if (!createInput.tokenTicker || createInput.tokenTicker.length === 0) {
|
|
27830
27133
|
throw new ValidationError("token ticker cannot be empty", {
|
|
27831
27134
|
field: "tokenInputs.createInput.tokenTicker"
|
|
@@ -27844,7 +27147,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27844
27147
|
tokenTickerEncoder.encode(createInput.tokenTicker)
|
|
27845
27148
|
);
|
|
27846
27149
|
allHashes.push(tokenTickerHashObj.digest());
|
|
27847
|
-
const decimalsHashObj =
|
|
27150
|
+
const decimalsHashObj = import_sha210.sha256.create();
|
|
27848
27151
|
const decimalsBytes = new Uint8Array(4);
|
|
27849
27152
|
new DataView(decimalsBytes.buffer).setUint32(
|
|
27850
27153
|
0,
|
|
@@ -27853,7 +27156,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27853
27156
|
);
|
|
27854
27157
|
decimalsHashObj.update(decimalsBytes);
|
|
27855
27158
|
allHashes.push(decimalsHashObj.digest());
|
|
27856
|
-
const maxSupplyHashObj =
|
|
27159
|
+
const maxSupplyHashObj = import_sha210.sha256.create();
|
|
27857
27160
|
if (!createInput.maxSupply) {
|
|
27858
27161
|
throw new ValidationError("max supply cannot be nil", {
|
|
27859
27162
|
field: "tokenInputs.createInput.maxSupply"
|
|
@@ -27869,12 +27172,12 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27869
27172
|
}
|
|
27870
27173
|
maxSupplyHashObj.update(createInput.maxSupply);
|
|
27871
27174
|
allHashes.push(maxSupplyHashObj.digest());
|
|
27872
|
-
const isFreezableHashObj =
|
|
27175
|
+
const isFreezableHashObj = import_sha210.sha256.create();
|
|
27873
27176
|
isFreezableHashObj.update(
|
|
27874
27177
|
new Uint8Array([createInput.isFreezable ? 1 : 0])
|
|
27875
27178
|
);
|
|
27876
27179
|
allHashes.push(isFreezableHashObj.digest());
|
|
27877
|
-
const creationEntityHashObj =
|
|
27180
|
+
const creationEntityHashObj = import_sha210.sha256.create();
|
|
27878
27181
|
if (!partialHash && createInput.creationEntityPublicKey) {
|
|
27879
27182
|
creationEntityHashObj.update(createInput.creationEntityPublicKey);
|
|
27880
27183
|
}
|
|
@@ -27885,7 +27188,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27885
27188
|
field: "tokenOutputs"
|
|
27886
27189
|
});
|
|
27887
27190
|
}
|
|
27888
|
-
const outputsLenHashObj =
|
|
27191
|
+
const outputsLenHashObj = import_sha210.sha256.create();
|
|
27889
27192
|
const outputsLenBytes = new Uint8Array(4);
|
|
27890
27193
|
new DataView(outputsLenBytes.buffer).setUint32(
|
|
27891
27194
|
0,
|
|
@@ -27901,7 +27204,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
27901
27204
|
index: i
|
|
27902
27205
|
});
|
|
27903
27206
|
}
|
|
27904
|
-
const hashObj2 =
|
|
27207
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
27905
27208
|
if (output.id && !partialHash) {
|
|
27906
27209
|
if (output.id.length === 0) {
|
|
27907
27210
|
throw new ValidationError(`output ID at index ${i} cannot be empty`, {
|
|
@@ -28002,7 +27305,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
28002
27305
|
}
|
|
28003
27306
|
return a.length - b.length;
|
|
28004
27307
|
});
|
|
28005
|
-
const operatorLenHashObj =
|
|
27308
|
+
const operatorLenHashObj = import_sha210.sha256.create();
|
|
28006
27309
|
const operatorLenBytes = new Uint8Array(4);
|
|
28007
27310
|
new DataView(operatorLenBytes.buffer).setUint32(
|
|
28008
27311
|
0,
|
|
@@ -28030,11 +27333,11 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
28030
27333
|
}
|
|
28031
27334
|
);
|
|
28032
27335
|
}
|
|
28033
|
-
const hashObj2 =
|
|
27336
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
28034
27337
|
hashObj2.update(pubKey);
|
|
28035
27338
|
allHashes.push(hashObj2.digest());
|
|
28036
27339
|
}
|
|
28037
|
-
const hashObj =
|
|
27340
|
+
const hashObj = import_sha210.sha256.create();
|
|
28038
27341
|
let networkBytes = new Uint8Array(4);
|
|
28039
27342
|
new DataView(networkBytes.buffer).setUint32(
|
|
28040
27343
|
0,
|
|
@@ -28044,7 +27347,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
28044
27347
|
);
|
|
28045
27348
|
hashObj.update(networkBytes);
|
|
28046
27349
|
allHashes.push(hashObj.digest());
|
|
28047
|
-
const clientTimestampHashObj =
|
|
27350
|
+
const clientTimestampHashObj = import_sha210.sha256.create();
|
|
28048
27351
|
const clientCreatedTs = tokenTransaction.clientCreatedTimestamp;
|
|
28049
27352
|
if (!clientCreatedTs) {
|
|
28050
27353
|
throw new ValidationError(
|
|
@@ -28064,7 +27367,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
28064
27367
|
clientTimestampHashObj.update(clientTimestampBytes);
|
|
28065
27368
|
allHashes.push(clientTimestampHashObj.digest());
|
|
28066
27369
|
if (!partialHash) {
|
|
28067
|
-
const expiryHashObj =
|
|
27370
|
+
const expiryHashObj = import_sha210.sha256.create();
|
|
28068
27371
|
const expiryTimeBytes = new Uint8Array(8);
|
|
28069
27372
|
const expiryUnixTime = tokenTransaction.expiryTime ? Math.floor(tokenTransaction.expiryTime.getTime() / 1e3) : 0;
|
|
28070
27373
|
new DataView(expiryTimeBytes.buffer).setBigUint64(
|
|
@@ -28076,9 +27379,9 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
|
28076
27379
|
expiryHashObj.update(expiryTimeBytes);
|
|
28077
27380
|
allHashes.push(expiryHashObj.digest());
|
|
28078
27381
|
}
|
|
28079
|
-
const finalHashObj =
|
|
27382
|
+
const finalHashObj = import_sha210.sha256.create();
|
|
28080
27383
|
const concatenatedHashes = new Uint8Array(
|
|
28081
|
-
allHashes.reduce((
|
|
27384
|
+
allHashes.reduce((sum2, hash) => sum2 + hash.length, 0)
|
|
28082
27385
|
);
|
|
28083
27386
|
let offset = 0;
|
|
28084
27387
|
for (const hash of allHashes) {
|
|
@@ -28095,7 +27398,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28095
27398
|
});
|
|
28096
27399
|
}
|
|
28097
27400
|
let allHashes = [];
|
|
28098
|
-
const versionHashObj =
|
|
27401
|
+
const versionHashObj = import_sha210.sha256.create();
|
|
28099
27402
|
const versionBytes = new Uint8Array(4);
|
|
28100
27403
|
new DataView(versionBytes.buffer).setUint32(
|
|
28101
27404
|
0,
|
|
@@ -28105,7 +27408,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28105
27408
|
);
|
|
28106
27409
|
versionHashObj.update(versionBytes);
|
|
28107
27410
|
allHashes.push(versionHashObj.digest());
|
|
28108
|
-
const typeHashObj =
|
|
27411
|
+
const typeHashObj = import_sha210.sha256.create();
|
|
28109
27412
|
const typeBytes = new Uint8Array(4);
|
|
28110
27413
|
let transactionType = 0;
|
|
28111
27414
|
if (tokenTransaction.tokenInputs?.$case === "mintInput") {
|
|
@@ -28136,7 +27439,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28136
27439
|
field: "tokenInputs.transferInput.outputsToSpend"
|
|
28137
27440
|
});
|
|
28138
27441
|
}
|
|
28139
|
-
const outputsLenHashObj2 =
|
|
27442
|
+
const outputsLenHashObj2 = import_sha210.sha256.create();
|
|
28140
27443
|
const outputsLenBytes2 = new Uint8Array(4);
|
|
28141
27444
|
new DataView(outputsLenBytes2.buffer).setUint32(
|
|
28142
27445
|
0,
|
|
@@ -28155,7 +27458,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28155
27458
|
index: i
|
|
28156
27459
|
});
|
|
28157
27460
|
}
|
|
28158
|
-
const hashObj2 =
|
|
27461
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
28159
27462
|
if (output.prevTokenTransactionHash) {
|
|
28160
27463
|
const prevHash = output.prevTokenTransactionHash;
|
|
28161
27464
|
if (output.prevTokenTransactionHash.length !== 32) {
|
|
@@ -28182,7 +27485,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28182
27485
|
allHashes.push(hashObj2.digest());
|
|
28183
27486
|
}
|
|
28184
27487
|
} else if (tokenTransaction.tokenInputs?.$case === "mintInput") {
|
|
28185
|
-
const hashObj2 =
|
|
27488
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
28186
27489
|
if (tokenTransaction.tokenInputs.mintInput.issuerPublicKey) {
|
|
28187
27490
|
const issuerPubKey = tokenTransaction.tokenInputs.mintInput.issuerPublicKey;
|
|
28188
27491
|
if (issuerPubKey.length === 0) {
|
|
@@ -28195,7 +27498,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28195
27498
|
}
|
|
28196
27499
|
hashObj2.update(issuerPubKey);
|
|
28197
27500
|
allHashes.push(hashObj2.digest());
|
|
28198
|
-
const tokenIdentifierHashObj =
|
|
27501
|
+
const tokenIdentifierHashObj = import_sha210.sha256.create();
|
|
28199
27502
|
if (tokenTransaction.tokenInputs.mintInput.tokenIdentifier) {
|
|
28200
27503
|
tokenIdentifierHashObj.update(
|
|
28201
27504
|
tokenTransaction.tokenInputs.mintInput.tokenIdentifier
|
|
@@ -28207,7 +27510,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28207
27510
|
}
|
|
28208
27511
|
} else if (tokenTransaction.tokenInputs?.$case === "createInput") {
|
|
28209
27512
|
const createInput = tokenTransaction.tokenInputs.createInput;
|
|
28210
|
-
const issuerPubKeyHashObj =
|
|
27513
|
+
const issuerPubKeyHashObj = import_sha210.sha256.create();
|
|
28211
27514
|
if (!createInput.issuerPublicKey || createInput.issuerPublicKey.length === 0) {
|
|
28212
27515
|
throw new ValidationError("issuer public key cannot be nil or empty", {
|
|
28213
27516
|
field: "tokenInputs.createInput.issuerPublicKey"
|
|
@@ -28215,7 +27518,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28215
27518
|
}
|
|
28216
27519
|
issuerPubKeyHashObj.update(createInput.issuerPublicKey);
|
|
28217
27520
|
allHashes.push(issuerPubKeyHashObj.digest());
|
|
28218
|
-
const tokenNameHashObj =
|
|
27521
|
+
const tokenNameHashObj = import_sha210.sha256.create();
|
|
28219
27522
|
if (!createInput.tokenName || createInput.tokenName.length === 0) {
|
|
28220
27523
|
throw new ValidationError("token name cannot be empty", {
|
|
28221
27524
|
field: "tokenInputs.createInput.tokenName"
|
|
@@ -28232,7 +27535,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28232
27535
|
const tokenNameEncoder = new TextEncoder();
|
|
28233
27536
|
tokenNameHashObj.update(tokenNameEncoder.encode(createInput.tokenName));
|
|
28234
27537
|
allHashes.push(tokenNameHashObj.digest());
|
|
28235
|
-
const tokenTickerHashObj =
|
|
27538
|
+
const tokenTickerHashObj = import_sha210.sha256.create();
|
|
28236
27539
|
if (!createInput.tokenTicker || createInput.tokenTicker.length === 0) {
|
|
28237
27540
|
throw new ValidationError("token ticker cannot be empty", {
|
|
28238
27541
|
field: "tokenInputs.createInput.tokenTicker"
|
|
@@ -28251,7 +27554,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28251
27554
|
tokenTickerEncoder.encode(createInput.tokenTicker)
|
|
28252
27555
|
);
|
|
28253
27556
|
allHashes.push(tokenTickerHashObj.digest());
|
|
28254
|
-
const decimalsHashObj =
|
|
27557
|
+
const decimalsHashObj = import_sha210.sha256.create();
|
|
28255
27558
|
const decimalsBytes = new Uint8Array(4);
|
|
28256
27559
|
new DataView(decimalsBytes.buffer).setUint32(
|
|
28257
27560
|
0,
|
|
@@ -28260,7 +27563,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28260
27563
|
);
|
|
28261
27564
|
decimalsHashObj.update(decimalsBytes);
|
|
28262
27565
|
allHashes.push(decimalsHashObj.digest());
|
|
28263
|
-
const maxSupplyHashObj =
|
|
27566
|
+
const maxSupplyHashObj = import_sha210.sha256.create();
|
|
28264
27567
|
if (!createInput.maxSupply) {
|
|
28265
27568
|
throw new ValidationError("max supply cannot be nil", {
|
|
28266
27569
|
field: "tokenInputs.createInput.maxSupply"
|
|
@@ -28276,12 +27579,12 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28276
27579
|
}
|
|
28277
27580
|
maxSupplyHashObj.update(createInput.maxSupply);
|
|
28278
27581
|
allHashes.push(maxSupplyHashObj.digest());
|
|
28279
|
-
const isFreezableHashObj =
|
|
27582
|
+
const isFreezableHashObj = import_sha210.sha256.create();
|
|
28280
27583
|
isFreezableHashObj.update(
|
|
28281
27584
|
new Uint8Array([createInput.isFreezable ? 1 : 0])
|
|
28282
27585
|
);
|
|
28283
27586
|
allHashes.push(isFreezableHashObj.digest());
|
|
28284
|
-
const creationEntityHashObj =
|
|
27587
|
+
const creationEntityHashObj = import_sha210.sha256.create();
|
|
28285
27588
|
if (!partialHash && createInput.creationEntityPublicKey) {
|
|
28286
27589
|
creationEntityHashObj.update(createInput.creationEntityPublicKey);
|
|
28287
27590
|
}
|
|
@@ -28292,7 +27595,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28292
27595
|
field: "tokenOutputs"
|
|
28293
27596
|
});
|
|
28294
27597
|
}
|
|
28295
|
-
const outputsLenHashObj =
|
|
27598
|
+
const outputsLenHashObj = import_sha210.sha256.create();
|
|
28296
27599
|
const outputsLenBytes = new Uint8Array(4);
|
|
28297
27600
|
new DataView(outputsLenBytes.buffer).setUint32(
|
|
28298
27601
|
0,
|
|
@@ -28308,7 +27611,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28308
27611
|
index: i
|
|
28309
27612
|
});
|
|
28310
27613
|
}
|
|
28311
|
-
const hashObj2 =
|
|
27614
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
28312
27615
|
if (output.id && !partialHash) {
|
|
28313
27616
|
if (output.id.length === 0) {
|
|
28314
27617
|
throw new ValidationError(`output ID at index ${i} cannot be empty`, {
|
|
@@ -28409,7 +27712,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28409
27712
|
}
|
|
28410
27713
|
return a.length - b.length;
|
|
28411
27714
|
});
|
|
28412
|
-
const operatorLenHashObj =
|
|
27715
|
+
const operatorLenHashObj = import_sha210.sha256.create();
|
|
28413
27716
|
const operatorLenBytes = new Uint8Array(4);
|
|
28414
27717
|
new DataView(operatorLenBytes.buffer).setUint32(
|
|
28415
27718
|
0,
|
|
@@ -28437,11 +27740,11 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28437
27740
|
}
|
|
28438
27741
|
);
|
|
28439
27742
|
}
|
|
28440
|
-
const hashObj2 =
|
|
27743
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
28441
27744
|
hashObj2.update(pubKey);
|
|
28442
27745
|
allHashes.push(hashObj2.digest());
|
|
28443
27746
|
}
|
|
28444
|
-
const hashObj =
|
|
27747
|
+
const hashObj = import_sha210.sha256.create();
|
|
28445
27748
|
let networkBytes = new Uint8Array(4);
|
|
28446
27749
|
new DataView(networkBytes.buffer).setUint32(
|
|
28447
27750
|
0,
|
|
@@ -28451,7 +27754,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28451
27754
|
);
|
|
28452
27755
|
hashObj.update(networkBytes);
|
|
28453
27756
|
allHashes.push(hashObj.digest());
|
|
28454
|
-
const clientTimestampHashObj =
|
|
27757
|
+
const clientTimestampHashObj = import_sha210.sha256.create();
|
|
28455
27758
|
const clientCreatedTs = tokenTransaction.clientCreatedTimestamp;
|
|
28456
27759
|
if (!clientCreatedTs) {
|
|
28457
27760
|
throw new ValidationError(
|
|
@@ -28471,7 +27774,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28471
27774
|
clientTimestampHashObj.update(clientTimestampBytes);
|
|
28472
27775
|
allHashes.push(clientTimestampHashObj.digest());
|
|
28473
27776
|
if (!partialHash) {
|
|
28474
|
-
const expiryHashObj =
|
|
27777
|
+
const expiryHashObj = import_sha210.sha256.create();
|
|
28475
27778
|
const expiryTimeBytes = new Uint8Array(8);
|
|
28476
27779
|
const expiryUnixTime = tokenTransaction.expiryTime ? Math.floor(tokenTransaction.expiryTime.getTime() / 1e3) : 0;
|
|
28477
27780
|
new DataView(expiryTimeBytes.buffer).setBigUint64(
|
|
@@ -28484,7 +27787,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28484
27787
|
allHashes.push(expiryHashObj.digest());
|
|
28485
27788
|
}
|
|
28486
27789
|
const attachments = tokenTransaction.invoiceAttachments;
|
|
28487
|
-
const lenHash =
|
|
27790
|
+
const lenHash = import_sha210.sha256.create();
|
|
28488
27791
|
const lenBytes = new Uint8Array(4);
|
|
28489
27792
|
new DataView(lenBytes.buffer).setUint32(
|
|
28490
27793
|
0,
|
|
@@ -28545,13 +27848,13 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
|
|
|
28545
27848
|
});
|
|
28546
27849
|
const encoder = new TextEncoder();
|
|
28547
27850
|
for (const k of sortedInvoices) {
|
|
28548
|
-
const h =
|
|
27851
|
+
const h = import_sha210.sha256.create();
|
|
28549
27852
|
h.update(encoder.encode(k.raw));
|
|
28550
27853
|
allHashes.push(h.digest());
|
|
28551
27854
|
}
|
|
28552
|
-
const finalHashObj =
|
|
27855
|
+
const finalHashObj = import_sha210.sha256.create();
|
|
28553
27856
|
const concatenatedHashes = new Uint8Array(
|
|
28554
|
-
allHashes.reduce((
|
|
27857
|
+
allHashes.reduce((sum2, hash) => sum2 + hash.length, 0)
|
|
28555
27858
|
);
|
|
28556
27859
|
let offset = 0;
|
|
28557
27860
|
for (const hash of allHashes) {
|
|
@@ -28572,7 +27875,7 @@ function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
|
|
|
28572
27875
|
}
|
|
28573
27876
|
let allHashes = [];
|
|
28574
27877
|
if (payload.finalTokenTransactionHash) {
|
|
28575
|
-
const hashObj2 =
|
|
27878
|
+
const hashObj2 = import_sha210.sha256.create();
|
|
28576
27879
|
if (payload.finalTokenTransactionHash.length !== 32) {
|
|
28577
27880
|
throw new ValidationError(`invalid final token transaction hash length`, {
|
|
28578
27881
|
field: "finalTokenTransactionHash",
|
|
@@ -28594,12 +27897,12 @@ function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
|
|
|
28594
27897
|
field: "operatorIdentityPublicKey"
|
|
28595
27898
|
});
|
|
28596
27899
|
}
|
|
28597
|
-
const hashObj =
|
|
27900
|
+
const hashObj = import_sha210.sha256.create();
|
|
28598
27901
|
hashObj.update(payload.operatorIdentityPublicKey);
|
|
28599
27902
|
allHashes.push(hashObj.digest());
|
|
28600
|
-
const finalHashObj =
|
|
27903
|
+
const finalHashObj = import_sha210.sha256.create();
|
|
28601
27904
|
const concatenatedHashes = new Uint8Array(
|
|
28602
|
-
allHashes.reduce((
|
|
27905
|
+
allHashes.reduce((sum2, hash) => sum2 + hash.length, 0)
|
|
28603
27906
|
);
|
|
28604
27907
|
let offset = 0;
|
|
28605
27908
|
for (const hash of allHashes) {
|
|
@@ -29002,11 +28305,11 @@ function validateTokenTransaction(finalTokenTransaction, partialTokenTransaction
|
|
|
29002
28305
|
|
|
29003
28306
|
// src/utils/token-transactions.ts
|
|
29004
28307
|
init_buffer();
|
|
29005
|
-
var
|
|
28308
|
+
var import_utils11 = require("@noble/curves/utils");
|
|
29006
28309
|
function sumAvailableTokens(outputs) {
|
|
29007
28310
|
try {
|
|
29008
28311
|
return outputs.reduce(
|
|
29009
|
-
(
|
|
28312
|
+
(sum2, output) => sum2 + BigInt((0, import_utils11.bytesToNumberBE)(output.output.tokenAmount)),
|
|
29010
28313
|
BigInt(0)
|
|
29011
28314
|
);
|
|
29012
28315
|
} catch (error) {
|
|
@@ -29037,7 +28340,7 @@ function filterTokenBalanceForTokenIdentifier(tokenBalances, tokenIdentifier) {
|
|
|
29037
28340
|
}
|
|
29038
28341
|
const tokenIdentifierBytes = decodeBech32mTokenIdentifier(tokenIdentifier).tokenIdentifier;
|
|
29039
28342
|
const tokenBalance = [...tokenBalances.entries()].find(
|
|
29040
|
-
([, info]) => (0,
|
|
28343
|
+
([, info]) => (0, import_utils11.equalBytes)(info.tokenMetadata.rawTokenIdentifier, tokenIdentifierBytes)
|
|
29041
28344
|
);
|
|
29042
28345
|
if (!tokenBalance) {
|
|
29043
28346
|
return {
|
|
@@ -29073,7 +28376,7 @@ var TokenTransactionService = class {
|
|
|
29073
28376
|
});
|
|
29074
28377
|
}
|
|
29075
28378
|
const totalTokenAmount = receiverOutputs.reduce(
|
|
29076
|
-
(
|
|
28379
|
+
(sum2, transfer) => sum2 + transfer.tokenAmount,
|
|
29077
28380
|
0n
|
|
29078
28381
|
);
|
|
29079
28382
|
let outputsToUse;
|
|
@@ -29131,14 +28434,14 @@ var TokenTransactionService = class {
|
|
|
29131
28434
|
}
|
|
29132
28435
|
if (receiverAddress.sparkInvoiceFields) {
|
|
29133
28436
|
return {
|
|
29134
|
-
receiverPublicKey: (0,
|
|
28437
|
+
receiverPublicKey: (0, import_utils13.hexToBytes)(receiverAddress.identityPublicKey),
|
|
29135
28438
|
rawTokenIdentifier,
|
|
29136
28439
|
tokenAmount: transfer.tokenAmount,
|
|
29137
28440
|
sparkInvoice: transfer.receiverSparkAddress
|
|
29138
28441
|
};
|
|
29139
28442
|
}
|
|
29140
28443
|
return {
|
|
29141
|
-
receiverPublicKey: (0,
|
|
28444
|
+
receiverPublicKey: (0, import_utils13.hexToBytes)(receiverAddress.identityPublicKey),
|
|
29142
28445
|
rawTokenIdentifier,
|
|
29143
28446
|
tokenAmount: transfer.tokenAmount
|
|
29144
28447
|
};
|
|
@@ -29161,14 +28464,14 @@ var TokenTransactionService = class {
|
|
|
29161
28464
|
);
|
|
29162
28465
|
const availableTokenAmount = sumAvailableTokens(selectedOutputs);
|
|
29163
28466
|
const totalRequestedAmount = tokenOutputData.reduce(
|
|
29164
|
-
(
|
|
28467
|
+
(sum2, output) => sum2 + output.tokenAmount,
|
|
29165
28468
|
0n
|
|
29166
28469
|
);
|
|
29167
28470
|
const tokenOutputs = tokenOutputData.map(
|
|
29168
28471
|
(output) => ({
|
|
29169
28472
|
ownerPublicKey: output.receiverPublicKey,
|
|
29170
28473
|
tokenIdentifier: output.rawTokenIdentifier,
|
|
29171
|
-
tokenAmount: (0,
|
|
28474
|
+
tokenAmount: (0, import_utils12.numberToBytesBE)(output.tokenAmount, 16)
|
|
29172
28475
|
})
|
|
29173
28476
|
);
|
|
29174
28477
|
if (availableTokenAmount > totalRequestedAmount) {
|
|
@@ -29177,7 +28480,7 @@ var TokenTransactionService = class {
|
|
|
29177
28480
|
tokenOutputs.push({
|
|
29178
28481
|
ownerPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
29179
28482
|
tokenIdentifier: firstTokenIdentifierBytes,
|
|
29180
|
-
tokenAmount: (0,
|
|
28483
|
+
tokenAmount: (0, import_utils12.numberToBytesBE)(changeAmount, 16)
|
|
29181
28484
|
});
|
|
29182
28485
|
}
|
|
29183
28486
|
return {
|
|
@@ -29204,7 +28507,7 @@ var TokenTransactionService = class {
|
|
|
29204
28507
|
for (const [_, operator] of Object.entries(
|
|
29205
28508
|
this.config.getSigningOperators()
|
|
29206
28509
|
)) {
|
|
29207
|
-
operatorKeys.push((0,
|
|
28510
|
+
operatorKeys.push((0, import_utils13.hexToBytes)(operator.identityPublicKey));
|
|
29208
28511
|
}
|
|
29209
28512
|
return operatorKeys;
|
|
29210
28513
|
}
|
|
@@ -29221,7 +28524,7 @@ var TokenTransactionService = class {
|
|
|
29221
28524
|
finalTokenTransactionHash,
|
|
29222
28525
|
signingOperators
|
|
29223
28526
|
);
|
|
29224
|
-
return (0,
|
|
28527
|
+
return (0, import_utils12.bytesToHex)(finalTokenTransactionHash);
|
|
29225
28528
|
}
|
|
29226
28529
|
async startTokenTransaction(tokenTransaction, signingOperators, outputsToSpendSigningPublicKeys, outputsToSpendCommitments) {
|
|
29227
28530
|
const sparkClient = await this.connectionManager.createSparkTokenClient(
|
|
@@ -29396,10 +28699,10 @@ var TokenTransactionService = class {
|
|
|
29396
28699
|
});
|
|
29397
28700
|
}
|
|
29398
28701
|
for (const ownerPublicKey of ownerPublicKeys) {
|
|
29399
|
-
isValidPublicKey((0,
|
|
28702
|
+
isValidPublicKey((0, import_utils12.bytesToHex)(ownerPublicKey));
|
|
29400
28703
|
}
|
|
29401
28704
|
for (const issuerPublicKey of issuerPublicKeys) {
|
|
29402
|
-
isValidPublicKey((0,
|
|
28705
|
+
isValidPublicKey((0, import_utils12.bytesToHex)(issuerPublicKey));
|
|
29403
28706
|
}
|
|
29404
28707
|
for (const tokenIdentifier of tokenIdentifiers) {
|
|
29405
28708
|
if (tokenIdentifier.length !== 32) {
|
|
@@ -29467,8 +28770,8 @@ var TokenTransactionService = class {
|
|
|
29467
28770
|
this.config.getCoordinatorAddress()
|
|
29468
28771
|
);
|
|
29469
28772
|
let queryParams = {
|
|
29470
|
-
issuerPublicKeys: issuerPublicKeys?.map(
|
|
29471
|
-
ownerPublicKeys: ownerPublicKeys?.map(
|
|
28773
|
+
issuerPublicKeys: issuerPublicKeys?.map(import_utils13.hexToBytes),
|
|
28774
|
+
ownerPublicKeys: ownerPublicKeys?.map(import_utils13.hexToBytes),
|
|
29472
28775
|
tokenIdentifiers: tokenIdentifiers?.map((identifier) => {
|
|
29473
28776
|
const { tokenIdentifier } = decodeBech32mTokenIdentifier(
|
|
29474
28777
|
identifier,
|
|
@@ -29476,7 +28779,7 @@ var TokenTransactionService = class {
|
|
|
29476
28779
|
);
|
|
29477
28780
|
return tokenIdentifier;
|
|
29478
28781
|
}),
|
|
29479
|
-
tokenTransactionHashes: tokenTransactionHashes?.map(
|
|
28782
|
+
tokenTransactionHashes: tokenTransactionHashes?.map(import_utils13.hexToBytes),
|
|
29480
28783
|
outputIds: outputIds || [],
|
|
29481
28784
|
limit: pageSize,
|
|
29482
28785
|
offset
|
|
@@ -29511,7 +28814,7 @@ var TokenTransactionService = class {
|
|
|
29511
28814
|
});
|
|
29512
28815
|
}
|
|
29513
28816
|
const exactMatch = tokenOutputs.find(
|
|
29514
|
-
(item) => (0,
|
|
28817
|
+
(item) => (0, import_utils12.bytesToNumberBE)(item.output.tokenAmount) === tokenAmount
|
|
29515
28818
|
);
|
|
29516
28819
|
if (exactMatch) {
|
|
29517
28820
|
return [exactMatch];
|
|
@@ -29522,7 +28825,7 @@ var TokenTransactionService = class {
|
|
|
29522
28825
|
for (const outputWithPreviousTransactionData of tokenOutputs) {
|
|
29523
28826
|
if (remainingAmount <= 0n) break;
|
|
29524
28827
|
selectedOutputs.push(outputWithPreviousTransactionData);
|
|
29525
|
-
remainingAmount -= (0,
|
|
28828
|
+
remainingAmount -= (0, import_utils12.bytesToNumberBE)(
|
|
29526
28829
|
outputWithPreviousTransactionData.output.tokenAmount
|
|
29527
28830
|
);
|
|
29528
28831
|
}
|
|
@@ -29537,22 +28840,22 @@ var TokenTransactionService = class {
|
|
|
29537
28840
|
sortTokenOutputsByStrategy(tokenOutputs, strategy) {
|
|
29538
28841
|
if (strategy === "SMALL_FIRST") {
|
|
29539
28842
|
tokenOutputs.sort((a, b) => {
|
|
29540
|
-
|
|
29541
|
-
|
|
29542
|
-
|
|
28843
|
+
const amountA = (0, import_utils12.bytesToNumberBE)(a.output.tokenAmount);
|
|
28844
|
+
const amountB = (0, import_utils12.bytesToNumberBE)(b.output.tokenAmount);
|
|
28845
|
+
return amountA < amountB ? -1 : amountA > amountB ? 1 : 0;
|
|
29543
28846
|
});
|
|
29544
28847
|
} else {
|
|
29545
28848
|
tokenOutputs.sort((a, b) => {
|
|
29546
|
-
|
|
29547
|
-
|
|
29548
|
-
|
|
28849
|
+
const amountA = (0, import_utils12.bytesToNumberBE)(a.output.tokenAmount);
|
|
28850
|
+
const amountB = (0, import_utils12.bytesToNumberBE)(b.output.tokenAmount);
|
|
28851
|
+
return amountB < amountA ? -1 : amountB > amountA ? 1 : 0;
|
|
29549
28852
|
});
|
|
29550
28853
|
}
|
|
29551
28854
|
}
|
|
29552
28855
|
// Helper function for deciding if the signer public key is the identity public key
|
|
29553
28856
|
async signMessageWithKey(message, publicKey) {
|
|
29554
28857
|
const tokenSignatures = this.config.getTokenSignatures();
|
|
29555
|
-
if ((0,
|
|
28858
|
+
if ((0, import_utils12.bytesToHex)(publicKey) === (0, import_utils12.bytesToHex)(await this.config.signer.getIdentityPublicKey())) {
|
|
29556
28859
|
if (tokenSignatures === "SCHNORR") {
|
|
29557
28860
|
return await this.config.signer.signSchnorrWithIdentityKey(message);
|
|
29558
28861
|
} else {
|
|
@@ -29561,8 +28864,8 @@ var TokenTransactionService = class {
|
|
|
29561
28864
|
} else {
|
|
29562
28865
|
throw new ValidationError("Invalid public key", {
|
|
29563
28866
|
field: "publicKey",
|
|
29564
|
-
value: (0,
|
|
29565
|
-
expected: (0,
|
|
28867
|
+
value: (0, import_utils12.bytesToHex)(publicKey),
|
|
28868
|
+
expected: (0, import_utils12.bytesToHex)(await this.config.signer.getIdentityPublicKey())
|
|
29566
28869
|
});
|
|
29567
28870
|
}
|
|
29568
28871
|
}
|
|
@@ -29581,7 +28884,7 @@ var TokenTransactionService = class {
|
|
|
29581
28884
|
}
|
|
29582
28885
|
const payload = {
|
|
29583
28886
|
finalTokenTransactionHash,
|
|
29584
|
-
operatorIdentityPublicKey: (0,
|
|
28887
|
+
operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
|
|
29585
28888
|
};
|
|
29586
28889
|
const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
|
|
29587
28890
|
const ownerSignature = await this.signMessageWithKey(
|
|
@@ -29603,7 +28906,7 @@ var TokenTransactionService = class {
|
|
|
29603
28906
|
}
|
|
29604
28907
|
const payload = {
|
|
29605
28908
|
finalTokenTransactionHash,
|
|
29606
|
-
operatorIdentityPublicKey: (0,
|
|
28909
|
+
operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
|
|
29607
28910
|
};
|
|
29608
28911
|
const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
|
|
29609
28912
|
const ownerSignature = await this.signMessageWithKey(
|
|
@@ -29619,7 +28922,7 @@ var TokenTransactionService = class {
|
|
|
29619
28922
|
for (let i = 0; i < transferInput.outputsToSpend.length; i++) {
|
|
29620
28923
|
const payload = {
|
|
29621
28924
|
finalTokenTransactionHash,
|
|
29622
|
-
operatorIdentityPublicKey: (0,
|
|
28925
|
+
operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
|
|
29623
28926
|
};
|
|
29624
28927
|
const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
|
|
29625
28928
|
let ownerSignature;
|
|
@@ -29636,315 +28939,1020 @@ var TokenTransactionService = class {
|
|
|
29636
28939
|
}
|
|
29637
28940
|
inputTtxoSignaturesPerOperator.push({
|
|
29638
28941
|
ttxoSignatures,
|
|
29639
|
-
operatorIdentityPublicKey: (0,
|
|
28942
|
+
operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
|
|
28943
|
+
});
|
|
28944
|
+
}
|
|
28945
|
+
return inputTtxoSignaturesPerOperator;
|
|
28946
|
+
}
|
|
28947
|
+
};
|
|
28948
|
+
|
|
28949
|
+
// src/utils/adaptor-signature.ts
|
|
28950
|
+
init_buffer();
|
|
28951
|
+
var import_modular = require("@noble/curves/abstract/modular");
|
|
28952
|
+
var import_secp256k17 = require("@noble/curves/secp256k1");
|
|
28953
|
+
var import_utils14 = require("@noble/curves/utils");
|
|
28954
|
+
function generateSignatureFromExistingAdaptor(signature, adaptorPrivateKeyBytes) {
|
|
28955
|
+
const { r, s: s2 } = parseSignature(signature);
|
|
28956
|
+
const sBigInt = (0, import_utils14.bytesToNumberBE)(s2);
|
|
28957
|
+
const tBigInt = (0, import_utils14.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
28958
|
+
const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k17.secp256k1.CURVE.n);
|
|
28959
|
+
const newSignature = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(newS, 32)]);
|
|
28960
|
+
return newSignature;
|
|
28961
|
+
}
|
|
28962
|
+
function generateAdaptorFromSignature(signature) {
|
|
28963
|
+
const adaptorPrivateKey = import_secp256k17.secp256k1.utils.randomPrivateKey();
|
|
28964
|
+
const { r, s: s2 } = parseSignature(signature);
|
|
28965
|
+
const sBigInt = (0, import_utils14.bytesToNumberBE)(s2);
|
|
28966
|
+
const tBigInt = (0, import_utils14.bytesToNumberBE)(adaptorPrivateKey);
|
|
28967
|
+
const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k17.secp256k1.CURVE.n);
|
|
28968
|
+
const newSignature = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(newS, 32)]);
|
|
28969
|
+
return {
|
|
28970
|
+
adaptorSignature: newSignature,
|
|
28971
|
+
adaptorPrivateKey
|
|
28972
|
+
};
|
|
28973
|
+
}
|
|
28974
|
+
function validateOutboundAdaptorSignature(pubkey, hash, signature, adaptorPubkey) {
|
|
28975
|
+
return schnorrVerifyWithAdaptor(
|
|
28976
|
+
signature,
|
|
28977
|
+
hash,
|
|
28978
|
+
pubkey,
|
|
28979
|
+
adaptorPubkey,
|
|
28980
|
+
false
|
|
28981
|
+
);
|
|
28982
|
+
}
|
|
28983
|
+
function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes) {
|
|
28984
|
+
const { r, s: s2 } = parseSignature(signature);
|
|
28985
|
+
const sBigInt = (0, import_utils14.bytesToNumberBE)(s2);
|
|
28986
|
+
const adaptorPrivateKey = (0, import_utils14.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
28987
|
+
const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k17.secp256k1.CURVE.n);
|
|
28988
|
+
const newSig = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(newS, 32)]);
|
|
28989
|
+
try {
|
|
28990
|
+
if (import_secp256k17.schnorr.verify(newSig, hash, pubkey)) {
|
|
28991
|
+
return newSig;
|
|
28992
|
+
}
|
|
28993
|
+
} catch (e) {
|
|
28994
|
+
console.error("[applyAdaptorToSignature] Addition verification failed:", e);
|
|
28995
|
+
}
|
|
28996
|
+
const altS = (0, import_modular.mod)(sBigInt - adaptorPrivateKey, import_secp256k17.secp256k1.CURVE.n);
|
|
28997
|
+
const altSig = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(altS, 32)]);
|
|
28998
|
+
try {
|
|
28999
|
+
if (import_secp256k17.schnorr.verify(altSig, hash, pubkey)) {
|
|
29000
|
+
return altSig;
|
|
29001
|
+
}
|
|
29002
|
+
} catch (e) {
|
|
29003
|
+
console.error(
|
|
29004
|
+
"[applyAdaptorToSignature] Subtraction verification failed:",
|
|
29005
|
+
e
|
|
29006
|
+
);
|
|
29007
|
+
}
|
|
29008
|
+
throw new Error("Cannot apply adaptor to signature");
|
|
29009
|
+
}
|
|
29010
|
+
function schnorrVerifyWithAdaptor(signature, hash, pubKeyBytes, adaptorPubkey, inbound) {
|
|
29011
|
+
if (hash.length !== 32) {
|
|
29012
|
+
throw new Error(`wrong size for message (got ${hash.length}, want 32)`);
|
|
29013
|
+
}
|
|
29014
|
+
const pubKey = import_secp256k17.schnorr.utils.lift_x((0, import_utils14.bytesToNumberBE)(pubKeyBytes));
|
|
29015
|
+
pubKey.assertValidity();
|
|
29016
|
+
const { r, s: s2 } = parseSignature(signature);
|
|
29017
|
+
const commitmenet = import_secp256k17.schnorr.utils.taggedHash(
|
|
29018
|
+
"BIP0340/challenge",
|
|
29019
|
+
r,
|
|
29020
|
+
pubKey.toBytes().slice(1),
|
|
29021
|
+
hash
|
|
29022
|
+
);
|
|
29023
|
+
if (commitmenet.length > 32) {
|
|
29024
|
+
throw new Error("hash of (r || P || m) too big");
|
|
29025
|
+
}
|
|
29026
|
+
const e = (0, import_modular.mod)((0, import_utils14.bytesToNumberBE)(commitmenet), import_secp256k17.secp256k1.CURVE.n);
|
|
29027
|
+
const negE = (0, import_modular.mod)(-e, import_secp256k17.secp256k1.CURVE.n);
|
|
29028
|
+
const sG = import_secp256k17.secp256k1.Point.BASE.multiplyUnsafe((0, import_utils14.bytesToNumberBE)(s2));
|
|
29029
|
+
const eP = pubKey.multiplyUnsafe(negE);
|
|
29030
|
+
const R = sG.add(eP);
|
|
29031
|
+
if (R.is0()) {
|
|
29032
|
+
throw new Error("R is zero");
|
|
29033
|
+
}
|
|
29034
|
+
R.assertValidity();
|
|
29035
|
+
const adaptorPoint = import_secp256k17.secp256k1.Point.fromHex(adaptorPubkey);
|
|
29036
|
+
const newR = R.add(adaptorPoint);
|
|
29037
|
+
if (!inbound && newR.equals(import_secp256k17.secp256k1.Point.ZERO)) {
|
|
29038
|
+
throw new Error("calculated R point is the point at infinity");
|
|
29039
|
+
}
|
|
29040
|
+
newR.assertValidity();
|
|
29041
|
+
if (newR.y % 2n !== 0n) {
|
|
29042
|
+
throw new Error("calculated R y-value is odd");
|
|
29043
|
+
}
|
|
29044
|
+
const rNum = (0, import_utils14.bytesToNumberBE)(r);
|
|
29045
|
+
if (newR.toAffine().x !== rNum) {
|
|
29046
|
+
throw new Error("calculated R point was not given R");
|
|
29047
|
+
}
|
|
29048
|
+
return true;
|
|
29049
|
+
}
|
|
29050
|
+
function parseSignature(signature) {
|
|
29051
|
+
if (signature.length < 64) {
|
|
29052
|
+
throw new ValidationError("Signature too short", {
|
|
29053
|
+
expectedLength: 64,
|
|
29054
|
+
actualLength: signature.length
|
|
29055
|
+
});
|
|
29056
|
+
}
|
|
29057
|
+
if (signature.length > 64) {
|
|
29058
|
+
throw new ValidationError("Signature too long", {
|
|
29059
|
+
expectedLength: 64,
|
|
29060
|
+
actualLength: signature.length
|
|
29061
|
+
});
|
|
29062
|
+
}
|
|
29063
|
+
const r = signature.slice(0, 32);
|
|
29064
|
+
const s2 = signature.slice(32, 64);
|
|
29065
|
+
if ((0, import_utils14.bytesToNumberBE)(r) >= import_secp256k17.secp256k1.CURVE.Fp.ORDER) {
|
|
29066
|
+
throw new ValidationError("Invalid signature: r >= field prime", {
|
|
29067
|
+
rValue: (0, import_utils14.bytesToNumberBE)(r),
|
|
29068
|
+
fieldPrime: import_secp256k17.secp256k1.CURVE.Fp.ORDER
|
|
29069
|
+
});
|
|
29070
|
+
}
|
|
29071
|
+
if ((0, import_utils14.bytesToNumberBE)(s2) >= import_secp256k17.secp256k1.CURVE.n) {
|
|
29072
|
+
throw new ValidationError("Invalid signature: s >= group order", {
|
|
29073
|
+
sValue: (0, import_utils14.bytesToNumberBE)(s2),
|
|
29074
|
+
groupOrder: import_secp256k17.secp256k1.CURVE.n
|
|
29075
|
+
});
|
|
29076
|
+
}
|
|
29077
|
+
return { r, s: s2 };
|
|
29078
|
+
}
|
|
29079
|
+
|
|
29080
|
+
// src/spark-wallet/spark-wallet.ts
|
|
29081
|
+
var import_sha212 = require("@noble/hashes/sha2");
|
|
29082
|
+
var import_api = require("@opentelemetry/api");
|
|
29083
|
+
var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
29084
|
+
var import_eventemitter3 = require("eventemitter3");
|
|
29085
|
+
var import_nice_grpc_common = require("nice-grpc-common");
|
|
29086
|
+
|
|
29087
|
+
// src/constants.ts
|
|
29088
|
+
init_buffer();
|
|
29089
|
+
var import_core11 = require("@lightsparkdev/core");
|
|
29090
|
+
var isReactNative = "navigator" in globalThis && navigator.product === "ReactNative";
|
|
29091
|
+
var isBun = "Bun" in globalThis;
|
|
29092
|
+
var isWebExtension = (
|
|
29093
|
+
/* globalThis.chrome actually exists in extension contexts for all browsers for legacy reasons: */
|
|
29094
|
+
"chrome" in globalThis && globalThis.chrome.runtime?.id
|
|
29095
|
+
);
|
|
29096
|
+
var userAgent = "navigator" in globalThis ? globalThis.navigator.userAgent || "unknown-user-agent" : void 0;
|
|
29097
|
+
var packageVersion = true ? "0.3.7" : "unknown";
|
|
29098
|
+
var baseEnvStr = "unknown";
|
|
29099
|
+
if (isBun) {
|
|
29100
|
+
const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
|
|
29101
|
+
baseEnvStr = `bun/${bunVersion}`;
|
|
29102
|
+
} else if (import_core11.isNode) {
|
|
29103
|
+
baseEnvStr = `node/${globalThis.process.version}`;
|
|
29104
|
+
} else if (isReactNative) {
|
|
29105
|
+
baseEnvStr = "react-native";
|
|
29106
|
+
} else if (import_core11.isBare) {
|
|
29107
|
+
const bareVersion = Bare.version;
|
|
29108
|
+
baseEnvStr = `bare/${bareVersion}`;
|
|
29109
|
+
} else if (isWebExtension) {
|
|
29110
|
+
const protocol = "location" in globalThis ? globalThis.location.protocol : "";
|
|
29111
|
+
const extScriptType = "window" in globalThis ? "content-script" : "background-script";
|
|
29112
|
+
baseEnvStr = `web-extension/${protocol.replace(":", "")}/${extScriptType}/${userAgent}`;
|
|
29113
|
+
} else {
|
|
29114
|
+
baseEnvStr = `browser/${userAgent}`;
|
|
29115
|
+
}
|
|
29116
|
+
var clientEnv = `js-spark-sdk/${packageVersion} ${baseEnvStr}`;
|
|
29117
|
+
|
|
29118
|
+
// src/services/signing.ts
|
|
29119
|
+
init_buffer();
|
|
29120
|
+
var import_utils15 = require("@noble/curves/utils");
|
|
29121
|
+
var SigningService = class {
|
|
29122
|
+
config;
|
|
29123
|
+
constructor(config) {
|
|
29124
|
+
this.config = config;
|
|
29125
|
+
}
|
|
29126
|
+
async signRefundsInternal(refundTx, sighash, leaf, signingCommitments) {
|
|
29127
|
+
const leafSigningJobs = [];
|
|
29128
|
+
const signingCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29129
|
+
if (!signingCommitments) {
|
|
29130
|
+
throw new ValidationError("Invalid signing commitments", {
|
|
29131
|
+
field: "signingNonceCommitments",
|
|
29132
|
+
value: signingCommitments,
|
|
29133
|
+
expected: "Non-null signing commitments"
|
|
29134
|
+
});
|
|
29135
|
+
}
|
|
29136
|
+
const signingResult = await this.config.signer.signFrost({
|
|
29137
|
+
message: sighash,
|
|
29138
|
+
keyDerivation: leaf.keyDerivation,
|
|
29139
|
+
publicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
29140
|
+
leaf.keyDerivation
|
|
29141
|
+
),
|
|
29142
|
+
selfCommitment: signingCommitment,
|
|
29143
|
+
statechainCommitments: signingCommitments,
|
|
29144
|
+
adaptorPubKey: new Uint8Array(),
|
|
29145
|
+
verifyingKey: leaf.leaf.verifyingPublicKey
|
|
29146
|
+
});
|
|
29147
|
+
leafSigningJobs.push({
|
|
29148
|
+
leafId: leaf.leaf.id,
|
|
29149
|
+
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
29150
|
+
leaf.keyDerivation
|
|
29151
|
+
),
|
|
29152
|
+
rawTx: refundTx.toBytes(),
|
|
29153
|
+
signingNonceCommitment: signingCommitment.commitment,
|
|
29154
|
+
userSignature: signingResult,
|
|
29155
|
+
signingCommitments: {
|
|
29156
|
+
signingCommitments
|
|
29157
|
+
}
|
|
29158
|
+
});
|
|
29159
|
+
return leafSigningJobs;
|
|
29160
|
+
}
|
|
29161
|
+
async signRefunds(leaves, receiverIdentityPubkey, cpfpSigningCommitments, directSigningCommitments, directFromCpfpSigningCommitments) {
|
|
29162
|
+
const cpfpLeafSigningJobs = [];
|
|
29163
|
+
const directLeafSigningJobs = [];
|
|
29164
|
+
const directFromCpfpLeafSigningJobs = [];
|
|
29165
|
+
for (let i = 0; i < leaves.length; i++) {
|
|
29166
|
+
const leaf = leaves[i];
|
|
29167
|
+
if (!leaf?.leaf) {
|
|
29168
|
+
throw new ValidationError("Leaf not found in signRefunds", {
|
|
29169
|
+
field: "leaf",
|
|
29170
|
+
value: leaf,
|
|
29171
|
+
expected: "Non-null leaf"
|
|
29172
|
+
});
|
|
29173
|
+
}
|
|
29174
|
+
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
29175
|
+
const cpfpNodeOutPoint = {
|
|
29176
|
+
txid: (0, import_utils15.hexToBytes)(getTxId(nodeTx)),
|
|
29177
|
+
index: 0
|
|
29178
|
+
};
|
|
29179
|
+
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
29180
|
+
const sequence = currRefundTx.getInput(0).sequence;
|
|
29181
|
+
if (!sequence) {
|
|
29182
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
29183
|
+
field: "sequence",
|
|
29184
|
+
value: currRefundTx.getInput(0),
|
|
29185
|
+
expected: "Non-null sequence"
|
|
29186
|
+
});
|
|
29187
|
+
}
|
|
29188
|
+
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
29189
|
+
const amountSats = currRefundTx.getOutput(0).amount;
|
|
29190
|
+
if (amountSats === void 0) {
|
|
29191
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
29192
|
+
field: "amount",
|
|
29193
|
+
value: currRefundTx.getOutput(0),
|
|
29194
|
+
expected: "Non-null amount"
|
|
29195
|
+
});
|
|
29196
|
+
}
|
|
29197
|
+
let directNodeTx;
|
|
29198
|
+
let directNodeOutPoint;
|
|
29199
|
+
if (leaf.leaf.directTx.length > 0) {
|
|
29200
|
+
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
29201
|
+
directNodeOutPoint = {
|
|
29202
|
+
txid: (0, import_utils15.hexToBytes)(getTxId(directNodeTx)),
|
|
29203
|
+
index: 0
|
|
29204
|
+
};
|
|
29205
|
+
}
|
|
29206
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
29207
|
+
sequence: nextSequence,
|
|
29208
|
+
directSequence: nextDirectSequence,
|
|
29209
|
+
input: cpfpNodeOutPoint,
|
|
29210
|
+
directInput: directNodeOutPoint,
|
|
29211
|
+
amountSats,
|
|
29212
|
+
receivingPubkey: receiverIdentityPubkey,
|
|
29213
|
+
network: this.config.getNetwork()
|
|
29214
|
+
});
|
|
29215
|
+
const refundSighash = getSigHashFromTx(
|
|
29216
|
+
cpfpRefundTx,
|
|
29217
|
+
0,
|
|
29218
|
+
nodeTx.getOutput(0)
|
|
29219
|
+
);
|
|
29220
|
+
const signingJobs = await this.signRefundsInternal(
|
|
29221
|
+
cpfpRefundTx,
|
|
29222
|
+
refundSighash,
|
|
29223
|
+
leaf,
|
|
29224
|
+
cpfpSigningCommitments[i]?.signingNonceCommitments
|
|
29225
|
+
);
|
|
29226
|
+
cpfpLeafSigningJobs.push(...signingJobs);
|
|
29227
|
+
if (directRefundTx) {
|
|
29228
|
+
if (!directNodeTx) {
|
|
29229
|
+
throw new ValidationError(
|
|
29230
|
+
"Direct node transaction undefined while direct refund transaction is defined",
|
|
29231
|
+
{
|
|
29232
|
+
field: "directNodeTx",
|
|
29233
|
+
value: directNodeTx,
|
|
29234
|
+
expected: "Non-null direct node transaction"
|
|
29235
|
+
}
|
|
29236
|
+
);
|
|
29237
|
+
}
|
|
29238
|
+
const refundSighash2 = getSigHashFromTx(
|
|
29239
|
+
directRefundTx,
|
|
29240
|
+
0,
|
|
29241
|
+
directNodeTx.getOutput(0)
|
|
29242
|
+
);
|
|
29243
|
+
const signingJobs2 = await this.signRefundsInternal(
|
|
29244
|
+
directRefundTx,
|
|
29245
|
+
refundSighash2,
|
|
29246
|
+
leaf,
|
|
29247
|
+
directSigningCommitments[i]?.signingNonceCommitments
|
|
29248
|
+
);
|
|
29249
|
+
directLeafSigningJobs.push(...signingJobs2);
|
|
29250
|
+
}
|
|
29251
|
+
if (directFromCpfpRefundTx) {
|
|
29252
|
+
if (!directNodeTx) {
|
|
29253
|
+
throw new ValidationError(
|
|
29254
|
+
"Direct node transaction undefined while direct from CPFP refund transaction is defined",
|
|
29255
|
+
{
|
|
29256
|
+
field: "directNodeTx",
|
|
29257
|
+
value: directNodeTx,
|
|
29258
|
+
expected: "Non-null direct node transaction"
|
|
29259
|
+
}
|
|
29260
|
+
);
|
|
29261
|
+
}
|
|
29262
|
+
const refundSighash2 = getSigHashFromTx(
|
|
29263
|
+
directFromCpfpRefundTx,
|
|
29264
|
+
0,
|
|
29265
|
+
nodeTx.getOutput(0)
|
|
29266
|
+
);
|
|
29267
|
+
const signingJobs2 = await this.signRefundsInternal(
|
|
29268
|
+
directFromCpfpRefundTx,
|
|
29269
|
+
refundSighash2,
|
|
29270
|
+
leaf,
|
|
29271
|
+
directFromCpfpSigningCommitments[i]?.signingNonceCommitments
|
|
29272
|
+
);
|
|
29273
|
+
directFromCpfpLeafSigningJobs.push(...signingJobs2);
|
|
29274
|
+
}
|
|
29275
|
+
}
|
|
29276
|
+
return {
|
|
29277
|
+
cpfpLeafSigningJobs,
|
|
29278
|
+
directLeafSigningJobs,
|
|
29279
|
+
directFromCpfpLeafSigningJobs
|
|
29280
|
+
};
|
|
29281
|
+
}
|
|
29282
|
+
};
|
|
29283
|
+
|
|
29284
|
+
// src/signer/signer.ts
|
|
29285
|
+
init_buffer();
|
|
29286
|
+
var import_secp256k110 = require("@bitcoinerlab/secp256k1");
|
|
29287
|
+
var import_secp256k111 = require("@noble/curves/secp256k1");
|
|
29288
|
+
var import_utils18 = require("@noble/curves/utils");
|
|
29289
|
+
var import_sha211 = require("@noble/hashes/sha2");
|
|
29290
|
+
var import_bip32 = require("@scure/bip32");
|
|
29291
|
+
var import_bip39 = require("@scure/bip39");
|
|
29292
|
+
var import_english = require("@scure/bip39/wordlists/english");
|
|
29293
|
+
var import_utils19 = require("@scure/btc-signer/utils");
|
|
29294
|
+
var ecies2 = __toESM(require("eciesjs"), 1);
|
|
29295
|
+
|
|
29296
|
+
// src/utils/secret-sharing.ts
|
|
29297
|
+
init_buffer();
|
|
29298
|
+
var import_secp256k18 = require("@noble/curves/secp256k1");
|
|
29299
|
+
var import_utils16 = require("@noble/curves/utils");
|
|
29300
|
+
function getRandomBigInt(max) {
|
|
29301
|
+
const byteLength = max.toString(2).length + 7 >> 3;
|
|
29302
|
+
const maxBigInt = max;
|
|
29303
|
+
const mask = (1n << BigInt(max.toString(2).length)) - 1n;
|
|
29304
|
+
while (true) {
|
|
29305
|
+
const crypto = getCrypto();
|
|
29306
|
+
const randBytes = crypto.getRandomValues(new Uint8Array(byteLength + 1));
|
|
29307
|
+
const randValue = BigInt("0x" + (0, import_utils16.bytesToHex)(randBytes)) & mask;
|
|
29308
|
+
if (randValue < maxBigInt) {
|
|
29309
|
+
return randValue;
|
|
29310
|
+
}
|
|
29311
|
+
}
|
|
29312
|
+
}
|
|
29313
|
+
function modInverse(a, m) {
|
|
29314
|
+
a = (a % m + m) % m;
|
|
29315
|
+
let [old_r, r] = [a, m];
|
|
29316
|
+
let [old_s, s2] = [1n, 0n];
|
|
29317
|
+
let [old_t, t] = [0n, 1n];
|
|
29318
|
+
while (r !== 0n) {
|
|
29319
|
+
const quotient = old_r / r;
|
|
29320
|
+
[old_r, r] = [r, old_r - quotient * r];
|
|
29321
|
+
[old_s, s2] = [s2, old_s - quotient * s2];
|
|
29322
|
+
[old_t, t] = [t, old_t - quotient * t];
|
|
29323
|
+
}
|
|
29324
|
+
if (old_r !== 1n) {
|
|
29325
|
+
throw new ValidationError("Modular inverse does not exist", {
|
|
29326
|
+
field: "modInverse",
|
|
29327
|
+
value: `a: ${a}, m: ${m}`,
|
|
29328
|
+
expected: "a and m must be coprime"
|
|
29329
|
+
});
|
|
29330
|
+
}
|
|
29331
|
+
return (old_s % m + m) % m;
|
|
29332
|
+
}
|
|
29333
|
+
function evaluatePolynomial(polynomial, x) {
|
|
29334
|
+
let result = 0n;
|
|
29335
|
+
for (let i = 0; i < polynomial.coefficients.length; i++) {
|
|
29336
|
+
const coeff = polynomial.coefficients[i];
|
|
29337
|
+
if (!coeff) {
|
|
29338
|
+
throw new ValidationError("Coefficient is undefined", {
|
|
29339
|
+
field: "coefficient",
|
|
29340
|
+
value: "undefined",
|
|
29341
|
+
expected: "A valid bigint coefficient"
|
|
29342
|
+
});
|
|
29343
|
+
}
|
|
29344
|
+
const xPow = x ** BigInt(i) % polynomial.fieldModulus;
|
|
29345
|
+
result = (result + xPow * coeff) % polynomial.fieldModulus;
|
|
29346
|
+
}
|
|
29347
|
+
return result;
|
|
29348
|
+
}
|
|
29349
|
+
function fieldDiv(numerator, denominator, fieldModulus) {
|
|
29350
|
+
if (denominator === 0n) {
|
|
29351
|
+
throw new ValidationError("Division by zero", {
|
|
29352
|
+
field: "denominator",
|
|
29353
|
+
value: "0",
|
|
29354
|
+
expected: "Non-zero value"
|
|
29355
|
+
});
|
|
29356
|
+
}
|
|
29357
|
+
const inverse = modInverse(denominator, fieldModulus);
|
|
29358
|
+
return numerator * inverse % fieldModulus;
|
|
29359
|
+
}
|
|
29360
|
+
function computerLagrangeCoefficients(index, points) {
|
|
29361
|
+
let numerator = 1n;
|
|
29362
|
+
let denominator = 1n;
|
|
29363
|
+
let fieldModulus = points[0]?.fieldModulus;
|
|
29364
|
+
if (!fieldModulus) {
|
|
29365
|
+
throw new ValidationError("Field modulus is undefined", {
|
|
29366
|
+
field: "fieldModulus",
|
|
29367
|
+
value: "undefined",
|
|
29368
|
+
expected: "A valid field modulus"
|
|
29369
|
+
});
|
|
29370
|
+
}
|
|
29371
|
+
for (const point of points) {
|
|
29372
|
+
if (point.index === index) {
|
|
29373
|
+
continue;
|
|
29374
|
+
}
|
|
29375
|
+
numerator = numerator * point.index;
|
|
29376
|
+
const value = point.index - index;
|
|
29377
|
+
denominator = denominator * value;
|
|
29378
|
+
}
|
|
29379
|
+
return fieldDiv(numerator, denominator, fieldModulus);
|
|
29380
|
+
}
|
|
29381
|
+
function generatePolynomialForSecretSharing(fieldModulus, secret, degree) {
|
|
29382
|
+
const coefficients = new Array(degree);
|
|
29383
|
+
const proofs = new Array(degree);
|
|
29384
|
+
coefficients[0] = secret;
|
|
29385
|
+
proofs[0] = import_secp256k18.secp256k1.Point.fromPrivateKey(secret).toBytes(true);
|
|
29386
|
+
for (let i = 1; i < degree; i++) {
|
|
29387
|
+
const coefficient = getRandomBigInt(fieldModulus);
|
|
29388
|
+
coefficients[i] = coefficient;
|
|
29389
|
+
proofs[i] = import_secp256k18.secp256k1.Point.fromPrivateKey(coefficient).toBytes(true);
|
|
29390
|
+
}
|
|
29391
|
+
return {
|
|
29392
|
+
fieldModulus,
|
|
29393
|
+
coefficients,
|
|
29394
|
+
proofs
|
|
29395
|
+
};
|
|
29396
|
+
}
|
|
29397
|
+
function splitSecret(fieldModulus, secret, threshold, numberOfShares) {
|
|
29398
|
+
const polynomial = generatePolynomialForSecretSharing(
|
|
29399
|
+
fieldModulus,
|
|
29400
|
+
secret,
|
|
29401
|
+
threshold
|
|
29402
|
+
);
|
|
29403
|
+
const shares = [];
|
|
29404
|
+
for (let i = 1; i <= numberOfShares; i++) {
|
|
29405
|
+
const share = evaluatePolynomial(polynomial, BigInt(i));
|
|
29406
|
+
shares.push({
|
|
29407
|
+
fieldModulus,
|
|
29408
|
+
threshold,
|
|
29409
|
+
index: BigInt(i),
|
|
29410
|
+
share
|
|
29411
|
+
});
|
|
29412
|
+
}
|
|
29413
|
+
return shares;
|
|
29414
|
+
}
|
|
29415
|
+
function splitSecretWithProofs(secret, fieldModulus, threshold, numberOfShares) {
|
|
29416
|
+
const polynomial = generatePolynomialForSecretSharing(
|
|
29417
|
+
fieldModulus,
|
|
29418
|
+
secret,
|
|
29419
|
+
threshold
|
|
29420
|
+
);
|
|
29421
|
+
const shares = [];
|
|
29422
|
+
for (let i = 1; i <= numberOfShares; i++) {
|
|
29423
|
+
const share = evaluatePolynomial(polynomial, BigInt(i));
|
|
29424
|
+
shares.push({
|
|
29425
|
+
fieldModulus,
|
|
29426
|
+
threshold,
|
|
29427
|
+
index: BigInt(i),
|
|
29428
|
+
share,
|
|
29429
|
+
proofs: polynomial.proofs
|
|
29430
|
+
});
|
|
29431
|
+
}
|
|
29432
|
+
return shares;
|
|
29433
|
+
}
|
|
29434
|
+
function recoverSecret(shares) {
|
|
29435
|
+
if (shares.length === 0) return 0n;
|
|
29436
|
+
const threshold = shares[0]?.threshold;
|
|
29437
|
+
const fieldModulus = shares[0]?.fieldModulus;
|
|
29438
|
+
if (!threshold || !fieldModulus) {
|
|
29439
|
+
throw new ValidationError("Shares are not valid", {
|
|
29440
|
+
field: "shares",
|
|
29441
|
+
value: "Missing threshold or fieldModulus",
|
|
29442
|
+
expected: "Valid shares with threshold and fieldModulus"
|
|
29443
|
+
});
|
|
29444
|
+
}
|
|
29445
|
+
if (shares.length < threshold) {
|
|
29446
|
+
throw new ValidationError("Not enough shares to recover secret", {
|
|
29447
|
+
field: "shares",
|
|
29448
|
+
value: shares.length,
|
|
29449
|
+
expected: `At least ${threshold} shares`
|
|
29450
|
+
});
|
|
29451
|
+
}
|
|
29452
|
+
let result = 0n;
|
|
29453
|
+
for (const share of shares) {
|
|
29454
|
+
const coeff = computerLagrangeCoefficients(share.index, shares);
|
|
29455
|
+
const item = share.share * coeff % fieldModulus;
|
|
29456
|
+
result = (result + item) % fieldModulus;
|
|
29457
|
+
}
|
|
29458
|
+
return result;
|
|
29459
|
+
}
|
|
29460
|
+
function validateShare(share) {
|
|
29461
|
+
const targetPubkey = import_secp256k18.secp256k1.Point.fromPrivateKey(share.share).toBytes(
|
|
29462
|
+
true
|
|
29463
|
+
);
|
|
29464
|
+
let resultPubkey = share.proofs[0];
|
|
29465
|
+
if (!resultPubkey) {
|
|
29466
|
+
throw new ValidationError("Result pubkey is not valid", {
|
|
29467
|
+
field: "resultPubkey",
|
|
29468
|
+
value: "null",
|
|
29469
|
+
expected: "Valid public key bytes"
|
|
29470
|
+
});
|
|
29471
|
+
}
|
|
29472
|
+
for (let i = 1; i < share.proofs.length; i++) {
|
|
29473
|
+
const pubkey = share.proofs[i];
|
|
29474
|
+
if (!pubkey) {
|
|
29475
|
+
throw new ValidationError("Pubkey is not valid", {
|
|
29476
|
+
field: "pubkey",
|
|
29477
|
+
value: "null",
|
|
29478
|
+
expected: "Valid public key bytes"
|
|
29479
|
+
});
|
|
29480
|
+
}
|
|
29481
|
+
const value = share.index ** BigInt(i) % share.fieldModulus;
|
|
29482
|
+
const scaledPoint = import_secp256k18.secp256k1.Point.fromHex(pubkey).multiply(value);
|
|
29483
|
+
resultPubkey = import_secp256k18.secp256k1.Point.fromHex(resultPubkey).add(scaledPoint).toBytes(true);
|
|
29484
|
+
}
|
|
29485
|
+
if (!(0, import_utils16.equalBytes)(resultPubkey, targetPubkey)) {
|
|
29486
|
+
throw new ValidationError("Share is not valid", {
|
|
29487
|
+
field: "share",
|
|
29488
|
+
value: "Invalid proof",
|
|
29489
|
+
expected: "Valid share with matching proofs"
|
|
29490
|
+
});
|
|
29491
|
+
}
|
|
29492
|
+
}
|
|
29493
|
+
function bigIntToPrivateKey(value) {
|
|
29494
|
+
const hex = value.toString(16).padStart(64, "0");
|
|
29495
|
+
const bytes2 = new Uint8Array(32);
|
|
29496
|
+
for (let i = 0; i < 32; i++) {
|
|
29497
|
+
bytes2[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
29498
|
+
}
|
|
29499
|
+
return bytes2;
|
|
29500
|
+
}
|
|
29501
|
+
|
|
29502
|
+
// src/utils/signing.ts
|
|
29503
|
+
init_buffer();
|
|
29504
|
+
var import_secp256k19 = require("@noble/curves/secp256k1");
|
|
29505
|
+
function getRandomSigningNonce() {
|
|
29506
|
+
const binding = import_secp256k19.secp256k1.utils.randomPrivateKey();
|
|
29507
|
+
const hiding = import_secp256k19.secp256k1.utils.randomPrivateKey();
|
|
29508
|
+
return createSigningNonce(binding, hiding);
|
|
29509
|
+
}
|
|
29510
|
+
function createSigningNonce(binding, hiding) {
|
|
29511
|
+
if (binding.length !== 32 || hiding.length !== 32) {
|
|
29512
|
+
throw new ValidationError("Invalid nonce length", {
|
|
29513
|
+
field: "nonce",
|
|
29514
|
+
value: `binding: ${binding.length}, hiding: ${hiding.length}`,
|
|
29515
|
+
expected: "Both binding and hiding should be 32 bytes"
|
|
29516
|
+
});
|
|
29517
|
+
}
|
|
29518
|
+
return {
|
|
29519
|
+
binding,
|
|
29520
|
+
hiding
|
|
29521
|
+
};
|
|
29522
|
+
}
|
|
29523
|
+
function getSigningCommitmentFromNonce(nonce) {
|
|
29524
|
+
const bindingPubKey = import_secp256k19.secp256k1.getPublicKey(nonce.binding, true);
|
|
29525
|
+
const hidingPubKey = import_secp256k19.secp256k1.getPublicKey(nonce.hiding, true);
|
|
29526
|
+
return {
|
|
29527
|
+
binding: bindingPubKey,
|
|
29528
|
+
hiding: hidingPubKey
|
|
29529
|
+
};
|
|
29530
|
+
}
|
|
29531
|
+
function encodeSigningNonceToBytes(nonce) {
|
|
29532
|
+
return new Uint8Array([...nonce.binding, ...nonce.hiding]);
|
|
29533
|
+
}
|
|
29534
|
+
function decodeBytesToSigningNonce(bytes2) {
|
|
29535
|
+
if (bytes2.length !== 64) {
|
|
29536
|
+
throw new ValidationError("Invalid nonce length", {
|
|
29537
|
+
field: "bytes",
|
|
29538
|
+
value: bytes2.length,
|
|
29539
|
+
expected: "64 bytes (32 bytes for binding + 32 bytes for hiding)"
|
|
29540
|
+
});
|
|
29541
|
+
}
|
|
29542
|
+
return {
|
|
29543
|
+
binding: bytes2.slice(32, 64),
|
|
29544
|
+
hiding: bytes2.slice(0, 32)
|
|
29545
|
+
};
|
|
29546
|
+
}
|
|
29547
|
+
function createSigningCommitment(binding, hiding) {
|
|
29548
|
+
if (binding.length !== 33 || hiding.length !== 33) {
|
|
29549
|
+
throw new ValidationError("Invalid nonce commitment length", {
|
|
29550
|
+
field: "commitment",
|
|
29551
|
+
value: `binding: ${binding.length}, hiding: ${hiding.length}`,
|
|
29552
|
+
expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
|
|
29553
|
+
});
|
|
29554
|
+
}
|
|
29555
|
+
return {
|
|
29556
|
+
binding,
|
|
29557
|
+
hiding
|
|
29558
|
+
};
|
|
29559
|
+
}
|
|
29560
|
+
function encodeSigningCommitmentToBytes(commitment) {
|
|
29561
|
+
if (commitment.binding.length !== 33 || commitment.hiding.length !== 33) {
|
|
29562
|
+
throw new ValidationError("Invalid nonce commitment length", {
|
|
29563
|
+
field: "commitment",
|
|
29564
|
+
value: `binding: ${commitment.binding.length}, hiding: ${commitment.hiding.length}`,
|
|
29565
|
+
expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
|
|
29566
|
+
});
|
|
29567
|
+
}
|
|
29568
|
+
return new Uint8Array([...commitment.binding, ...commitment.hiding]);
|
|
29569
|
+
}
|
|
29570
|
+
function decodeBytesToSigningCommitment(bytes2) {
|
|
29571
|
+
if (bytes2.length !== 66) {
|
|
29572
|
+
throw new ValidationError("Invalid nonce commitment length", {
|
|
29573
|
+
field: "bytes",
|
|
29574
|
+
value: bytes2.length,
|
|
29575
|
+
expected: "66 bytes (33 bytes for binding + 33 bytes for hiding)"
|
|
29576
|
+
});
|
|
29577
|
+
}
|
|
29578
|
+
return {
|
|
29579
|
+
binding: bytes2.slice(33, 66),
|
|
29580
|
+
hiding: bytes2.slice(0, 33)
|
|
29581
|
+
};
|
|
29582
|
+
}
|
|
29583
|
+
|
|
29584
|
+
// src/signer/signer.ts
|
|
29585
|
+
var sparkFrostModule = void 0;
|
|
29586
|
+
var getSparkFrostModule = async () => {
|
|
29587
|
+
if (isReactNative) {
|
|
29588
|
+
return void 0;
|
|
29589
|
+
}
|
|
29590
|
+
if (!sparkFrostModule) {
|
|
29591
|
+
sparkFrostModule = await Promise.resolve().then(() => (init_wasm(), wasm_exports));
|
|
29592
|
+
}
|
|
29593
|
+
return sparkFrostModule;
|
|
29594
|
+
};
|
|
29595
|
+
var HARDENED_OFFSET = 2147483648;
|
|
29596
|
+
var DefaultSparkKeysGenerator = class {
|
|
29597
|
+
async deriveKeysFromSeed(seed, accountNumber) {
|
|
29598
|
+
const hdkey = import_bip32.HDKey.fromMasterSeed(seed);
|
|
29599
|
+
if (!hdkey.privateKey || !hdkey.publicKey) {
|
|
29600
|
+
throw new ValidationError("Failed to derive keys from seed", {
|
|
29601
|
+
field: "hdkey",
|
|
29602
|
+
value: seed
|
|
29603
|
+
});
|
|
29604
|
+
}
|
|
29605
|
+
const identityKey = hdkey.derive(`m/8797555'/${accountNumber}'/0'`);
|
|
29606
|
+
const signingKey = hdkey.derive(`m/8797555'/${accountNumber}'/1'`);
|
|
29607
|
+
const depositKey = hdkey.derive(`m/8797555'/${accountNumber}'/2'`);
|
|
29608
|
+
const staticDepositKey = hdkey.derive(`m/8797555'/${accountNumber}'/3'`);
|
|
29609
|
+
if (!identityKey.privateKey || !depositKey.privateKey || !signingKey.privateKey || !identityKey.publicKey || !depositKey.publicKey || !signingKey.publicKey || !staticDepositKey.privateKey || !staticDepositKey.publicKey) {
|
|
29610
|
+
throw new ValidationError(
|
|
29611
|
+
"Failed to derive all required keys from seed",
|
|
29612
|
+
{
|
|
29613
|
+
field: "derivedKeys"
|
|
29614
|
+
}
|
|
29615
|
+
);
|
|
29616
|
+
}
|
|
29617
|
+
return {
|
|
29618
|
+
identityKey: {
|
|
29619
|
+
privateKey: identityKey.privateKey,
|
|
29620
|
+
publicKey: identityKey.publicKey
|
|
29621
|
+
},
|
|
29622
|
+
signingHDKey: {
|
|
29623
|
+
hdKey: signingKey,
|
|
29624
|
+
privateKey: signingKey.privateKey,
|
|
29625
|
+
publicKey: signingKey.publicKey
|
|
29626
|
+
},
|
|
29627
|
+
depositKey: {
|
|
29628
|
+
privateKey: depositKey.privateKey,
|
|
29629
|
+
publicKey: depositKey.publicKey
|
|
29630
|
+
},
|
|
29631
|
+
staticDepositHDKey: {
|
|
29632
|
+
hdKey: staticDepositKey,
|
|
29633
|
+
privateKey: staticDepositKey.privateKey,
|
|
29634
|
+
publicKey: staticDepositKey.publicKey
|
|
29635
|
+
}
|
|
29636
|
+
};
|
|
29637
|
+
}
|
|
29638
|
+
};
|
|
29639
|
+
var DefaultSparkSigner = class {
|
|
29640
|
+
identityKey = null;
|
|
29641
|
+
signingKey = null;
|
|
29642
|
+
depositKey = null;
|
|
29643
|
+
staticDepositKey = null;
|
|
29644
|
+
commitmentToNonceMap = /* @__PURE__ */ new Map();
|
|
29645
|
+
keysGenerator;
|
|
29646
|
+
constructor({
|
|
29647
|
+
sparkKeysGenerator
|
|
29648
|
+
} = {}) {
|
|
29649
|
+
this.keysGenerator = sparkKeysGenerator ?? new DefaultSparkKeysGenerator();
|
|
29650
|
+
}
|
|
29651
|
+
deriveSigningKey(hash) {
|
|
29652
|
+
if (!this.signingKey) {
|
|
29653
|
+
throw new ValidationError("Private key not initialized", {
|
|
29654
|
+
field: "signingKey"
|
|
29655
|
+
});
|
|
29656
|
+
}
|
|
29657
|
+
const view = new DataView(hash.buffer);
|
|
29658
|
+
const amount = view.getUint32(0, false) % HARDENED_OFFSET + HARDENED_OFFSET;
|
|
29659
|
+
const newPrivateKey = this.signingKey?.deriveChild(amount).privateKey;
|
|
29660
|
+
if (!newPrivateKey) {
|
|
29661
|
+
throw new ValidationError("Failed to recover signing key", {
|
|
29662
|
+
field: "privateKey"
|
|
29663
|
+
});
|
|
29664
|
+
}
|
|
29665
|
+
return newPrivateKey;
|
|
29666
|
+
}
|
|
29667
|
+
async decryptEciesToPrivateKey(ciphertext) {
|
|
29668
|
+
if (!this.identityKey?.privateKey) {
|
|
29669
|
+
throw new ConfigurationError("Identity key not initialized", {
|
|
29670
|
+
configKey: "identityKey"
|
|
29640
29671
|
});
|
|
29641
29672
|
}
|
|
29642
|
-
|
|
29673
|
+
const receiverEciesPrivKey = ecies2.PrivateKey.fromHex(
|
|
29674
|
+
(0, import_utils18.bytesToHex)(this.identityKey.privateKey)
|
|
29675
|
+
);
|
|
29676
|
+
const privateKey = ecies2.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
|
|
29677
|
+
return privateKey;
|
|
29643
29678
|
}
|
|
29644
|
-
|
|
29645
|
-
|
|
29646
|
-
|
|
29647
|
-
|
|
29648
|
-
|
|
29649
|
-
|
|
29650
|
-
|
|
29651
|
-
|
|
29652
|
-
|
|
29653
|
-
|
|
29654
|
-
|
|
29655
|
-
|
|
29656
|
-
const newSignature = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
|
|
29657
|
-
return newSignature;
|
|
29658
|
-
}
|
|
29659
|
-
function generateAdaptorFromSignature(signature) {
|
|
29660
|
-
const adaptorPrivateKey = import_secp256k111.secp256k1.utils.randomPrivateKey();
|
|
29661
|
-
const { r, s: s2 } = parseSignature(signature);
|
|
29662
|
-
const sBigInt = (0, import_utils18.bytesToNumberBE)(s2);
|
|
29663
|
-
const tBigInt = (0, import_utils18.bytesToNumberBE)(adaptorPrivateKey);
|
|
29664
|
-
const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k111.secp256k1.CURVE.n);
|
|
29665
|
-
const newSignature = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
|
|
29666
|
-
return {
|
|
29667
|
-
adaptorSignature: newSignature,
|
|
29668
|
-
adaptorPrivateKey
|
|
29669
|
-
};
|
|
29670
|
-
}
|
|
29671
|
-
function validateOutboundAdaptorSignature(pubkey, hash, signature, adaptorPubkey) {
|
|
29672
|
-
return schnorrVerifyWithAdaptor(
|
|
29673
|
-
signature,
|
|
29674
|
-
hash,
|
|
29675
|
-
pubkey,
|
|
29676
|
-
adaptorPubkey,
|
|
29677
|
-
false
|
|
29678
|
-
);
|
|
29679
|
-
}
|
|
29680
|
-
function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes) {
|
|
29681
|
-
const { r, s: s2 } = parseSignature(signature);
|
|
29682
|
-
const sBigInt = (0, import_utils18.bytesToNumberBE)(s2);
|
|
29683
|
-
const adaptorPrivateKey = (0, import_utils18.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
29684
|
-
const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k111.secp256k1.CURVE.n);
|
|
29685
|
-
const newSig = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
|
|
29686
|
-
try {
|
|
29687
|
-
if (import_secp256k111.schnorr.verify(newSig, hash, pubkey)) {
|
|
29688
|
-
return newSig;
|
|
29679
|
+
async getSigningPrivateKeyFromDerivation(keyDerivation) {
|
|
29680
|
+
switch (keyDerivation.type) {
|
|
29681
|
+
case "leaf" /* LEAF */:
|
|
29682
|
+
return this.deriveSigningKey((0, import_sha211.sha256)(keyDerivation.path));
|
|
29683
|
+
case "deposit" /* DEPOSIT */:
|
|
29684
|
+
return this.depositKey?.privateKey ?? new Uint8Array();
|
|
29685
|
+
case "static_deposit" /* STATIC_DEPOSIT */:
|
|
29686
|
+
return this.getStaticDepositSecretKey(keyDerivation.path);
|
|
29687
|
+
case "ecies" /* ECIES */:
|
|
29688
|
+
return this.decryptEciesToPrivateKey(keyDerivation.path);
|
|
29689
|
+
case "random" /* RANDOM */:
|
|
29690
|
+
return import_secp256k111.secp256k1.utils.randomPrivateKey();
|
|
29689
29691
|
}
|
|
29690
|
-
} catch (e) {
|
|
29691
|
-
console.error("[applyAdaptorToSignature] Addition verification failed:", e);
|
|
29692
29692
|
}
|
|
29693
|
-
|
|
29694
|
-
|
|
29695
|
-
|
|
29696
|
-
|
|
29697
|
-
|
|
29693
|
+
async signSchnorrWithIdentityKey(message) {
|
|
29694
|
+
if (!this.identityKey?.privateKey) {
|
|
29695
|
+
throw new ValidationError("Private key not set", {
|
|
29696
|
+
field: "identityKey"
|
|
29697
|
+
});
|
|
29698
29698
|
}
|
|
29699
|
-
|
|
29700
|
-
|
|
29701
|
-
"[applyAdaptorToSignature] Subtraction verification failed:",
|
|
29702
|
-
e
|
|
29703
|
-
);
|
|
29699
|
+
const signature = import_secp256k111.schnorr.sign(message, this.identityKey.privateKey);
|
|
29700
|
+
return signature;
|
|
29704
29701
|
}
|
|
29705
|
-
|
|
29706
|
-
|
|
29707
|
-
|
|
29708
|
-
|
|
29709
|
-
|
|
29702
|
+
async getIdentityPublicKey() {
|
|
29703
|
+
if (!this.identityKey?.publicKey) {
|
|
29704
|
+
throw new ValidationError("Private key is not set", {
|
|
29705
|
+
field: "identityKey"
|
|
29706
|
+
});
|
|
29707
|
+
}
|
|
29708
|
+
return this.identityKey.publicKey;
|
|
29710
29709
|
}
|
|
29711
|
-
|
|
29712
|
-
|
|
29713
|
-
|
|
29714
|
-
|
|
29715
|
-
|
|
29716
|
-
|
|
29717
|
-
|
|
29718
|
-
hash
|
|
29719
|
-
);
|
|
29720
|
-
if (commitmenet.length > 32) {
|
|
29721
|
-
throw new Error("hash of (r || P || m) too big");
|
|
29710
|
+
async getDepositSigningKey() {
|
|
29711
|
+
if (!this.depositKey?.publicKey) {
|
|
29712
|
+
throw new ValidationError("Deposit key is not set", {
|
|
29713
|
+
field: "depositKey"
|
|
29714
|
+
});
|
|
29715
|
+
}
|
|
29716
|
+
return this.depositKey.publicKey;
|
|
29722
29717
|
}
|
|
29723
|
-
|
|
29724
|
-
|
|
29725
|
-
|
|
29726
|
-
const eP = pubKey.multiplyUnsafe(negE);
|
|
29727
|
-
const R = sG.add(eP);
|
|
29728
|
-
if (R.is0()) {
|
|
29729
|
-
throw new Error("R is zero");
|
|
29718
|
+
async getStaticDepositSigningKey(idx) {
|
|
29719
|
+
const staticDepositKey = await this.getStaticDepositSecretKey(idx);
|
|
29720
|
+
return import_secp256k111.secp256k1.getPublicKey(staticDepositKey);
|
|
29730
29721
|
}
|
|
29731
|
-
|
|
29732
|
-
|
|
29733
|
-
|
|
29734
|
-
|
|
29735
|
-
|
|
29722
|
+
async getStaticDepositSecretKey(idx) {
|
|
29723
|
+
if (!this.staticDepositKey) {
|
|
29724
|
+
throw new ValidationError("Static deposit key is not set", {
|
|
29725
|
+
field: "staticDepositKey"
|
|
29726
|
+
});
|
|
29727
|
+
}
|
|
29728
|
+
const staticDepositKey = this.staticDepositKey.deriveChild(
|
|
29729
|
+
HARDENED_OFFSET + idx
|
|
29730
|
+
);
|
|
29731
|
+
if (!staticDepositKey?.privateKey) {
|
|
29732
|
+
throw new ValidationError("Static deposit key is not set", {
|
|
29733
|
+
field: "staticDepositKey"
|
|
29734
|
+
});
|
|
29735
|
+
}
|
|
29736
|
+
return staticDepositKey.privateKey;
|
|
29736
29737
|
}
|
|
29737
|
-
|
|
29738
|
-
|
|
29739
|
-
throw new Error("calculated R y-value is odd");
|
|
29738
|
+
async generateMnemonic() {
|
|
29739
|
+
return (0, import_bip39.generateMnemonic)(import_english.wordlist);
|
|
29740
29740
|
}
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
throw new Error("calculated R point was not given R");
|
|
29741
|
+
async mnemonicToSeed(mnemonic) {
|
|
29742
|
+
return await (0, import_bip39.mnemonicToSeed)(mnemonic);
|
|
29744
29743
|
}
|
|
29745
|
-
|
|
29746
|
-
|
|
29747
|
-
|
|
29748
|
-
if (signature.length < 64) {
|
|
29749
|
-
throw new ValidationError("Signature too short", {
|
|
29750
|
-
expectedLength: 64,
|
|
29751
|
-
actualLength: signature.length
|
|
29752
|
-
});
|
|
29744
|
+
async getPublicKeyFromDerivation(keyDerivation) {
|
|
29745
|
+
const privateKey = await this.getSigningPrivateKeyFromDerivation(keyDerivation);
|
|
29746
|
+
return import_secp256k111.secp256k1.getPublicKey(privateKey);
|
|
29753
29747
|
}
|
|
29754
|
-
|
|
29755
|
-
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
29748
|
+
async subtractPrivateKeysGivenDerivationPaths(first, second) {
|
|
29749
|
+
const firstPrivateKey = this.deriveSigningKey((0, import_sha211.sha256)(first));
|
|
29750
|
+
const secondPrivateKey = this.deriveSigningKey((0, import_sha211.sha256)(second));
|
|
29751
|
+
const resultPrivKey = subtractPrivateKeys(
|
|
29752
|
+
firstPrivateKey,
|
|
29753
|
+
secondPrivateKey
|
|
29754
|
+
);
|
|
29755
|
+
const resultPubKey = import_secp256k111.secp256k1.getPublicKey(resultPrivKey);
|
|
29756
|
+
return resultPubKey;
|
|
29759
29757
|
}
|
|
29760
|
-
|
|
29761
|
-
|
|
29762
|
-
|
|
29763
|
-
|
|
29764
|
-
|
|
29765
|
-
|
|
29758
|
+
async subtractAndSplitSecretWithProofsGivenDerivations({
|
|
29759
|
+
first,
|
|
29760
|
+
second,
|
|
29761
|
+
curveOrder,
|
|
29762
|
+
threshold,
|
|
29763
|
+
numShares
|
|
29764
|
+
}) {
|
|
29765
|
+
const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
|
|
29766
|
+
const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
|
|
29767
|
+
const resultPrivKey = subtractPrivateKeys(
|
|
29768
|
+
firstPrivateKey,
|
|
29769
|
+
secondPrivateKey
|
|
29770
|
+
);
|
|
29771
|
+
return await this.splitSecretWithProofs({
|
|
29772
|
+
secret: resultPrivKey,
|
|
29773
|
+
curveOrder,
|
|
29774
|
+
threshold,
|
|
29775
|
+
numShares
|
|
29766
29776
|
});
|
|
29767
29777
|
}
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
29778
|
+
async subtractSplitAndEncrypt({
|
|
29779
|
+
first,
|
|
29780
|
+
second,
|
|
29781
|
+
curveOrder,
|
|
29782
|
+
threshold,
|
|
29783
|
+
numShares,
|
|
29784
|
+
receiverPublicKey
|
|
29785
|
+
}) {
|
|
29786
|
+
const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
|
|
29787
|
+
const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
|
|
29788
|
+
const resultPrivKey = subtractPrivateKeys(
|
|
29789
|
+
firstPrivateKey,
|
|
29790
|
+
secondPrivateKey
|
|
29791
|
+
);
|
|
29792
|
+
return {
|
|
29793
|
+
shares: await this.splitSecretWithProofs({
|
|
29794
|
+
secret: resultPrivKey,
|
|
29795
|
+
curveOrder,
|
|
29796
|
+
threshold,
|
|
29797
|
+
numShares
|
|
29798
|
+
}),
|
|
29799
|
+
secretCipher: ecies2.encrypt(receiverPublicKey, secondPrivateKey)
|
|
29800
|
+
};
|
|
29773
29801
|
}
|
|
29774
|
-
|
|
29775
|
-
|
|
29776
|
-
|
|
29777
|
-
|
|
29778
|
-
|
|
29779
|
-
|
|
29780
|
-
|
|
29781
|
-
|
|
29782
|
-
var import_nice_grpc_common = require("nice-grpc-common");
|
|
29783
|
-
|
|
29784
|
-
// src/services/signing.ts
|
|
29785
|
-
init_buffer();
|
|
29786
|
-
var import_utils19 = require("@noble/curves/utils");
|
|
29787
|
-
var SigningService = class {
|
|
29788
|
-
config;
|
|
29789
|
-
constructor(config) {
|
|
29790
|
-
this.config = config;
|
|
29802
|
+
async splitSecretWithProofs({
|
|
29803
|
+
secret,
|
|
29804
|
+
curveOrder,
|
|
29805
|
+
threshold,
|
|
29806
|
+
numShares
|
|
29807
|
+
}) {
|
|
29808
|
+
const secretAsInt = (0, import_utils18.bytesToNumberBE)(secret);
|
|
29809
|
+
return splitSecretWithProofs(secretAsInt, curveOrder, threshold, numShares);
|
|
29791
29810
|
}
|
|
29792
|
-
async
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
|
|
29811
|
+
async signFrost({
|
|
29812
|
+
message,
|
|
29813
|
+
keyDerivation,
|
|
29814
|
+
publicKey,
|
|
29815
|
+
verifyingKey,
|
|
29816
|
+
selfCommitment,
|
|
29817
|
+
statechainCommitments,
|
|
29818
|
+
adaptorPubKey
|
|
29819
|
+
}) {
|
|
29820
|
+
const SparkFrost = await getSparkFrostModule();
|
|
29821
|
+
if (!SparkFrost) {
|
|
29822
|
+
throw new ValidationError("SparkFrost module not found", {
|
|
29823
|
+
field: "SparkFrost"
|
|
29800
29824
|
});
|
|
29801
29825
|
}
|
|
29802
|
-
const
|
|
29803
|
-
|
|
29804
|
-
|
|
29805
|
-
|
|
29806
|
-
|
|
29807
|
-
|
|
29808
|
-
|
|
29809
|
-
|
|
29810
|
-
|
|
29811
|
-
|
|
29826
|
+
const signingPrivateKey = await this.getSigningPrivateKeyFromDerivation(keyDerivation);
|
|
29827
|
+
if (!signingPrivateKey) {
|
|
29828
|
+
throw new ValidationError("Private key not found for public key", {
|
|
29829
|
+
field: "privateKey"
|
|
29830
|
+
});
|
|
29831
|
+
}
|
|
29832
|
+
const commitment = selfCommitment.commitment;
|
|
29833
|
+
const nonce = this.commitmentToNonceMap.get(commitment);
|
|
29834
|
+
if (!nonce) {
|
|
29835
|
+
throw new ValidationError("Nonce not found for commitment", {
|
|
29836
|
+
field: "nonce"
|
|
29837
|
+
});
|
|
29838
|
+
}
|
|
29839
|
+
const keyPackage = {
|
|
29840
|
+
secretKey: signingPrivateKey,
|
|
29841
|
+
publicKey,
|
|
29842
|
+
verifyingKey
|
|
29843
|
+
};
|
|
29844
|
+
const logMessage = (0, import_utils18.bytesToHex)(message);
|
|
29845
|
+
const result = await SparkFrost.signFrost({
|
|
29846
|
+
message,
|
|
29847
|
+
keyPackage,
|
|
29848
|
+
nonce,
|
|
29849
|
+
selfCommitment: commitment,
|
|
29850
|
+
statechainCommitments,
|
|
29851
|
+
adaptorPubKey
|
|
29812
29852
|
});
|
|
29813
|
-
|
|
29814
|
-
|
|
29815
|
-
|
|
29816
|
-
|
|
29817
|
-
|
|
29818
|
-
|
|
29819
|
-
|
|
29820
|
-
|
|
29821
|
-
|
|
29822
|
-
|
|
29823
|
-
|
|
29853
|
+
return result;
|
|
29854
|
+
}
|
|
29855
|
+
async aggregateFrost({
|
|
29856
|
+
message,
|
|
29857
|
+
publicKey,
|
|
29858
|
+
verifyingKey,
|
|
29859
|
+
selfCommitment,
|
|
29860
|
+
statechainCommitments,
|
|
29861
|
+
adaptorPubKey,
|
|
29862
|
+
selfSignature,
|
|
29863
|
+
statechainSignatures,
|
|
29864
|
+
statechainPublicKeys
|
|
29865
|
+
}) {
|
|
29866
|
+
const SparkFrost = await getSparkFrostModule();
|
|
29867
|
+
if (!SparkFrost) {
|
|
29868
|
+
throw new ValidationError("SparkFrost module not found", {
|
|
29869
|
+
field: "SparkFrost"
|
|
29870
|
+
});
|
|
29871
|
+
}
|
|
29872
|
+
return SparkFrost.aggregateFrost({
|
|
29873
|
+
message,
|
|
29874
|
+
statechainSignatures,
|
|
29875
|
+
statechainPublicKeys,
|
|
29876
|
+
verifyingKey,
|
|
29877
|
+
statechainCommitments,
|
|
29878
|
+
selfCommitment: selfCommitment.commitment,
|
|
29879
|
+
selfPublicKey: publicKey,
|
|
29880
|
+
selfSignature,
|
|
29881
|
+
adaptorPubKey
|
|
29824
29882
|
});
|
|
29825
|
-
return leafSigningJobs;
|
|
29826
29883
|
}
|
|
29827
|
-
async
|
|
29828
|
-
|
|
29829
|
-
|
|
29830
|
-
|
|
29831
|
-
|
|
29832
|
-
|
|
29833
|
-
|
|
29834
|
-
|
|
29835
|
-
|
|
29836
|
-
|
|
29837
|
-
|
|
29838
|
-
|
|
29839
|
-
|
|
29840
|
-
|
|
29841
|
-
|
|
29842
|
-
|
|
29843
|
-
|
|
29844
|
-
|
|
29845
|
-
|
|
29846
|
-
|
|
29847
|
-
|
|
29848
|
-
|
|
29849
|
-
|
|
29850
|
-
|
|
29851
|
-
|
|
29852
|
-
|
|
29853
|
-
|
|
29854
|
-
|
|
29855
|
-
|
|
29856
|
-
|
|
29857
|
-
|
|
29858
|
-
|
|
29859
|
-
value: currRefundTx.getOutput(0),
|
|
29860
|
-
expected: "Non-null amount"
|
|
29861
|
-
});
|
|
29862
|
-
}
|
|
29863
|
-
let directNodeTx;
|
|
29864
|
-
let directNodeOutPoint;
|
|
29865
|
-
if (leaf.leaf.directTx.length > 0) {
|
|
29866
|
-
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
29867
|
-
directNodeOutPoint = {
|
|
29868
|
-
txid: (0, import_utils19.hexToBytes)(getTxId(directNodeTx)),
|
|
29869
|
-
index: 0
|
|
29870
|
-
};
|
|
29871
|
-
}
|
|
29872
|
-
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
29873
|
-
sequence: nextSequence,
|
|
29874
|
-
directSequence: nextDirectSequence,
|
|
29875
|
-
input: cpfpNodeOutPoint,
|
|
29876
|
-
directInput: directNodeOutPoint,
|
|
29877
|
-
amountSats,
|
|
29878
|
-
receivingPubkey: receiverIdentityPubkey,
|
|
29879
|
-
network: this.config.getNetwork()
|
|
29884
|
+
async createSparkWalletFromSeed(seed, accountNumber) {
|
|
29885
|
+
if (typeof seed === "string") {
|
|
29886
|
+
seed = (0, import_utils18.hexToBytes)(seed);
|
|
29887
|
+
}
|
|
29888
|
+
const {
|
|
29889
|
+
identityKey,
|
|
29890
|
+
signingHDKey: signingKey,
|
|
29891
|
+
depositKey,
|
|
29892
|
+
staticDepositHDKey: staticDepositKey
|
|
29893
|
+
} = await this.keysGenerator.deriveKeysFromSeed(seed, accountNumber ?? 0);
|
|
29894
|
+
this.identityKey = identityKey;
|
|
29895
|
+
this.depositKey = depositKey;
|
|
29896
|
+
this.signingKey = signingKey.hdKey;
|
|
29897
|
+
this.staticDepositKey = staticDepositKey.hdKey;
|
|
29898
|
+
return (0, import_utils18.bytesToHex)(identityKey.publicKey);
|
|
29899
|
+
}
|
|
29900
|
+
async signMessageWithIdentityKey(message, compact) {
|
|
29901
|
+
if (!this.identityKey?.privateKey) {
|
|
29902
|
+
throw new ConfigurationError("Identity key not initialized", {
|
|
29903
|
+
configKey: "identityKey"
|
|
29904
|
+
});
|
|
29905
|
+
}
|
|
29906
|
+
const signature = import_secp256k111.secp256k1.sign(message, this.identityKey.privateKey);
|
|
29907
|
+
if (compact) {
|
|
29908
|
+
return signature.toCompactRawBytes();
|
|
29909
|
+
}
|
|
29910
|
+
return signature.toDERRawBytes();
|
|
29911
|
+
}
|
|
29912
|
+
async decryptEcies(ciphertext) {
|
|
29913
|
+
if (!this.identityKey?.privateKey) {
|
|
29914
|
+
throw new ConfigurationError("Identity key not initialized", {
|
|
29915
|
+
configKey: "identityKey"
|
|
29880
29916
|
});
|
|
29881
|
-
const refundSighash = getSigHashFromTx(
|
|
29882
|
-
cpfpRefundTx,
|
|
29883
|
-
0,
|
|
29884
|
-
nodeTx.getOutput(0)
|
|
29885
|
-
);
|
|
29886
|
-
const signingJobs = await this.signRefundsInternal(
|
|
29887
|
-
cpfpRefundTx,
|
|
29888
|
-
refundSighash,
|
|
29889
|
-
leaf,
|
|
29890
|
-
cpfpSigningCommitments[i]?.signingNonceCommitments
|
|
29891
|
-
);
|
|
29892
|
-
cpfpLeafSigningJobs.push(...signingJobs);
|
|
29893
|
-
if (directRefundTx) {
|
|
29894
|
-
if (!directNodeTx) {
|
|
29895
|
-
throw new ValidationError(
|
|
29896
|
-
"Direct node transaction undefined while direct refund transaction is defined",
|
|
29897
|
-
{
|
|
29898
|
-
field: "directNodeTx",
|
|
29899
|
-
value: directNodeTx,
|
|
29900
|
-
expected: "Non-null direct node transaction"
|
|
29901
|
-
}
|
|
29902
|
-
);
|
|
29903
|
-
}
|
|
29904
|
-
const refundSighash2 = getSigHashFromTx(
|
|
29905
|
-
directRefundTx,
|
|
29906
|
-
0,
|
|
29907
|
-
directNodeTx.getOutput(0)
|
|
29908
|
-
);
|
|
29909
|
-
const signingJobs2 = await this.signRefundsInternal(
|
|
29910
|
-
directRefundTx,
|
|
29911
|
-
refundSighash2,
|
|
29912
|
-
leaf,
|
|
29913
|
-
directSigningCommitments[i]?.signingNonceCommitments
|
|
29914
|
-
);
|
|
29915
|
-
directLeafSigningJobs.push(...signingJobs2);
|
|
29916
|
-
}
|
|
29917
|
-
if (directFromCpfpRefundTx) {
|
|
29918
|
-
if (!directNodeTx) {
|
|
29919
|
-
throw new ValidationError(
|
|
29920
|
-
"Direct node transaction undefined while direct from CPFP refund transaction is defined",
|
|
29921
|
-
{
|
|
29922
|
-
field: "directNodeTx",
|
|
29923
|
-
value: directNodeTx,
|
|
29924
|
-
expected: "Non-null direct node transaction"
|
|
29925
|
-
}
|
|
29926
|
-
);
|
|
29927
|
-
}
|
|
29928
|
-
const refundSighash2 = getSigHashFromTx(
|
|
29929
|
-
directFromCpfpRefundTx,
|
|
29930
|
-
0,
|
|
29931
|
-
nodeTx.getOutput(0)
|
|
29932
|
-
);
|
|
29933
|
-
const signingJobs2 = await this.signRefundsInternal(
|
|
29934
|
-
directFromCpfpRefundTx,
|
|
29935
|
-
refundSighash2,
|
|
29936
|
-
leaf,
|
|
29937
|
-
directFromCpfpSigningCommitments[i]?.signingNonceCommitments
|
|
29938
|
-
);
|
|
29939
|
-
directFromCpfpLeafSigningJobs.push(...signingJobs2);
|
|
29940
|
-
}
|
|
29941
29917
|
}
|
|
29918
|
+
const receiverEciesPrivKey = ecies2.PrivateKey.fromHex(
|
|
29919
|
+
(0, import_utils18.bytesToHex)(this.identityKey.privateKey)
|
|
29920
|
+
);
|
|
29921
|
+
const privateKey = ecies2.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
|
|
29922
|
+
const publicKey = import_secp256k111.secp256k1.getPublicKey(privateKey);
|
|
29923
|
+
return publicKey;
|
|
29924
|
+
}
|
|
29925
|
+
async getRandomSigningCommitment() {
|
|
29926
|
+
const nonce = getRandomSigningNonce();
|
|
29927
|
+
const commitment = getSigningCommitmentFromNonce(nonce);
|
|
29928
|
+
this.commitmentToNonceMap.set(commitment, nonce);
|
|
29942
29929
|
return {
|
|
29943
|
-
|
|
29944
|
-
directLeafSigningJobs,
|
|
29945
|
-
directFromCpfpLeafSigningJobs
|
|
29930
|
+
commitment
|
|
29946
29931
|
};
|
|
29947
29932
|
}
|
|
29933
|
+
async validateMessageWithIdentityKey(message, signature) {
|
|
29934
|
+
if (!this.identityKey?.publicKey) {
|
|
29935
|
+
throw new ConfigurationError("Identity key not initialized", {
|
|
29936
|
+
configKey: "identityKey"
|
|
29937
|
+
});
|
|
29938
|
+
}
|
|
29939
|
+
return import_secp256k111.secp256k1.verify(signature, message, this.identityKey.publicKey);
|
|
29940
|
+
}
|
|
29941
|
+
signTransactionIndex(tx, index, publicKey) {
|
|
29942
|
+
let privateKey;
|
|
29943
|
+
if ((0, import_utils18.equalBytes)(publicKey, this.identityKey?.publicKey ?? new Uint8Array())) {
|
|
29944
|
+
privateKey = this.identityKey?.privateKey;
|
|
29945
|
+
} else if ((0, import_utils18.equalBytes)(publicKey, this.depositKey?.publicKey ?? new Uint8Array())) {
|
|
29946
|
+
privateKey = this.depositKey?.privateKey;
|
|
29947
|
+
}
|
|
29948
|
+
if (!privateKey) {
|
|
29949
|
+
throw new ValidationError("Private key not found for public key", {
|
|
29950
|
+
field: "privateKey",
|
|
29951
|
+
value: (0, import_utils18.bytesToHex)(publicKey)
|
|
29952
|
+
});
|
|
29953
|
+
}
|
|
29954
|
+
tx.signIdx(privateKey, index);
|
|
29955
|
+
}
|
|
29948
29956
|
};
|
|
29949
29957
|
|
|
29950
29958
|
// src/tests/utils/test-faucet.ts
|
|
@@ -29965,7 +29973,7 @@ var COIN_AMOUNT = 10000000n;
|
|
|
29965
29973
|
var FEE_AMOUNT = 1000n;
|
|
29966
29974
|
var TARGET_NUM_COINS = 20;
|
|
29967
29975
|
var BitcoinFaucet = class _BitcoinFaucet {
|
|
29968
|
-
constructor(url
|
|
29976
|
+
constructor(url, username, password) {
|
|
29969
29977
|
this.url = url;
|
|
29970
29978
|
this.username = username;
|
|
29971
29979
|
this.password = password;
|
|
@@ -29978,8 +29986,11 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29978
29986
|
static instance = null;
|
|
29979
29987
|
miningAddress;
|
|
29980
29988
|
lock = Promise.resolve();
|
|
29981
|
-
static getInstance(
|
|
29989
|
+
static getInstance() {
|
|
29982
29990
|
if (!_BitcoinFaucet.instance) {
|
|
29991
|
+
const url = process.env.BITCOIN_RPC_URL || (process.env.MINIKUBE_IP ? `http://${process.env.MINIKUBE_IP}:8332` : "http://127.0.0.1:8332");
|
|
29992
|
+
const username = process.env.BITCOIN_RPC_USER || "testutil";
|
|
29993
|
+
const password = process.env.BITCOIN_RPC_PASSWORD || "testutilpassword";
|
|
29983
29994
|
_BitcoinFaucet.instance = new _BitcoinFaucet(url, username, password);
|
|
29984
29995
|
}
|
|
29985
29996
|
return _BitcoinFaucet.instance;
|
|
@@ -30308,6 +30319,76 @@ function chunkArray(arr, size) {
|
|
|
30308
30319
|
return chunks;
|
|
30309
30320
|
}
|
|
30310
30321
|
|
|
30322
|
+
// src/utils/optimize.ts
|
|
30323
|
+
init_buffer();
|
|
30324
|
+
var DENOMINATIONS = Array.from({ length: 28 }, (_, i) => 2 ** i);
|
|
30325
|
+
function assert(condition, message) {
|
|
30326
|
+
if (!condition) {
|
|
30327
|
+
throw new InternalValidationError(message || "Assertion failed");
|
|
30328
|
+
}
|
|
30329
|
+
}
|
|
30330
|
+
function sum(arr) {
|
|
30331
|
+
return arr.reduce((a, b) => a + b, 0);
|
|
30332
|
+
}
|
|
30333
|
+
function sorted(arr) {
|
|
30334
|
+
return [...arr].sort((a, b) => a - b);
|
|
30335
|
+
}
|
|
30336
|
+
function equals(a, b) {
|
|
30337
|
+
return a.length === b.length && a.every((val, index) => val === b[index]);
|
|
30338
|
+
}
|
|
30339
|
+
function greedyLeaves(amount) {
|
|
30340
|
+
const leaves = [];
|
|
30341
|
+
let remaining = amount;
|
|
30342
|
+
for (let i = DENOMINATIONS.length - 1; i >= 0; i--) {
|
|
30343
|
+
const leaf = DENOMINATIONS[i];
|
|
30344
|
+
if (typeof leaf === "number" && leaf > 0) {
|
|
30345
|
+
while (remaining >= leaf) {
|
|
30346
|
+
remaining -= leaf;
|
|
30347
|
+
leaves.push(leaf);
|
|
30348
|
+
}
|
|
30349
|
+
}
|
|
30350
|
+
}
|
|
30351
|
+
assert(sum(leaves) === amount, "greedy_leaves: sum mismatch");
|
|
30352
|
+
return sorted(leaves);
|
|
30353
|
+
}
|
|
30354
|
+
var Swap = class {
|
|
30355
|
+
inLeaves;
|
|
30356
|
+
outLeaves;
|
|
30357
|
+
constructor(inLeaves, outLeaves) {
|
|
30358
|
+
this.inLeaves = [...inLeaves];
|
|
30359
|
+
this.outLeaves = [...outLeaves];
|
|
30360
|
+
assert(
|
|
30361
|
+
sum(this.inLeaves) === sum(this.outLeaves),
|
|
30362
|
+
"Swap in/out leaves must sum to same value for swap: " + this.toString()
|
|
30363
|
+
);
|
|
30364
|
+
}
|
|
30365
|
+
toString() {
|
|
30366
|
+
return `Swap(in=${JSON.stringify(this.inLeaves)}, out=${JSON.stringify(this.outLeaves)})`;
|
|
30367
|
+
}
|
|
30368
|
+
};
|
|
30369
|
+
function maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap = 64) {
|
|
30370
|
+
const swaps = [];
|
|
30371
|
+
let batch = [];
|
|
30372
|
+
let leaves = sorted(inputLeaves);
|
|
30373
|
+
while (leaves.length > 0) {
|
|
30374
|
+
batch.push(leaves.shift());
|
|
30375
|
+
const target = greedyLeaves(sum(batch));
|
|
30376
|
+
if (batch.length >= maxLeavesPerSwap || target.length >= maxLeavesPerSwap) {
|
|
30377
|
+
if (!equals(target, batch)) {
|
|
30378
|
+
swaps.push(new Swap([...batch], target));
|
|
30379
|
+
}
|
|
30380
|
+
batch = [];
|
|
30381
|
+
}
|
|
30382
|
+
}
|
|
30383
|
+
if (batch.length > 0) {
|
|
30384
|
+
const target = greedyLeaves(sum(batch));
|
|
30385
|
+
if (!equals(target, batch)) {
|
|
30386
|
+
swaps.push(new Swap([...batch], target));
|
|
30387
|
+
}
|
|
30388
|
+
}
|
|
30389
|
+
return swaps;
|
|
30390
|
+
}
|
|
30391
|
+
|
|
30311
30392
|
// src/utils/retry.ts
|
|
30312
30393
|
init_buffer();
|
|
30313
30394
|
var DEFAULT_RETRY_CONFIG = {
|
|
@@ -30411,8 +30492,9 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30411
30492
|
// Add this property near the top of the class with other private properties
|
|
30412
30493
|
claimTransfersInterval = null;
|
|
30413
30494
|
tracer = null;
|
|
30414
|
-
constructor(options,
|
|
30495
|
+
constructor(options, signerArg) {
|
|
30415
30496
|
super();
|
|
30497
|
+
const signer = signerArg || this.buildSigner();
|
|
30416
30498
|
this.config = new WalletConfigService(options, signer);
|
|
30417
30499
|
this.connectionManager = this.buildConnectionManager(this.config);
|
|
30418
30500
|
this.signingService = new SigningService(this.config);
|
|
@@ -30470,6 +30552,9 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30470
30552
|
}
|
|
30471
30553
|
return this.sspClient;
|
|
30472
30554
|
}
|
|
30555
|
+
buildSigner() {
|
|
30556
|
+
return new DefaultSparkSigner();
|
|
30557
|
+
}
|
|
30473
30558
|
buildConnectionManager(config) {
|
|
30474
30559
|
return new ConnectionManager(config);
|
|
30475
30560
|
}
|
|
@@ -30831,8 +30916,34 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30831
30916
|
await this.withLeaves(async () => {
|
|
30832
30917
|
this.optimizationInProgress = true;
|
|
30833
30918
|
try {
|
|
30834
|
-
|
|
30835
|
-
|
|
30919
|
+
this.leaves = await this.getLeaves();
|
|
30920
|
+
const swaps = maximizeUnilateralExit(
|
|
30921
|
+
this.leaves.map((leaf) => leaf.value)
|
|
30922
|
+
);
|
|
30923
|
+
const valueToNodes = /* @__PURE__ */ new Map();
|
|
30924
|
+
this.leaves.forEach((leaf) => {
|
|
30925
|
+
if (!valueToNodes.has(leaf.value)) {
|
|
30926
|
+
valueToNodes.set(leaf.value, []);
|
|
30927
|
+
}
|
|
30928
|
+
valueToNodes.get(leaf.value).push(leaf);
|
|
30929
|
+
});
|
|
30930
|
+
for (const swap of swaps) {
|
|
30931
|
+
const leavesToSend = [];
|
|
30932
|
+
for (const leafValue of swap.inLeaves) {
|
|
30933
|
+
const nodes = valueToNodes.get(leafValue);
|
|
30934
|
+
if (nodes && nodes.length > 0) {
|
|
30935
|
+
const node = nodes.shift();
|
|
30936
|
+
leavesToSend.push(node);
|
|
30937
|
+
} else {
|
|
30938
|
+
throw new InternalValidationError(
|
|
30939
|
+
`No unused leaf with value ${leafValue} found in leaves`
|
|
30940
|
+
);
|
|
30941
|
+
}
|
|
30942
|
+
}
|
|
30943
|
+
await this.requestLeavesSwap({
|
|
30944
|
+
leaves: leavesToSend,
|
|
30945
|
+
targetAmounts: swap.outLeaves
|
|
30946
|
+
});
|
|
30836
30947
|
}
|
|
30837
30948
|
this.leaves = await this.getLeaves();
|
|
30838
30949
|
} finally {
|
|
@@ -31403,6 +31514,10 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31403
31514
|
directSignatureMap,
|
|
31404
31515
|
directFromCpfpSignatureMap
|
|
31405
31516
|
);
|
|
31517
|
+
const leavesToRemove = new Set(leavesBatch.map((leaf) => leaf.id));
|
|
31518
|
+
this.leaves = [
|
|
31519
|
+
...this.leaves.filter((leaf) => !leavesToRemove.has(leaf.id))
|
|
31520
|
+
];
|
|
31406
31521
|
const completeResponse = await sspClient.completeLeaveSwap({
|
|
31407
31522
|
adaptorSecretKey: (0, import_utils23.bytesToHex)(cpfpAdaptorPrivateKey),
|
|
31408
31523
|
directAdaptorSecretKey: (0, import_utils23.bytesToHex)(directAdaptorPrivateKey),
|
|
@@ -31991,7 +32106,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31991
32106
|
creditAmountView.setUint32(4, upperHalf, true);
|
|
31992
32107
|
parts.push(new Uint8Array(creditAmountBuffer));
|
|
31993
32108
|
parts.push((0, import_utils23.hexToBytes)(sspSignature));
|
|
31994
|
-
const totalLength = parts.reduce((
|
|
32109
|
+
const totalLength = parts.reduce((sum2, part) => sum2 + part.length, 0);
|
|
31995
32110
|
const payload = new Uint8Array(totalLength);
|
|
31996
32111
|
let offset = 0;
|
|
31997
32112
|
for (const part of parts) {
|
|
@@ -33087,8 +33202,8 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33087
33202
|
);
|
|
33088
33203
|
const sspResponse = await sspClient.requestLightningSend({
|
|
33089
33204
|
encodedInvoice: invoice,
|
|
33090
|
-
|
|
33091
|
-
|
|
33205
|
+
amountSats: isZeroAmountInvoice ? amountSatsToSend : void 0,
|
|
33206
|
+
userOutboundTransferExternalId: swapResponse.transfer.id
|
|
33092
33207
|
});
|
|
33093
33208
|
if (!sspResponse) {
|
|
33094
33209
|
throw new Error("Failed to contact SSP");
|
|
@@ -33394,12 +33509,13 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33394
33509
|
}
|
|
33395
33510
|
}))
|
|
33396
33511
|
);
|
|
33512
|
+
const transferId = (0, import_uuidv75.uuidv7)();
|
|
33397
33513
|
const requestCoopExitParams = {
|
|
33398
33514
|
leafExternalIds: leavesToSendToSsp.map((leaf) => leaf.id),
|
|
33399
33515
|
withdrawalAddress: onchainAddress,
|
|
33400
|
-
idempotencyKey: (0, import_uuidv75.uuidv7)(),
|
|
33401
33516
|
exitSpeed,
|
|
33402
|
-
withdrawAll: deductFeeFromWithdrawalAmount
|
|
33517
|
+
withdrawAll: deductFeeFromWithdrawalAmount,
|
|
33518
|
+
userOutboundTransferExternalId: transferId
|
|
33403
33519
|
};
|
|
33404
33520
|
if (!deductFeeFromWithdrawalAmount) {
|
|
33405
33521
|
requestCoopExitParams.feeQuoteId = feeEstimate.id;
|
|
@@ -33434,11 +33550,11 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33434
33550
|
leaves: leafKeyTweaks,
|
|
33435
33551
|
exitTxId: coopExitTxId,
|
|
33436
33552
|
connectorOutputs,
|
|
33437
|
-
receiverPubKey: sspPubIdentityKey
|
|
33553
|
+
receiverPubKey: sspPubIdentityKey,
|
|
33554
|
+
transferId
|
|
33438
33555
|
});
|
|
33439
33556
|
const completeResponse = await sspClient.completeCoopExit({
|
|
33440
|
-
userOutboundTransferExternalId: transfer.transfer.id
|
|
33441
|
-
coopExitRequestId: coopExitRequest.id
|
|
33557
|
+
userOutboundTransferExternalId: transfer.transfer.id
|
|
33442
33558
|
});
|
|
33443
33559
|
return completeResponse;
|
|
33444
33560
|
}
|
|
@@ -34160,7 +34276,6 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
34160
34276
|
const consoleOptions = wallet.config.getConsoleOptions();
|
|
34161
34277
|
const spanProcessors = [];
|
|
34162
34278
|
if (consoleOptions.otel) {
|
|
34163
|
-
console.log("OpenTelemetry client logging enabled.");
|
|
34164
34279
|
spanProcessors.push(new import_sdk_trace_base.SimpleSpanProcessor(new import_sdk_trace_base.ConsoleSpanExporter()));
|
|
34165
34280
|
}
|
|
34166
34281
|
const traceUrls = this.getOtelTraceUrls();
|
|
@@ -34353,7 +34468,6 @@ var SparkWalletBrowser = class extends SparkWallet {
|
|
|
34353
34468
|
spanProcessors,
|
|
34354
34469
|
traceUrls
|
|
34355
34470
|
}) {
|
|
34356
|
-
console.log("initializeTracerEnvBrowser");
|
|
34357
34471
|
initializeTracerEnvBrowser({ spanProcessors, traceUrls });
|
|
34358
34472
|
}
|
|
34359
34473
|
};
|