@buildonspark/spark-sdk 0.1.41 → 0.1.43
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 +15 -0
- package/android/src/main/jniLibs/arm64-v8a/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/x86/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/x86_64/libuniffi_spark_frost.so +0 -0
- package/dist/LightningSendFeeEstimateInput-BgOhEAI-.d.cts +10 -0
- package/dist/LightningSendFeeEstimateInput-BgOhEAI-.d.ts +10 -0
- package/dist/{RequestLightningSendInput-mXUWn_cp.d.ts → RequestLightningSendInput-D7fZdT4A.d.ts} +35 -16
- package/dist/{RequestLightningSendInput-DXcLoiCe.d.cts → RequestLightningSendInput-Na1mHdWg.d.cts} +35 -16
- package/dist/address/index.cjs +38 -7
- package/dist/address/index.d.cts +2 -2
- package/dist/address/index.d.ts +2 -2
- package/dist/address/index.js +3 -3
- package/dist/{chunk-ATEHMLKP.js → chunk-6AFUC5M2.js} +1 -1
- package/dist/{chunk-ZXDE2XMU.js → chunk-BUTZWYBW.js} +9 -6
- package/dist/{chunk-7EFSUADA.js → chunk-DOA6QXYQ.js} +1 -0
- package/dist/{chunk-J5W5Q2ZP.js → chunk-DQYKQJRZ.js} +291 -7
- package/dist/{chunk-TWF35O6M.js → chunk-GSI4OLXZ.js} +32 -1
- package/dist/{chunk-2ZXXLPG2.js → chunk-GYQR4B4P.js} +5 -4
- package/dist/{chunk-ROKY5KS4.js → chunk-HRQRRDSS.js} +53 -15
- package/dist/{chunk-YEZDPUFY.js → chunk-IRW5TWMH.js} +8 -8
- package/dist/{chunk-7VMYMQLF.js → chunk-NSJF5F5O.js} +1 -1
- package/dist/{chunk-TM4TOEOX.js → chunk-O4RYNJNB.js} +3 -3
- package/dist/{chunk-MGPRLH6Q.js → chunk-QNNSEJ4P.js} +1 -1
- package/dist/{chunk-UKT6OFLO.js → chunk-TIUBYNN5.js} +13 -7
- package/dist/{chunk-6YVPOQ2A.js → chunk-TOSP3INR.js} +235 -143
- package/dist/chunk-VFJQNBFX.js +21 -0
- package/dist/{chunk-KKSU7OZO.js → chunk-WWOTVNPP.js} +195 -67
- package/dist/{chunk-HK6LPV6Z.js → chunk-Z5HIAYFT.js} +1 -1
- package/dist/graphql/objects/index.cjs +229 -135
- package/dist/graphql/objects/index.d.cts +54 -9
- package/dist/graphql/objects/index.d.ts +54 -9
- package/dist/graphql/objects/index.js +3 -3
- package/dist/{index-OSDtPMmC.d.ts → index-7RYRH5wc.d.ts} +10 -8
- package/dist/{index-CFh4uWzi.d.cts → index-BJOc8Ur-.d.cts} +10 -8
- package/dist/index.cjs +790 -315
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +26 -26
- package/dist/index.node.cjs +790 -315
- package/dist/index.node.d.cts +9 -8
- package/dist/index.node.d.ts +9 -8
- package/dist/index.node.js +26 -26
- package/dist/native/index.cjs +812 -332
- package/dist/native/index.d.cts +53 -18
- package/dist/native/index.d.ts +53 -18
- package/dist/native/index.js +659 -181
- package/dist/{network-BiwBmoOg.d.cts → network-D5lKssVl.d.cts} +1 -1
- package/dist/{network-BF2GYPye.d.ts → network-xkBSpaTn.d.ts} +1 -1
- package/dist/proto/lrc20.d.cts +1 -1
- package/dist/proto/lrc20.d.ts +1 -1
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark_token.d.cts +1 -1
- package/dist/proto/spark_token.d.ts +1 -1
- package/dist/{sdk-types-CfhdFnsA.d.cts → sdk-types-B-q9py_P.d.cts} +1 -1
- package/dist/{sdk-types-MnQrHolg.d.ts → sdk-types-BPoPgzda.d.ts} +1 -1
- package/dist/services/config.cjs +118 -69
- package/dist/services/config.d.cts +6 -4
- package/dist/services/config.d.ts +6 -4
- package/dist/services/config.js +9 -9
- package/dist/services/connection.cjs +95 -15
- package/dist/services/connection.d.cts +6 -4
- package/dist/services/connection.d.ts +6 -4
- package/dist/services/connection.js +3 -3
- package/dist/services/index.cjs +487 -117
- package/dist/services/index.d.cts +5 -4
- package/dist/services/index.d.ts +5 -4
- package/dist/services/index.js +19 -19
- package/dist/services/lrc-connection.cjs +50 -7
- package/dist/services/lrc-connection.d.cts +5 -4
- package/dist/services/lrc-connection.d.ts +5 -4
- package/dist/services/lrc-connection.js +3 -3
- package/dist/services/token-transactions.cjs +351 -36
- package/dist/services/token-transactions.d.cts +5 -4
- package/dist/services/token-transactions.d.ts +5 -4
- package/dist/services/token-transactions.js +6 -6
- package/dist/services/wallet-config.cjs +1 -0
- package/dist/services/wallet-config.d.cts +6 -4
- package/dist/services/wallet-config.d.ts +6 -4
- package/dist/services/wallet-config.js +1 -1
- package/dist/signer/signer.cjs +117 -64
- package/dist/signer/signer.d.cts +4 -3
- package/dist/signer/signer.d.ts +4 -3
- package/dist/signer/signer.js +15 -7
- package/dist/{signer-CylxIujU.d.ts → signer-IO3oMRNj.d.cts} +2 -1
- package/dist/{signer-BhLS7SYR.d.cts → signer-wqesWifN.d.ts} +2 -1
- package/dist/{spark-DjR1b3TC.d.cts → spark-CDm4gqS6.d.cts} +1 -1
- package/dist/{spark-DjR1b3TC.d.ts → spark-CDm4gqS6.d.ts} +1 -1
- package/dist/types/index.cjs +282 -188
- package/dist/types/index.d.cts +7 -6
- package/dist/types/index.d.ts +7 -6
- package/dist/types/index.js +3 -3
- package/dist/utils/index.cjs +90 -58
- package/dist/utils/index.d.cts +6 -5
- package/dist/utils/index.d.ts +6 -5
- package/dist/utils/index.js +16 -16
- package/ios/spark_frostFFI.xcframework/ios-arm64/SparkFrost +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/SparkFrost +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/ios/spark_frostFFI.xcframework/macos-arm64_x86_64/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/package.json +4 -4
- package/src/constants.ts +21 -0
- package/src/errors/base.ts +43 -1
- package/src/graphql/client.ts +4 -0
- package/src/graphql/mutations/RequestLightningSend.ts +2 -0
- package/src/graphql/objects/ClaimStaticDepositInput.ts +1 -1
- package/src/graphql/objects/ClaimStaticDepositStatus.ts +4 -2
- package/src/graphql/objects/Connection.ts +7 -7
- package/src/graphql/objects/CoopExitFeeEstimate.ts +1 -1
- package/src/graphql/objects/CoopExitFeeQuote.ts +202 -0
- package/src/graphql/objects/CoopExitFeeQuoteInput.ts +41 -0
- package/src/graphql/objects/CoopExitFeeQuoteOutput.ts +45 -0
- package/src/graphql/objects/CoopExitRequest.ts +21 -0
- package/src/graphql/objects/CurrencyUnit.ts +26 -28
- package/src/graphql/objects/Entity.ts +84 -0
- package/src/graphql/objects/Invoice.ts +2 -2
- package/src/graphql/objects/Leaf.ts +1 -1
- package/src/graphql/objects/LeavesSwapFeeEstimateOutput.ts +1 -1
- package/src/graphql/objects/LeavesSwapRequest.ts +6 -0
- package/src/graphql/objects/LightningReceiveRequest.ts +11 -0
- package/src/graphql/objects/LightningSendFeeEstimateInput.ts +8 -0
- package/src/graphql/objects/LightningSendFeeEstimateOutput.ts +1 -1
- package/src/graphql/objects/LightningSendRequest.ts +3 -0
- package/src/graphql/objects/RequestCoopExitInput.ts +8 -0
- package/src/graphql/objects/RequestLeavesSwapInput.ts +5 -1
- package/src/graphql/objects/RequestLightningReceiveInput.ts +9 -2
- package/src/graphql/objects/RequestLightningSendInput.ts +8 -0
- package/src/graphql/objects/SparkCoopExitRequestStatus.ts +2 -0
- package/src/graphql/objects/SparkUserRequestType.ts +2 -0
- package/src/graphql/objects/SparkWalletUser.ts +20 -0
- package/src/graphql/objects/UserRequest.ts +32 -0
- package/src/graphql/objects/VerifyChallengeInput.ts +1 -1
- package/src/graphql/objects/index.ts +12 -3
- package/src/graphql/queries/LightningSendFeeEstimate.ts +2 -0
- package/src/logger.ts +3 -0
- package/src/native/index.ts +1 -0
- package/src/services/config.ts +4 -0
- package/src/services/connection.ts +68 -29
- package/src/services/coop-exit.ts +1 -1
- package/src/services/lightning.ts +25 -1
- package/src/services/lrc-connection.ts +3 -3
- package/src/services/token-transactions.ts +6 -2
- package/src/services/wallet-config.ts +2 -0
- package/src/signer/signer.ts +4 -1
- package/src/spark-wallet/spark-wallet.ts +51 -15
- package/src/spark-wallet/types.ts +1 -0
- package/src/tests/errors.test.ts +58 -0
- package/src/tests/integration/lightning.test.ts +184 -0
- package/src/tests/integration/ssp/static_deposit.test.ts +1 -2
- package/src/tests/tokens.test.ts +52 -3
- package/src/utils/token-hashing.ts +335 -1
- package/dist/LightningSendFeeEstimateInput-CJvPnCSB.d.cts +0 -5
- package/dist/LightningSendFeeEstimateInput-CJvPnCSB.d.ts +0 -5
- package/dist/chunk-HKAKEKCE.js +0 -8
|
@@ -2,19 +2,19 @@ import {
|
|
|
2
2
|
calculateAvailableTokenAmount,
|
|
3
3
|
checkIfSelectedOutputsAreAvailable,
|
|
4
4
|
collectResponses
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6AFUC5M2.js";
|
|
6
6
|
import {
|
|
7
7
|
decodeSparkAddress
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-O4RYNJNB.js";
|
|
9
9
|
import {
|
|
10
10
|
bigIntToPrivateKey,
|
|
11
11
|
recoverSecret
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QNNSEJ4P.js";
|
|
13
13
|
import {
|
|
14
14
|
InternalValidationError,
|
|
15
15
|
NetworkError,
|
|
16
16
|
ValidationError
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GSI4OLXZ.js";
|
|
18
18
|
import {
|
|
19
19
|
Buffer
|
|
20
20
|
} from "./chunk-MVRQ5US7.js";
|
|
@@ -30,6 +30,19 @@ import { secp256k1 as secp256k12 } from "@noble/curves/secp256k1";
|
|
|
30
30
|
// src/utils/token-hashing.ts
|
|
31
31
|
import { sha256 } from "@noble/hashes/sha2";
|
|
32
32
|
function hashTokenTransaction(tokenTransaction, partialHash = false) {
|
|
33
|
+
switch (tokenTransaction.version) {
|
|
34
|
+
case 0:
|
|
35
|
+
return hashTokenTransactionV0(tokenTransaction, partialHash);
|
|
36
|
+
case 1:
|
|
37
|
+
return hashTokenTransactionV1(tokenTransaction, partialHash);
|
|
38
|
+
default:
|
|
39
|
+
throw new ValidationError("invalid token transaction version", {
|
|
40
|
+
field: "tokenTransaction.version",
|
|
41
|
+
value: tokenTransaction.version
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function hashTokenTransactionV0(tokenTransaction, partialHash = false) {
|
|
33
46
|
if (!tokenTransaction) {
|
|
34
47
|
throw new ValidationError("token transaction cannot be nil", {
|
|
35
48
|
field: "tokenTransaction"
|
|
@@ -277,6 +290,275 @@ function hashTokenTransaction(tokenTransaction, partialHash = false) {
|
|
|
277
290
|
finalHashObj.update(concatenatedHashes);
|
|
278
291
|
return finalHashObj.digest();
|
|
279
292
|
}
|
|
293
|
+
function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
|
|
294
|
+
if (!tokenTransaction) {
|
|
295
|
+
throw new ValidationError("token transaction cannot be nil", {
|
|
296
|
+
field: "tokenTransaction"
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
let allHashes = [];
|
|
300
|
+
const versionHashObj = sha256.create();
|
|
301
|
+
const versionBytes = new Uint8Array(4);
|
|
302
|
+
new DataView(versionBytes.buffer).setUint32(
|
|
303
|
+
0,
|
|
304
|
+
tokenTransaction.version,
|
|
305
|
+
false
|
|
306
|
+
// false for big-endian
|
|
307
|
+
);
|
|
308
|
+
versionHashObj.update(versionBytes);
|
|
309
|
+
allHashes.push(versionHashObj.digest());
|
|
310
|
+
if (tokenTransaction.tokenInputs?.$case === "transferInput") {
|
|
311
|
+
if (!tokenTransaction.tokenInputs.transferInput.outputsToSpend) {
|
|
312
|
+
throw new ValidationError("outputs to spend cannot be null", {
|
|
313
|
+
field: "tokenInputs.transferInput.outputsToSpend"
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
if (tokenTransaction.tokenInputs.transferInput.outputsToSpend.length === 0) {
|
|
317
|
+
throw new ValidationError("outputs to spend cannot be empty", {
|
|
318
|
+
field: "tokenInputs.transferInput.outputsToSpend"
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
for (const [
|
|
322
|
+
i,
|
|
323
|
+
output
|
|
324
|
+
] of tokenTransaction.tokenInputs.transferInput.outputsToSpend.entries()) {
|
|
325
|
+
if (!output) {
|
|
326
|
+
throw new ValidationError(`output cannot be null at index ${i}`, {
|
|
327
|
+
field: `tokenInputs.transferInput.outputsToSpend[${i}]`,
|
|
328
|
+
index: i
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
const hashObj2 = sha256.create();
|
|
332
|
+
if (output.prevTokenTransactionHash) {
|
|
333
|
+
const prevHash = output.prevTokenTransactionHash;
|
|
334
|
+
if (output.prevTokenTransactionHash.length !== 32) {
|
|
335
|
+
throw new ValidationError(
|
|
336
|
+
`invalid previous transaction hash length at index ${i}`,
|
|
337
|
+
{
|
|
338
|
+
field: `tokenInputs.transferInput.outputsToSpend[${i}].prevTokenTransactionHash`,
|
|
339
|
+
value: prevHash,
|
|
340
|
+
expectedLength: 32,
|
|
341
|
+
actualLength: prevHash.length,
|
|
342
|
+
index: i
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
hashObj2.update(output.prevTokenTransactionHash);
|
|
347
|
+
}
|
|
348
|
+
const voutBytes = new Uint8Array(4);
|
|
349
|
+
new DataView(voutBytes.buffer).setUint32(
|
|
350
|
+
0,
|
|
351
|
+
output.prevTokenTransactionVout,
|
|
352
|
+
false
|
|
353
|
+
);
|
|
354
|
+
hashObj2.update(voutBytes);
|
|
355
|
+
allHashes.push(hashObj2.digest());
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (tokenTransaction.tokenInputs?.$case === "mintInput") {
|
|
359
|
+
const hashObj2 = sha256.create();
|
|
360
|
+
if (tokenTransaction.tokenInputs.mintInput.issuerPublicKey) {
|
|
361
|
+
const issuerPubKey = tokenTransaction.tokenInputs.mintInput.issuerPublicKey;
|
|
362
|
+
if (issuerPubKey.length === 0) {
|
|
363
|
+
throw new ValidationError("issuer public key cannot be empty", {
|
|
364
|
+
field: "tokenInputs.mintInput.issuerPublicKey",
|
|
365
|
+
value: issuerPubKey,
|
|
366
|
+
expectedLength: 1,
|
|
367
|
+
actualLength: 0
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
hashObj2.update(issuerPubKey);
|
|
371
|
+
if (tokenTransaction.tokenInputs.mintInput.issuerProvidedTimestamp != 0) {
|
|
372
|
+
const timestampBytes = new Uint8Array(8);
|
|
373
|
+
new DataView(timestampBytes.buffer).setBigUint64(
|
|
374
|
+
0,
|
|
375
|
+
BigInt(
|
|
376
|
+
tokenTransaction.tokenInputs.mintInput.issuerProvidedTimestamp
|
|
377
|
+
),
|
|
378
|
+
true
|
|
379
|
+
// true for little-endian to match Go implementation
|
|
380
|
+
);
|
|
381
|
+
hashObj2.update(timestampBytes);
|
|
382
|
+
}
|
|
383
|
+
allHashes.push(hashObj2.digest());
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (!tokenTransaction.tokenOutputs) {
|
|
387
|
+
throw new ValidationError("token outputs cannot be null", {
|
|
388
|
+
field: "tokenOutputs"
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
if (tokenTransaction.tokenOutputs.length === 0) {
|
|
392
|
+
throw new ValidationError("token outputs cannot be empty", {
|
|
393
|
+
field: "tokenOutputs"
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
for (const [i, output] of tokenTransaction.tokenOutputs.entries()) {
|
|
397
|
+
if (!output) {
|
|
398
|
+
throw new ValidationError(`output cannot be null at index ${i}`, {
|
|
399
|
+
field: `tokenOutputs[${i}]`,
|
|
400
|
+
index: i
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
const hashObj2 = sha256.create();
|
|
404
|
+
if (output.id && !partialHash) {
|
|
405
|
+
if (output.id.length === 0) {
|
|
406
|
+
throw new ValidationError(`output ID at index ${i} cannot be empty`, {
|
|
407
|
+
field: `tokenOutputs[${i}].id`,
|
|
408
|
+
index: i
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
hashObj2.update(new TextEncoder().encode(output.id));
|
|
412
|
+
}
|
|
413
|
+
if (output.ownerPublicKey) {
|
|
414
|
+
if (output.ownerPublicKey.length === 0) {
|
|
415
|
+
throw new ValidationError(
|
|
416
|
+
`owner public key at index ${i} cannot be empty`,
|
|
417
|
+
{
|
|
418
|
+
field: `tokenOutputs[${i}].ownerPublicKey`,
|
|
419
|
+
index: i
|
|
420
|
+
}
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
hashObj2.update(output.ownerPublicKey);
|
|
424
|
+
}
|
|
425
|
+
if (!partialHash) {
|
|
426
|
+
const revPubKey = output.revocationCommitment;
|
|
427
|
+
if (revPubKey) {
|
|
428
|
+
if (revPubKey.length === 0) {
|
|
429
|
+
throw new ValidationError(
|
|
430
|
+
`revocation commitment at index ${i} cannot be empty`,
|
|
431
|
+
{
|
|
432
|
+
field: `tokenOutputs[${i}].revocationCommitment`,
|
|
433
|
+
index: i
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
hashObj2.update(revPubKey);
|
|
438
|
+
}
|
|
439
|
+
const bondBytes = new Uint8Array(8);
|
|
440
|
+
new DataView(bondBytes.buffer).setBigUint64(
|
|
441
|
+
0,
|
|
442
|
+
BigInt(output.withdrawBondSats),
|
|
443
|
+
false
|
|
444
|
+
);
|
|
445
|
+
hashObj2.update(bondBytes);
|
|
446
|
+
const locktimeBytes = new Uint8Array(8);
|
|
447
|
+
new DataView(locktimeBytes.buffer).setBigUint64(
|
|
448
|
+
0,
|
|
449
|
+
BigInt(output.withdrawRelativeBlockLocktime),
|
|
450
|
+
false
|
|
451
|
+
);
|
|
452
|
+
hashObj2.update(locktimeBytes);
|
|
453
|
+
}
|
|
454
|
+
if (output.tokenPublicKey) {
|
|
455
|
+
if (output.tokenPublicKey.length === 0) {
|
|
456
|
+
throw new ValidationError(
|
|
457
|
+
`token public key at index ${i} cannot be empty`,
|
|
458
|
+
{
|
|
459
|
+
field: `tokenOutputs[${i}].tokenPublicKey`,
|
|
460
|
+
index: i
|
|
461
|
+
}
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
hashObj2.update(output.tokenPublicKey);
|
|
465
|
+
}
|
|
466
|
+
if (output.tokenAmount) {
|
|
467
|
+
if (output.tokenAmount.length === 0) {
|
|
468
|
+
throw new ValidationError(
|
|
469
|
+
`token amount at index ${i} cannot be empty`,
|
|
470
|
+
{
|
|
471
|
+
field: `tokenOutputs[${i}].tokenAmount`,
|
|
472
|
+
index: i
|
|
473
|
+
}
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
if (output.tokenAmount.length > 16) {
|
|
477
|
+
throw new ValidationError(
|
|
478
|
+
`token amount at index ${i} exceeds maximum length`,
|
|
479
|
+
{
|
|
480
|
+
field: `tokenOutputs[${i}].tokenAmount`,
|
|
481
|
+
value: output.tokenAmount,
|
|
482
|
+
expectedLength: 16,
|
|
483
|
+
actualLength: output.tokenAmount.length,
|
|
484
|
+
index: i
|
|
485
|
+
}
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
hashObj2.update(output.tokenAmount);
|
|
489
|
+
}
|
|
490
|
+
allHashes.push(hashObj2.digest());
|
|
491
|
+
}
|
|
492
|
+
if (!tokenTransaction.sparkOperatorIdentityPublicKeys) {
|
|
493
|
+
throw new ValidationError(
|
|
494
|
+
"spark operator identity public keys cannot be null",
|
|
495
|
+
{}
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
const sortedPubKeys = [
|
|
499
|
+
...tokenTransaction.sparkOperatorIdentityPublicKeys || []
|
|
500
|
+
].sort((a, b) => {
|
|
501
|
+
for (let i = 0; i < a.length && i < b.length; i++) {
|
|
502
|
+
if (a[i] !== b[i]) return a[i] - b[i];
|
|
503
|
+
}
|
|
504
|
+
return a.length - b.length;
|
|
505
|
+
});
|
|
506
|
+
for (const [i, pubKey] of sortedPubKeys.entries()) {
|
|
507
|
+
if (!pubKey) {
|
|
508
|
+
throw new ValidationError(
|
|
509
|
+
`operator public key at index ${i} cannot be null`,
|
|
510
|
+
{
|
|
511
|
+
field: `sparkOperatorIdentityPublicKeys[${i}]`,
|
|
512
|
+
index: i
|
|
513
|
+
}
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
if (pubKey.length === 0) {
|
|
517
|
+
throw new ValidationError(
|
|
518
|
+
`operator public key at index ${i} cannot be empty`,
|
|
519
|
+
{
|
|
520
|
+
field: `sparkOperatorIdentityPublicKeys[${i}]`,
|
|
521
|
+
index: i
|
|
522
|
+
}
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
const hashObj2 = sha256.create();
|
|
526
|
+
hashObj2.update(pubKey);
|
|
527
|
+
allHashes.push(hashObj2.digest());
|
|
528
|
+
}
|
|
529
|
+
const hashObj = sha256.create();
|
|
530
|
+
let networkBytes = new Uint8Array(4);
|
|
531
|
+
new DataView(networkBytes.buffer).setUint32(
|
|
532
|
+
0,
|
|
533
|
+
tokenTransaction.network.valueOf(),
|
|
534
|
+
false
|
|
535
|
+
// false for big-endian
|
|
536
|
+
);
|
|
537
|
+
hashObj.update(networkBytes);
|
|
538
|
+
allHashes.push(hashObj.digest());
|
|
539
|
+
const expiryHashObj = sha256.create();
|
|
540
|
+
const validityDurationBytes = new Uint8Array(8);
|
|
541
|
+
const expiryUnixTime = tokenTransaction.expiryTime ? Math.floor(tokenTransaction.expiryTime.getTime() / 1e3) : 0;
|
|
542
|
+
new DataView(validityDurationBytes.buffer).setBigUint64(
|
|
543
|
+
0,
|
|
544
|
+
BigInt(expiryUnixTime),
|
|
545
|
+
false
|
|
546
|
+
// false for big-endian
|
|
547
|
+
);
|
|
548
|
+
expiryHashObj.update(validityDurationBytes);
|
|
549
|
+
allHashes.push(expiryHashObj.digest());
|
|
550
|
+
const finalHashObj = sha256.create();
|
|
551
|
+
const concatenatedHashes = new Uint8Array(
|
|
552
|
+
allHashes.reduce((sum, hash) => sum + hash.length, 0)
|
|
553
|
+
);
|
|
554
|
+
let offset = 0;
|
|
555
|
+
for (const hash of allHashes) {
|
|
556
|
+
concatenatedHashes.set(hash, offset);
|
|
557
|
+
offset += hash.length;
|
|
558
|
+
}
|
|
559
|
+
finalHashObj.update(concatenatedHashes);
|
|
560
|
+
return finalHashObj.digest();
|
|
561
|
+
}
|
|
280
562
|
function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
|
|
281
563
|
if (!payload) {
|
|
282
564
|
throw new ValidationError(
|
|
@@ -900,7 +1182,7 @@ var TokenTransactionService = class {
|
|
|
900
1182
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
901
1183
|
this.config.getCoordinatorAddress()
|
|
902
1184
|
);
|
|
903
|
-
const partialTokenTransactionHash =
|
|
1185
|
+
const partialTokenTransactionHash = hashTokenTransactionV0(
|
|
904
1186
|
tokenTransaction,
|
|
905
1187
|
true
|
|
906
1188
|
);
|
|
@@ -981,7 +1263,7 @@ var TokenTransactionService = class {
|
|
|
981
1263
|
this.config.getThreshold()
|
|
982
1264
|
);
|
|
983
1265
|
const finalTokenTransaction = startResponse.finalTokenTransaction;
|
|
984
|
-
const finalTokenTransactionHash =
|
|
1266
|
+
const finalTokenTransactionHash = hashTokenTransactionV0(
|
|
985
1267
|
finalTokenTransaction,
|
|
986
1268
|
false
|
|
987
1269
|
);
|
|
@@ -1049,7 +1331,9 @@ var TokenTransactionService = class {
|
|
|
1049
1331
|
const startResponse = await sparkClient.start_transaction(
|
|
1050
1332
|
{
|
|
1051
1333
|
identityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
1052
|
-
partialTokenTransaction: tokenTransaction
|
|
1334
|
+
partialTokenTransaction: tokenTransaction,
|
|
1335
|
+
validityDurationSeconds: await this.config.getTokenValidityDurationSeconds(),
|
|
1336
|
+
partialTokenTransactionOwnerSignatures: ownerSignaturesWithIndex
|
|
1053
1337
|
},
|
|
1054
1338
|
{
|
|
1055
1339
|
retry: true,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/errors/base.ts
|
|
2
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
2
3
|
var SparkSDKError = class extends Error {
|
|
3
4
|
context;
|
|
4
5
|
originalError;
|
|
@@ -30,12 +31,42 @@ var SparkSDKError = class extends Error {
|
|
|
30
31
|
}
|
|
31
32
|
};
|
|
32
33
|
function getMessage(message, context = {}, originalError) {
|
|
33
|
-
const contextStr = Object.entries(context).map(([key, value]) => `${key}: ${
|
|
34
|
+
const contextStr = Object.entries(context).map(([key, value]) => `${key}: ${safeStringify(value)}`).join(", ");
|
|
34
35
|
const originalErrorStr = originalError ? `
|
|
35
36
|
Original Error: ${originalError.message}` : "";
|
|
36
37
|
return `SparkSDKError: ${message}${contextStr ? `
|
|
37
38
|
Context: ${contextStr}` : ""}${originalErrorStr}`;
|
|
38
39
|
}
|
|
40
|
+
function safeStringify(value) {
|
|
41
|
+
const replacer = (_, v) => {
|
|
42
|
+
if (typeof v === "bigint") {
|
|
43
|
+
return v.toString();
|
|
44
|
+
}
|
|
45
|
+
if (v instanceof Uint8Array) {
|
|
46
|
+
return formatUint8Array(v);
|
|
47
|
+
}
|
|
48
|
+
return v;
|
|
49
|
+
};
|
|
50
|
+
if (typeof value === "bigint") {
|
|
51
|
+
return `"${value.toString()}"`;
|
|
52
|
+
}
|
|
53
|
+
if (value instanceof Uint8Array) {
|
|
54
|
+
return `"${formatUint8Array(value)}"`;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const result = JSON.stringify(value, replacer);
|
|
58
|
+
return result === void 0 ? String(value) : result;
|
|
59
|
+
} catch {
|
|
60
|
+
try {
|
|
61
|
+
return String(value);
|
|
62
|
+
} catch {
|
|
63
|
+
return "[Unserializable]";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function formatUint8Array(arr) {
|
|
68
|
+
return `Uint8Array(0x${bytesToHex(arr)})`;
|
|
69
|
+
}
|
|
39
70
|
|
|
40
71
|
// src/errors/types.ts
|
|
41
72
|
var NetworkError = class extends SparkSDKError {
|
|
@@ -2,12 +2,13 @@ import {
|
|
|
2
2
|
SparkServiceDefinition
|
|
3
3
|
} from "./chunk-ABZA6R5S.js";
|
|
4
4
|
import {
|
|
5
|
+
clientEnv,
|
|
5
6
|
isBun,
|
|
6
7
|
isReactNative
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-VFJQNBFX.js";
|
|
8
9
|
import {
|
|
9
10
|
NetworkError
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GSI4OLXZ.js";
|
|
11
12
|
|
|
12
13
|
// src/services/lrc-connection.ts
|
|
13
14
|
import { isNode } from "@lightsparkdev/core";
|
|
@@ -101,7 +102,7 @@ var Lrc20ConnectionManager = class {
|
|
|
101
102
|
return async function* (call, options) {
|
|
102
103
|
return yield* call.next(call.request, {
|
|
103
104
|
...options,
|
|
104
|
-
metadata: Metadata(options.metadata).set("
|
|
105
|
+
metadata: Metadata(options.metadata).set("X-Client-Env", clientEnv)
|
|
105
106
|
});
|
|
106
107
|
}.bind(this);
|
|
107
108
|
}
|
|
@@ -109,7 +110,7 @@ var Lrc20ConnectionManager = class {
|
|
|
109
110
|
return async function* (call, options) {
|
|
110
111
|
return yield* call.next(call.request, {
|
|
111
112
|
...options,
|
|
112
|
-
metadata: Metadata(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto").set("
|
|
113
|
+
metadata: Metadata(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto").set("X-Client-Env", clientEnv)
|
|
113
114
|
});
|
|
114
115
|
}.bind(this);
|
|
115
116
|
}
|
|
@@ -2,17 +2,18 @@ import {
|
|
|
2
2
|
SparkTokenServiceDefinition
|
|
3
3
|
} from "./chunk-VA7MV4MZ.js";
|
|
4
4
|
import {
|
|
5
|
+
Empty,
|
|
6
|
+
SparkServiceDefinition
|
|
7
|
+
} from "./chunk-M6A4KFIG.js";
|
|
8
|
+
import {
|
|
9
|
+
clientEnv,
|
|
5
10
|
isBun,
|
|
6
11
|
isReactNative
|
|
7
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-VFJQNBFX.js";
|
|
8
13
|
import {
|
|
9
14
|
AuthenticationError,
|
|
10
15
|
NetworkError
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import {
|
|
13
|
-
Empty,
|
|
14
|
-
SparkServiceDefinition
|
|
15
|
-
} from "./chunk-M6A4KFIG.js";
|
|
16
|
+
} from "./chunk-GSI4OLXZ.js";
|
|
16
17
|
|
|
17
18
|
// src/services/connection.ts
|
|
18
19
|
import { isNode } from "@lightsparkdev/core";
|
|
@@ -969,12 +970,36 @@ var ConnectionManager = class {
|
|
|
969
970
|
}
|
|
970
971
|
async createSparkAuthnGrpcConnection(address, certPath) {
|
|
971
972
|
const channel = await this.createChannelWithTLS(address, certPath);
|
|
973
|
+
const authnMiddleware = this.createAuthnMiddleware();
|
|
972
974
|
return this.createGrpcClient(
|
|
973
975
|
SparkAuthnServiceDefinition,
|
|
974
976
|
channel,
|
|
975
|
-
false
|
|
977
|
+
false,
|
|
978
|
+
authnMiddleware
|
|
976
979
|
);
|
|
977
980
|
}
|
|
981
|
+
createAuthnMiddleware() {
|
|
982
|
+
if (isNode) {
|
|
983
|
+
return async function* (call, options) {
|
|
984
|
+
const metadata = Metadata(options.metadata).set(
|
|
985
|
+
"X-Client-Env",
|
|
986
|
+
clientEnv
|
|
987
|
+
);
|
|
988
|
+
return yield* call.next(call.request, {
|
|
989
|
+
...options,
|
|
990
|
+
metadata
|
|
991
|
+
});
|
|
992
|
+
}.bind(this);
|
|
993
|
+
} else {
|
|
994
|
+
return async function* (call, options) {
|
|
995
|
+
const metadata = Metadata(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("X-Client-Env", clientEnv).set("Content-Type", "application/grpc-web+proto");
|
|
996
|
+
return yield* call.next(call.request, {
|
|
997
|
+
...options,
|
|
998
|
+
metadata
|
|
999
|
+
});
|
|
1000
|
+
}.bind(this);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
978
1003
|
createMiddleware(address, authToken) {
|
|
979
1004
|
if (isNode) {
|
|
980
1005
|
return this.createNodeMiddleware(address, authToken);
|
|
@@ -984,21 +1009,29 @@ var ConnectionManager = class {
|
|
|
984
1009
|
}
|
|
985
1010
|
createNodeMiddleware(address, initialAuthToken) {
|
|
986
1011
|
return async function* (call, options) {
|
|
1012
|
+
const metadata = Metadata(options.metadata).set(
|
|
1013
|
+
"X-Client-Env",
|
|
1014
|
+
clientEnv
|
|
1015
|
+
);
|
|
987
1016
|
try {
|
|
988
1017
|
return yield* call.next(call.request, {
|
|
989
1018
|
...options,
|
|
990
|
-
metadata:
|
|
1019
|
+
metadata: metadata.set(
|
|
991
1020
|
"Authorization",
|
|
992
1021
|
`Bearer ${this.clients.get(address)?.authToken || initialAuthToken}`
|
|
993
|
-
)
|
|
1022
|
+
)
|
|
994
1023
|
});
|
|
995
1024
|
} catch (error) {
|
|
996
1025
|
if (error.message?.includes("token has expired")) {
|
|
997
1026
|
const newAuthToken = await this.authenticate(address);
|
|
998
|
-
this.clients.get(address)
|
|
1027
|
+
const clientData = this.clients.get(address);
|
|
1028
|
+
if (!clientData) {
|
|
1029
|
+
throw new Error(`No client found for address: ${address}`);
|
|
1030
|
+
}
|
|
1031
|
+
clientData.authToken = newAuthToken;
|
|
999
1032
|
return yield* call.next(call.request, {
|
|
1000
1033
|
...options,
|
|
1001
|
-
metadata:
|
|
1034
|
+
metadata: metadata.set("Authorization", `Bearer ${newAuthToken}`)
|
|
1002
1035
|
});
|
|
1003
1036
|
}
|
|
1004
1037
|
throw error;
|
|
@@ -1007,21 +1040,26 @@ var ConnectionManager = class {
|
|
|
1007
1040
|
}
|
|
1008
1041
|
createBrowserMiddleware(address, initialAuthToken) {
|
|
1009
1042
|
return async function* (call, options) {
|
|
1043
|
+
const metadata = Metadata(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("X-Client-Env", clientEnv).set("Content-Type", "application/grpc-web+proto");
|
|
1010
1044
|
try {
|
|
1011
1045
|
return yield* call.next(call.request, {
|
|
1012
1046
|
...options,
|
|
1013
|
-
metadata:
|
|
1047
|
+
metadata: metadata.set(
|
|
1014
1048
|
"Authorization",
|
|
1015
1049
|
`Bearer ${this.clients.get(address)?.authToken || initialAuthToken}`
|
|
1016
|
-
)
|
|
1050
|
+
)
|
|
1017
1051
|
});
|
|
1018
1052
|
} catch (error) {
|
|
1019
1053
|
if (error.message?.includes("token has expired")) {
|
|
1020
1054
|
const newAuthToken = await this.authenticate(address);
|
|
1021
|
-
this.clients.get(address)
|
|
1055
|
+
const clientData = this.clients.get(address);
|
|
1056
|
+
if (!clientData) {
|
|
1057
|
+
throw new Error(`No client found for address: ${address}`);
|
|
1058
|
+
}
|
|
1059
|
+
clientData.authToken = newAuthToken;
|
|
1022
1060
|
return yield* call.next(call.request, {
|
|
1023
1061
|
...options,
|
|
1024
|
-
metadata:
|
|
1062
|
+
metadata: metadata.set("Authorization", `Bearer ${newAuthToken}`)
|
|
1025
1063
|
});
|
|
1026
1064
|
}
|
|
1027
1065
|
throw error;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
encodeSparkAddress
|
|
3
|
+
} from "./chunk-O4RYNJNB.js";
|
|
1
4
|
import {
|
|
2
5
|
getNetwork,
|
|
3
6
|
getNetworkFromAddress
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-Z5HIAYFT.js";
|
|
5
8
|
import {
|
|
6
9
|
ELECTRS_CREDENTIALS,
|
|
7
10
|
getElectrsUrl
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DOA6QXYQ.js";
|
|
9
12
|
import {
|
|
10
13
|
BitcoinNetwork_default
|
|
11
14
|
} from "./chunk-HMLOC6TE.js";
|
|
12
|
-
import {
|
|
13
|
-
encodeSparkAddress
|
|
14
|
-
} from "./chunk-TM4TOEOX.js";
|
|
15
|
-
import {
|
|
16
|
-
ValidationError
|
|
17
|
-
} from "./chunk-TWF35O6M.js";
|
|
18
15
|
import {
|
|
19
16
|
TreeNode
|
|
20
17
|
} from "./chunk-M6A4KFIG.js";
|
|
18
|
+
import {
|
|
19
|
+
ValidationError
|
|
20
|
+
} from "./chunk-GSI4OLXZ.js";
|
|
21
21
|
import {
|
|
22
22
|
Buffer
|
|
23
23
|
} from "./chunk-MVRQ5US7.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ValidationError
|
|
3
|
-
} from "./chunk-TWF35O6M.js";
|
|
4
1
|
import {
|
|
5
2
|
SparkAddress
|
|
6
3
|
} from "./chunk-M6A4KFIG.js";
|
|
4
|
+
import {
|
|
5
|
+
ValidationError
|
|
6
|
+
} from "./chunk-GSI4OLXZ.js";
|
|
7
7
|
|
|
8
8
|
// src/address/address.ts
|
|
9
9
|
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isReactNative
|
|
3
|
+
} from "./chunk-VFJQNBFX.js";
|
|
1
4
|
import {
|
|
2
5
|
generateAdaptorFromSignature,
|
|
3
6
|
getRandomSigningNonce,
|
|
4
7
|
getSigningCommitmentFromNonce,
|
|
5
8
|
subtractPrivateKeys
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
isReactNative
|
|
9
|
-
} from "./chunk-HKAKEKCE.js";
|
|
9
|
+
} from "./chunk-NSJF5F5O.js";
|
|
10
10
|
import {
|
|
11
11
|
splitSecretWithProofs
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QNNSEJ4P.js";
|
|
13
13
|
import {
|
|
14
14
|
ConfigurationError,
|
|
15
15
|
ValidationError
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GSI4OLXZ.js";
|
|
17
17
|
import {
|
|
18
18
|
Buffer
|
|
19
19
|
} from "./chunk-MVRQ5US7.js";
|
|
@@ -38,6 +38,8 @@ import {
|
|
|
38
38
|
} from "@buildonspark/lrc20-sdk";
|
|
39
39
|
import { sha256 } from "@noble/hashes/sha2";
|
|
40
40
|
import { taprootTweakPrivKey } from "@scure/btc-signer/utils";
|
|
41
|
+
import { Receipt as Receipt2, PARITY as PARITY2, fromPrivateKey as fromPrivateKey2 } from "@buildonspark/lrc20-sdk";
|
|
42
|
+
import { MultisigReceiptInput } from "@buildonspark/lrc20-sdk/lrc/types";
|
|
41
43
|
var sparkFrostModule = void 0;
|
|
42
44
|
var getSparkFrostModule = async () => {
|
|
43
45
|
if (isReactNative) {
|
|
@@ -612,5 +614,9 @@ var TaprootSparkSigner = class extends DefaultSparkSigner {
|
|
|
612
614
|
export {
|
|
613
615
|
TaprootOutputKeysGenerator,
|
|
614
616
|
DefaultSparkSigner,
|
|
615
|
-
TaprootSparkSigner
|
|
617
|
+
TaprootSparkSigner,
|
|
618
|
+
Receipt2 as Receipt,
|
|
619
|
+
PARITY2 as PARITY,
|
|
620
|
+
fromPrivateKey2 as fromPrivateKey,
|
|
621
|
+
MultisigReceiptInput
|
|
616
622
|
};
|