@buildonspark/spark-sdk 0.1.45 → 0.1.47
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 +22 -0
- package/dist/{chunk-I54FARY2.js → chunk-EAP3U3CW.js} +14 -14
- package/dist/chunk-GWFQ7EBA.js +3773 -0
- package/dist/{chunk-J2IE4Z7Y.js → chunk-NNX4OK44.js} +3487 -934
- package/dist/{RequestLightningSendInput-Du0z7Om7.d.cts → client-CvpTRpcw.d.cts} +422 -212
- package/dist/{RequestLightningSendInput-DEPd_fPO.d.ts → client-D7KgLN44.d.ts} +422 -212
- package/dist/graphql/objects/index.d.cts +5 -9
- package/dist/graphql/objects/index.d.ts +5 -9
- package/dist/graphql/objects/index.js +1 -1
- package/dist/index.cjs +20461 -23377
- package/dist/index.d.cts +15 -769
- package/dist/index.d.ts +15 -769
- package/dist/index.js +81 -71
- package/dist/index.node.cjs +21994 -25018
- package/dist/index.node.d.cts +312 -34
- package/dist/index.node.d.ts +312 -34
- package/dist/index.node.js +82 -176
- package/dist/native/index.cjs +22847 -25841
- package/dist/native/index.d.cts +974 -1138
- package/dist/native/index.d.ts +974 -1138
- package/dist/native/index.js +10604 -13592
- package/dist/proto/lrc20.d.cts +2 -2
- package/dist/proto/lrc20.d.ts +2 -2
- package/dist/proto/lrc20.js +3098 -46
- 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-Cc4l4kb1.d.ts → sdk-types-BGCeea0G.d.ts} +1 -1
- package/dist/{sdk-types-B0SwjolI.d.cts → sdk-types-XUeQMLFP.d.cts} +1 -1
- package/dist/{spark-dM7EYXYQ.d.cts → spark-BbUrbvZz.d.cts} +1 -1
- package/dist/{spark-dM7EYXYQ.d.ts → spark-BbUrbvZz.d.ts} +1 -1
- package/dist/spark-wallet-BAFPpPtY.d.cts +923 -0
- package/dist/spark-wallet-CJkQW8pK.d.ts +923 -0
- package/dist/spark_bindings/native/index.d.cts +1 -1
- package/dist/spark_bindings/native/index.d.ts +1 -1
- package/dist/spark_bindings/wasm/index.d.cts +1 -1
- package/dist/spark_bindings/wasm/index.d.ts +1 -1
- package/dist/{services/index.cjs → tests/test-utils.cjs} +2512 -4380
- package/dist/tests/test-utils.d.cts +79 -0
- package/dist/tests/test-utils.d.ts +79 -0
- package/dist/tests/test-utils.js +85 -0
- package/dist/types/index.d.cts +5 -9
- package/dist/types/index.d.ts +5 -9
- package/dist/types/index.js +5 -5
- package/dist/{types-C-Rp0Oo7.d.cts → types-BADxR3bm.d.cts} +1 -1
- package/dist/{types-C-Rp0Oo7.d.ts → types-BADxR3bm.d.ts} +1 -1
- package/package.json +7 -35
- package/src/graphql/client.ts +59 -20
- package/src/index.node.ts +28 -2
- package/src/index.ts +31 -1
- package/src/native/index.ts +16 -2
- package/src/services/config.ts +4 -6
- package/src/services/connection.ts +131 -64
- package/src/services/lightning.ts +1 -2
- package/src/services/token-transactions.ts +7 -7
- package/src/services/transfer.ts +1 -1
- package/src/services/tree-creation.ts +1 -1
- package/src/services/wallet-config.ts +18 -10
- package/src/signer/signer.react-native.ts +2 -5
- package/src/signer/signer.ts +138 -64
- package/src/signer/types.ts +52 -0
- package/src/spark-wallet/spark-wallet.ts +79 -36
- package/src/spark-wallet/types.ts +4 -4
- package/src/tests/integration/coop-exit.test.ts +2 -1
- package/src/tests/integration/lightning.test.ts +2 -2
- package/src/tests/integration/swap.test.ts +1 -1
- package/src/tests/integration/transfer.test.ts +5 -5
- package/src/tests/integration/tree-creation.test.ts +1 -1
- package/src/tests/integration/wallet.test.ts +1 -0
- package/src/tests/isHermeticTest.ts +3 -24
- package/src/tests/{test-util.ts → test-utils.ts} +3 -7
- package/src/tests/wrapWithOtelSpan.test.ts +1 -1
- package/src/{address → utils}/address.ts +1 -1
- package/src/utils/crypto.ts +19 -9
- package/src/utils/index.ts +2 -0
- package/src/utils/network.ts +17 -0
- package/src/utils/secret-sharing.ts +1 -2
- package/src/utils/signing.ts +1 -1
- package/src/utils/token-transactions.ts +3 -3
- package/src/utils/unilateral-exit.ts +32 -0
- package/src/utils/xchain-address.ts +1 -1
- package/dist/BitcoinNetwork-TnABML0T.d.cts +0 -18
- package/dist/BitcoinNetwork-TnABML0T.d.ts +0 -18
- package/dist/LightningSendFeeEstimateInput-BgOhEAI-.d.cts +0 -10
- package/dist/LightningSendFeeEstimateInput-BgOhEAI-.d.ts +0 -10
- package/dist/address/index.cjs +0 -458
- package/dist/address/index.d.cts +0 -32
- package/dist/address/index.d.ts +0 -32
- package/dist/address/index.js +0 -17
- package/dist/chunk-5FUB65LX.js +0 -838
- package/dist/chunk-6264CGDM.js +0 -113
- package/dist/chunk-7V6N75CC.js +0 -24
- package/dist/chunk-C2S227QR.js +0 -2336
- package/dist/chunk-GSI4OLXZ.js +0 -117
- package/dist/chunk-GZ5IPPJ2.js +0 -170
- package/dist/chunk-HWJWKEIU.js +0 -75
- package/dist/chunk-KMUMFYFX.js +0 -137
- package/dist/chunk-L3EHBOUX.js +0 -0
- package/dist/chunk-NSJF5F5O.js +0 -325
- package/dist/chunk-NTFKFRQ2.js +0 -3146
- package/dist/chunk-PQN3C2MF.js +0 -1122
- package/dist/chunk-QNNSEJ4P.js +0 -232
- package/dist/chunk-R5PXJZQS.js +0 -277
- package/dist/chunk-VTUGIIWI.js +0 -0
- package/dist/chunk-YUPMXTCJ.js +0 -622
- package/dist/chunk-Z5HIAYFT.js +0 -84
- package/dist/index-B2AwKW5J.d.cts +0 -214
- package/dist/index-CJDi1HWc.d.ts +0 -214
- package/dist/network-BTJl-Sul.d.ts +0 -46
- package/dist/network-CqgsdUF2.d.cts +0 -46
- package/dist/services/config.cjs +0 -2354
- package/dist/services/config.d.cts +0 -42
- package/dist/services/config.d.ts +0 -42
- package/dist/services/config.js +0 -17
- package/dist/services/connection.cjs +0 -17691
- package/dist/services/connection.d.cts +0 -95
- package/dist/services/connection.d.ts +0 -95
- package/dist/services/connection.js +0 -11
- package/dist/services/index.d.cts +0 -21
- package/dist/services/index.d.ts +0 -21
- package/dist/services/index.js +0 -58
- package/dist/services/lrc-connection.cjs +0 -4713
- package/dist/services/lrc-connection.d.cts +0 -34
- package/dist/services/lrc-connection.d.ts +0 -34
- package/dist/services/lrc-connection.js +0 -11
- package/dist/services/token-transactions.cjs +0 -2877
- package/dist/services/token-transactions.d.cts +0 -75
- package/dist/services/token-transactions.d.ts +0 -75
- package/dist/services/token-transactions.js +0 -15
- package/dist/services/wallet-config.cjs +0 -340
- package/dist/services/wallet-config.d.cts +0 -56
- package/dist/services/wallet-config.d.ts +0 -56
- package/dist/services/wallet-config.js +0 -33
- package/dist/signer/signer.cjs +0 -2004
- package/dist/signer/signer.d.cts +0 -10
- package/dist/signer/signer.d.ts +0 -10
- package/dist/signer/signer.js +0 -24
- package/dist/signer-BocS_J6B.d.ts +0 -187
- package/dist/signer-DKS0AJkw.d.cts +0 -187
- package/dist/utils/index.cjs +0 -2947
- package/dist/utils/index.d.cts +0 -18
- package/dist/utils/index.d.ts +0 -18
- package/dist/utils/index.js +0 -157
- package/src/address/index.ts +0 -1
- package/src/services/lrc-connection.ts +0 -215
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { HDKey } from "@scure/bip32";
|
|
2
|
+
import type {
|
|
3
|
+
IKeyPackage,
|
|
4
|
+
ISigningCommitment,
|
|
5
|
+
} from "../spark_bindings/types.js";
|
|
6
|
+
|
|
7
|
+
export { MultisigReceiptInput } from "@buildonspark/lrc20-sdk/lrc/types";
|
|
8
|
+
|
|
9
|
+
export type SigningNonce = {
|
|
10
|
+
binding: Uint8Array;
|
|
11
|
+
hiding: Uint8Array;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type SigningCommitment = {
|
|
15
|
+
binding: Uint8Array;
|
|
16
|
+
hiding: Uint8Array;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type SignFrostParams = {
|
|
20
|
+
message: Uint8Array;
|
|
21
|
+
privateAsPubKey: Uint8Array;
|
|
22
|
+
publicKey: Uint8Array;
|
|
23
|
+
verifyingKey: Uint8Array;
|
|
24
|
+
selfCommitment: ISigningCommitment;
|
|
25
|
+
statechainCommitments?: { [key: string]: ISigningCommitment } | undefined;
|
|
26
|
+
adaptorPubKey?: Uint8Array | undefined;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type AggregateFrostParams = Omit<SignFrostParams, "privateAsPubKey"> & {
|
|
30
|
+
selfSignature: Uint8Array;
|
|
31
|
+
statechainSignatures?: { [key: string]: Uint8Array } | undefined;
|
|
32
|
+
statechainPublicKeys?: { [key: string]: Uint8Array } | undefined;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type SplitSecretWithProofsParams = {
|
|
36
|
+
secret: Uint8Array;
|
|
37
|
+
curveOrder: bigint;
|
|
38
|
+
threshold: number;
|
|
39
|
+
numShares: number;
|
|
40
|
+
isSecretPubkey?: boolean;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type DerivedHDKey = {
|
|
44
|
+
hdKey: HDKey;
|
|
45
|
+
privateKey: Uint8Array;
|
|
46
|
+
publicKey: Uint8Array;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type KeyPair = {
|
|
50
|
+
privateKey: Uint8Array;
|
|
51
|
+
publicKey: Uint8Array;
|
|
52
|
+
};
|
|
@@ -54,7 +54,6 @@ import { ConnectionManager } from "../services/connection.js";
|
|
|
54
54
|
import { CoopExitService } from "../services/coop-exit.js";
|
|
55
55
|
import { DepositService } from "../services/deposit.js";
|
|
56
56
|
import { LightningService } from "../services/lightning.js";
|
|
57
|
-
import { Lrc20ConnectionManager } from "../services/lrc-connection.js";
|
|
58
57
|
import { TokenTransactionService } from "../services/token-transactions.js";
|
|
59
58
|
import type { LeafKeyTweak } from "../services/transfer.js";
|
|
60
59
|
import { TransferService } from "../services/transfer.js";
|
|
@@ -88,7 +87,7 @@ import {
|
|
|
88
87
|
NetworkToProto,
|
|
89
88
|
NetworkType,
|
|
90
89
|
} from "../utils/network.js";
|
|
91
|
-
import {
|
|
90
|
+
import { sumAvailableTokens } from "../utils/token-transactions.js";
|
|
92
91
|
import { getNextTransactionSequence } from "../utils/transaction.js";
|
|
93
92
|
|
|
94
93
|
import { LRCWallet } from "@buildonspark/lrc20-sdk";
|
|
@@ -99,7 +98,7 @@ import {
|
|
|
99
98
|
encodeSparkAddress,
|
|
100
99
|
isValidPublicKey,
|
|
101
100
|
SparkAddressFormat,
|
|
102
|
-
} from "../address
|
|
101
|
+
} from "../utils/address.js";
|
|
103
102
|
import { isReactNative } from "../constants.js";
|
|
104
103
|
import { Network as NetworkProto, networkToJSON } from "../proto/spark.js";
|
|
105
104
|
import {
|
|
@@ -124,12 +123,15 @@ import type {
|
|
|
124
123
|
InitWalletResponse,
|
|
125
124
|
PayLightningInvoiceParams,
|
|
126
125
|
SparkWalletProps,
|
|
127
|
-
|
|
126
|
+
UserTokenMetadata,
|
|
128
127
|
TransferParams,
|
|
129
128
|
TokenBalanceMap,
|
|
130
129
|
} from "./types.js";
|
|
131
130
|
import { encodeHumanReadableTokenIdentifier } from "../utils/token-identifier.js";
|
|
132
|
-
import {
|
|
131
|
+
import {
|
|
132
|
+
TokenTransactionWithStatus,
|
|
133
|
+
TokenMetadata,
|
|
134
|
+
} from "../proto/spark_token.js";
|
|
133
135
|
|
|
134
136
|
/**
|
|
135
137
|
* The SparkWallet class is the primary interface for interacting with the Spark network.
|
|
@@ -140,7 +142,6 @@ export class SparkWallet extends EventEmitter {
|
|
|
140
142
|
protected config: WalletConfigService;
|
|
141
143
|
|
|
142
144
|
protected connectionManager: ConnectionManager;
|
|
143
|
-
protected lrc20ConnectionManager: Lrc20ConnectionManager;
|
|
144
145
|
protected lrc20Wallet: LRCWallet | undefined;
|
|
145
146
|
protected transferService: TransferService;
|
|
146
147
|
protected tracerId = "spark-sdk";
|
|
@@ -169,6 +170,7 @@ export class SparkWallet extends EventEmitter {
|
|
|
169
170
|
|
|
170
171
|
protected tokenOutputs: Map<string, OutputWithPreviousTransactionData[]> =
|
|
171
172
|
new Map();
|
|
173
|
+
protected tokenMetadata: Map<string, TokenMetadata> = new Map();
|
|
172
174
|
|
|
173
175
|
// Add this property near the top of the class with other private properties
|
|
174
176
|
private claimTransfersInterval: NodeJS.Timeout | null = null;
|
|
@@ -188,7 +190,6 @@ export class SparkWallet extends EventEmitter {
|
|
|
188
190
|
this.config = new WalletConfigService(options, signer);
|
|
189
191
|
this.connectionManager = new ConnectionManager(this.config);
|
|
190
192
|
this.signingService = new SigningService(this.config);
|
|
191
|
-
this.lrc20ConnectionManager = new Lrc20ConnectionManager(this.config);
|
|
192
193
|
this.depositService = new DepositService(
|
|
193
194
|
this.config,
|
|
194
195
|
this.connectionManager,
|
|
@@ -1214,34 +1215,70 @@ export class SparkWallet extends EventEmitter {
|
|
|
1214
1215
|
};
|
|
1215
1216
|
}
|
|
1216
1217
|
|
|
1218
|
+
private async getTokenMetadata(): Promise<Map<string, UserTokenMetadata>> {
|
|
1219
|
+
let metadataToFetch = new Array<string>();
|
|
1220
|
+
for (const issuerPublicKey of this.tokenOutputs.keys()) {
|
|
1221
|
+
if (!this.tokenMetadata.has(issuerPublicKey)) {
|
|
1222
|
+
metadataToFetch.push(issuerPublicKey);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
if (metadataToFetch.length > 0) {
|
|
1227
|
+
const sparkTokenClient =
|
|
1228
|
+
await this.connectionManager.createSparkTokenClient(
|
|
1229
|
+
this.config.getCoordinatorAddress(),
|
|
1230
|
+
);
|
|
1231
|
+
|
|
1232
|
+
try {
|
|
1233
|
+
const response = await sparkTokenClient.query_token_metadata({
|
|
1234
|
+
issuerPublicKeys: metadataToFetch.map(hexToBytes),
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
for (const metadata of response.tokenMetadata) {
|
|
1238
|
+
this.tokenMetadata.set(
|
|
1239
|
+
bytesToHex(metadata.issuerPublicKey),
|
|
1240
|
+
metadata,
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
} catch (error) {
|
|
1244
|
+
throw new NetworkError("Failed to fetch token metadata", {
|
|
1245
|
+
errorCount: 1,
|
|
1246
|
+
errors: error instanceof Error ? error.message : String(error),
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
let tokenMetadataMap = new Map<string, UserTokenMetadata>();
|
|
1252
|
+
|
|
1253
|
+
for (const [issuerPublicKey, metadata] of this.tokenMetadata) {
|
|
1254
|
+
tokenMetadataMap.set(issuerPublicKey, {
|
|
1255
|
+
tokenPublicKey: bytesToHex(metadata.issuerPublicKey),
|
|
1256
|
+
rawTokenIdentifier: metadata.tokenIdentifier,
|
|
1257
|
+
tokenName: metadata.tokenName,
|
|
1258
|
+
tokenTicker: metadata.tokenTicker,
|
|
1259
|
+
decimals: metadata.decimals,
|
|
1260
|
+
maxSupply: bytesToNumberBE(metadata.maxSupply),
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
return tokenMetadataMap;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1217
1267
|
private async getTokenBalance(): Promise<TokenBalanceMap> {
|
|
1218
|
-
const
|
|
1219
|
-
await this.connectionManager.createSparkTokenClient(
|
|
1220
|
-
this.config.getCoordinatorAddress(),
|
|
1221
|
-
);
|
|
1268
|
+
const tokenMetadataMap = await this.getTokenMetadata();
|
|
1222
1269
|
|
|
1223
|
-
const tokenMetadata = await sparkTokenClient.query_token_metadata({
|
|
1224
|
-
issuerPublicKeys: Array.from(this.tokenOutputs.keys()).map(hexToBytes),
|
|
1225
|
-
});
|
|
1226
1270
|
const result: TokenBalanceMap = new Map();
|
|
1271
|
+
for (const [issuerPublicKey, tokenMetadata] of tokenMetadataMap) {
|
|
1272
|
+
const outputs = this.tokenOutputs.get(issuerPublicKey);
|
|
1227
1273
|
|
|
1228
|
-
for (const metadata of tokenMetadata.tokenMetadata) {
|
|
1229
|
-
const tokenPublicKey = bytesToHex(metadata.issuerPublicKey);
|
|
1230
|
-
const leaves = this.tokenOutputs.get(tokenPublicKey);
|
|
1231
1274
|
const humanReadableTokenIdentifier = encodeHumanReadableTokenIdentifier({
|
|
1232
|
-
tokenIdentifier:
|
|
1275
|
+
tokenIdentifier: tokenMetadata.rawTokenIdentifier,
|
|
1233
1276
|
network: this.config.getNetworkType(),
|
|
1234
1277
|
});
|
|
1278
|
+
|
|
1235
1279
|
result.set(humanReadableTokenIdentifier, {
|
|
1236
|
-
balance:
|
|
1237
|
-
tokenMetadata:
|
|
1238
|
-
tokenPublicKey,
|
|
1239
|
-
rawTokenIdentifier: metadata.tokenIdentifier,
|
|
1240
|
-
tokenName: metadata.tokenName,
|
|
1241
|
-
tokenTicker: metadata.tokenTicker,
|
|
1242
|
-
decimals: metadata.decimals,
|
|
1243
|
-
maxSupply: bytesToNumberBE(metadata.maxSupply),
|
|
1244
|
-
},
|
|
1280
|
+
balance: outputs ? sumAvailableTokens(outputs) : BigInt(0),
|
|
1281
|
+
tokenMetadata: tokenMetadata,
|
|
1245
1282
|
});
|
|
1246
1283
|
}
|
|
1247
1284
|
|
|
@@ -3303,7 +3340,7 @@ export class SparkWallet extends EventEmitter {
|
|
|
3303
3340
|
}
|
|
3304
3341
|
|
|
3305
3342
|
/**
|
|
3306
|
-
* Retrieves token transaction history for specified tokens
|
|
3343
|
+
* Retrieves token transaction history for specified tokens
|
|
3307
3344
|
* Can optionally filter by specific transaction hashes.
|
|
3308
3345
|
*
|
|
3309
3346
|
* @param ownerPublicKeys - Optional array of owner public keys to query transactions for
|
|
@@ -3313,13 +3350,20 @@ export class SparkWallet extends EventEmitter {
|
|
|
3313
3350
|
* @param outputIds - Optional array of output IDs to filter by
|
|
3314
3351
|
* @returns Promise resolving to array of token transactions with their current status
|
|
3315
3352
|
*/
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3353
|
+
|
|
3354
|
+
public async queryTokenTransactions({
|
|
3355
|
+
ownerPublicKeys,
|
|
3356
|
+
issuerPublicKeys,
|
|
3357
|
+
tokenTransactionHashes,
|
|
3358
|
+
tokenIdentifiers,
|
|
3359
|
+
outputIds,
|
|
3360
|
+
}: {
|
|
3361
|
+
ownerPublicKeys?: string[];
|
|
3362
|
+
issuerPublicKeys?: string[];
|
|
3363
|
+
tokenTransactionHashes?: string[];
|
|
3364
|
+
tokenIdentifiers?: string[];
|
|
3365
|
+
outputIds?: string[];
|
|
3366
|
+
}): Promise<TokenTransactionWithStatus[]> {
|
|
3323
3367
|
return this.tokenTransactionService.queryTokenTransactions({
|
|
3324
3368
|
ownerPublicKeys,
|
|
3325
3369
|
issuerPublicKeys,
|
|
@@ -3849,7 +3893,6 @@ export class SparkWallet extends EventEmitter {
|
|
|
3849
3893
|
public async cleanupConnections() {
|
|
3850
3894
|
this.cleanup();
|
|
3851
3895
|
await this.connectionManager.closeConnections();
|
|
3852
|
-
await this.lrc20ConnectionManager.closeConnection();
|
|
3853
3896
|
}
|
|
3854
3897
|
|
|
3855
3898
|
// Add this new method to start periodic claiming
|
|
@@ -41,7 +41,7 @@ export type DepositParams = {
|
|
|
41
41
|
*
|
|
42
42
|
* @example
|
|
43
43
|
* ```typescript
|
|
44
|
-
* const tokenMetadata:
|
|
44
|
+
* const tokenMetadata: UserTokenMetadata = {
|
|
45
45
|
* rawTokenIdentifier: new Uint8Array([1, 2, 3]),
|
|
46
46
|
* tokenPublicKey: "0348fbb...",
|
|
47
47
|
* tokenName: "SparkToken",
|
|
@@ -51,10 +51,10 @@ export type DepositParams = {
|
|
|
51
51
|
* };
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
|
-
export type
|
|
54
|
+
export type UserTokenMetadata = {
|
|
55
55
|
/** Raw binary token identifier - This is used to encode the human readable token identifier */
|
|
56
56
|
rawTokenIdentifier: Uint8Array;
|
|
57
|
-
/**
|
|
57
|
+
/** Public key of the token issuer - Same as issuerPublicKey */
|
|
58
58
|
tokenPublicKey: string;
|
|
59
59
|
/** Human-readable name of the token (e.g., SparkToken)*/
|
|
60
60
|
tokenName: string;
|
|
@@ -70,7 +70,7 @@ export type TokenBalanceMap = Map<
|
|
|
70
70
|
HumanReadableTokenIdentifier,
|
|
71
71
|
{
|
|
72
72
|
balance: bigint;
|
|
73
|
-
tokenMetadata:
|
|
73
|
+
tokenMetadata: UserTokenMetadata;
|
|
74
74
|
}
|
|
75
75
|
>;
|
|
76
76
|
|
|
@@ -19,9 +19,10 @@ import {
|
|
|
19
19
|
getTxIdNoReverse,
|
|
20
20
|
} from "../../utils/bitcoin.js";
|
|
21
21
|
import { getNetwork, Network } from "../../utils/network.js";
|
|
22
|
-
import { createNewTree } from "../test-
|
|
22
|
+
import { createNewTree } from "../test-utils.js";
|
|
23
23
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
24
24
|
import { BitcoinFaucet } from "../utils/test-faucet.js";
|
|
25
|
+
|
|
25
26
|
describe("coop exit", () => {
|
|
26
27
|
const brokenTestFn = process.env.GITHUB_ACTIONS ? it.skip : it;
|
|
27
28
|
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
CurrencyUnit,
|
|
16
16
|
LightningReceiveRequestStatus,
|
|
17
17
|
} from "../../types/index.js";
|
|
18
|
-
import { createNewTree, getTestWalletConfig } from "../test-
|
|
18
|
+
import { createNewTree, getTestWalletConfig } from "../test-utils.js";
|
|
19
19
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
20
20
|
import { BitcoinFaucet } from "../utils/test-faucet.js";
|
|
21
21
|
|
|
@@ -476,7 +476,7 @@ describe("LightningService", () => {
|
|
|
476
476
|
);
|
|
477
477
|
|
|
478
478
|
expect(transfer.status).toEqual(
|
|
479
|
-
TransferStatus.
|
|
479
|
+
TransferStatus.TRANSFER_STATUS_SENDER_KEY_TWEAK_PENDING,
|
|
480
480
|
);
|
|
481
481
|
|
|
482
482
|
const refunds =
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
computeTaprootKeyNoScript,
|
|
17
17
|
getSigHashFromTx,
|
|
18
18
|
} from "../../utils/bitcoin.js";
|
|
19
|
-
import { createNewTree } from "../test-
|
|
19
|
+
import { createNewTree } from "../test-utils.js";
|
|
20
20
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
21
21
|
import { BitcoinFaucet } from "../utils/test-faucet.js";
|
|
22
22
|
|
|
@@ -16,9 +16,9 @@ import { TransferService } from "../../services/transfer.js";
|
|
|
16
16
|
import {
|
|
17
17
|
ConfigOptions,
|
|
18
18
|
getLocalSigningOperators,
|
|
19
|
-
|
|
19
|
+
WalletConfig,
|
|
20
20
|
} from "../../services/wallet-config.js";
|
|
21
|
-
import { createNewTree } from "
|
|
21
|
+
import { createNewTree } from "../test-utils.js";
|
|
22
22
|
import { NetworkType } from "../../utils/network.js";
|
|
23
23
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
24
24
|
import { BitcoinFaucet } from "../utils/test-faucet.js";
|
|
@@ -423,7 +423,7 @@ describe("Transfer", () => {
|
|
|
423
423
|
),
|
|
424
424
|
);
|
|
425
425
|
const missingOperatorOptions = {
|
|
426
|
-
...
|
|
426
|
+
...WalletConfig.LOCAL,
|
|
427
427
|
signingOperators,
|
|
428
428
|
};
|
|
429
429
|
const mnemonic = generateMnemonic(wordlist);
|
|
@@ -493,7 +493,7 @@ describe("Transfer", () => {
|
|
|
493
493
|
]);
|
|
494
494
|
|
|
495
495
|
const receiverOptions = {
|
|
496
|
-
...
|
|
496
|
+
...WalletConfig.LOCAL,
|
|
497
497
|
};
|
|
498
498
|
|
|
499
499
|
const { wallet: receiverWalletWithAllOperators } =
|
|
@@ -521,7 +521,7 @@ describe("Transfer", () => {
|
|
|
521
521
|
const { wallet: receiverWalletWithMissingOperatorAsCoordinator } =
|
|
522
522
|
await SparkWalletTesting.initialize({
|
|
523
523
|
options: {
|
|
524
|
-
...
|
|
524
|
+
...WalletConfig.LOCAL,
|
|
525
525
|
coodinatorIdentifier: soToRemove,
|
|
526
526
|
},
|
|
527
527
|
mnemonicOrSeed: mnemonic,
|
|
@@ -6,7 +6,7 @@ import { ValidationError } from "../../errors/types.js";
|
|
|
6
6
|
import { getTxFromRawTxBytes, getTxId } from "../../utils/bitcoin.js";
|
|
7
7
|
import { Network } from "../../utils/network.js";
|
|
8
8
|
import { DEFAULT_FEE_SATS } from "../../utils/transaction.js";
|
|
9
|
-
import { createNewTreeWithLevels } from "../test-
|
|
9
|
+
import { createNewTreeWithLevels } from "../test-utils.js";
|
|
10
10
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
11
11
|
import { BitcoinFaucet } from "../utils/test-faucet.js";
|
|
12
12
|
|
|
@@ -2,6 +2,7 @@ import { describe, expect, it } from "@jest/globals";
|
|
|
2
2
|
import { ConfigOptions } from "../../services/wallet-config.js";
|
|
3
3
|
import { NetworkType } from "../../utils/network.js";
|
|
4
4
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
5
|
+
|
|
5
6
|
describe("wallet", () => {
|
|
6
7
|
it("should initialize a wallet", async () => {
|
|
7
8
|
const seedOrMnemonics = [
|
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Checks if the current environment is a hermetic test environment.
|
|
6
|
-
* A hermetic test environment is identified by either:
|
|
7
|
-
* 1. The existence of a marker file at /tmp/spark_hermetic (Node.js only)
|
|
8
|
-
* 2. The HERMETIC_TEST environment variable being set to "true"
|
|
9
|
-
*
|
|
10
|
-
* @returns {boolean} True if running in a hermetic test environment, false otherwise
|
|
11
|
-
*/
|
|
12
|
-
export function isHermeticTest() {
|
|
13
|
-
if (isNode) {
|
|
14
|
-
return (
|
|
15
|
-
(fs?.existsSync?.("/tmp/spark_hermetic") ?? false) ||
|
|
16
|
-
process.env.HERMETIC_TEST === "true"
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
(typeof process !== "undefined" && process.env?.HERMETIC_TEST === "true") ||
|
|
22
|
-
false
|
|
23
|
-
);
|
|
24
|
-
}
|
|
1
|
+
export const isHermeticTest = Boolean(
|
|
2
|
+
typeof process !== "undefined" && process?.env?.HERMETIC_TEST === "true",
|
|
3
|
+
);
|
|
@@ -6,17 +6,13 @@ import { TreeNode } from "../proto/spark.js";
|
|
|
6
6
|
import { WalletConfigService } from "../services/config.js";
|
|
7
7
|
import { ConnectionManager } from "../services/connection.js";
|
|
8
8
|
import { DepositService } from "../services/deposit.js";
|
|
9
|
-
import {
|
|
10
|
-
ConfigOptions,
|
|
11
|
-
LOCAL_WALLET_CONFIG,
|
|
12
|
-
} from "../services/wallet-config.js";
|
|
9
|
+
import { ConfigOptions, WalletConfig } from "../services/wallet-config.js";
|
|
13
10
|
import { getP2TRAddressFromPublicKey } from "../utils/bitcoin.js";
|
|
14
|
-
import { getCrypto } from "../utils/crypto.js";
|
|
15
11
|
import { getNetwork, Network } from "../utils/network.js";
|
|
16
12
|
import { SparkWalletTesting } from "./utils/spark-testing-wallet.js";
|
|
17
13
|
import { BitcoinFaucet } from "./utils/test-faucet.js";
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
export { BitcoinFaucet };
|
|
20
16
|
|
|
21
17
|
export function getTestWalletConfig() {
|
|
22
18
|
const identityPrivateKey = secp256k1.utils.randomPrivateKey();
|
|
@@ -27,7 +23,7 @@ export function getTestWalletConfigWithIdentityKey(
|
|
|
27
23
|
identityPrivateKey: Uint8Array,
|
|
28
24
|
) {
|
|
29
25
|
return {
|
|
30
|
-
...
|
|
26
|
+
...WalletConfig.LOCAL,
|
|
31
27
|
identityPrivateKey,
|
|
32
28
|
} as ConfigOptions;
|
|
33
29
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from "@jest/globals";
|
|
2
2
|
import { SparkWalletTesting } from "./utils/spark-testing-wallet.js";
|
|
3
|
-
import { getTestWalletConfig } from "./test-
|
|
3
|
+
import { getTestWalletConfig } from "./test-utils.js";
|
|
4
4
|
import { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
|
|
5
5
|
import { trace } from "@opentelemetry/api";
|
|
6
6
|
|
|
@@ -2,7 +2,7 @@ import { secp256k1 } from "@noble/curves/secp256k1";
|
|
|
2
2
|
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
|
3
3
|
import { bech32m } from "@scure/base";
|
|
4
4
|
import { PaymentIntentFields, SparkAddress } from "../proto/spark.js";
|
|
5
|
-
import { NetworkType } from "
|
|
5
|
+
import { NetworkType } from "./network.js";
|
|
6
6
|
import { ValidationError } from "../errors/index.js";
|
|
7
7
|
|
|
8
8
|
import { UUID, uuidv7 } from "uuidv7";
|
package/src/utils/crypto.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
export interface SparkCrypto {
|
|
2
|
+
// Browser
|
|
3
|
+
getRandomValues<T extends ArrayBufferView | null>(array: T): T;
|
|
4
|
+
// Node.js
|
|
5
|
+
getRandomValues<T extends ArrayBuffer | ArrayBufferView>(array: T): T;
|
|
6
|
+
}
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
let cryptoImpl: any =
|
|
5
|
-
typeof window !== "undefined"
|
|
6
|
-
? window.crypto
|
|
7
|
-
: typeof global !== "undefined" && global.crypto
|
|
8
|
-
? global.crypto
|
|
9
|
-
: nodeCrypto;
|
|
8
|
+
let cryptoImpl: SparkCrypto | null = globalThis.crypto ?? null;
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
export const getCrypto = () => {
|
|
11
|
+
if (!cryptoImpl) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
"Crypto implementation is not set. Please set it using setCrypto().",
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return cryptoImpl;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const setCrypto = (cryptoImplParam: SparkCrypto | null): void => {
|
|
21
|
+
cryptoImpl = cryptoImplParam;
|
|
12
22
|
};
|
package/src/utils/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from "./address.js";
|
|
1
2
|
export * from "./adaptor-signature.js";
|
|
2
3
|
export * from "./bitcoin.js";
|
|
3
4
|
export * from "./keys.js";
|
|
@@ -7,6 +8,7 @@ export * from "./proof.js";
|
|
|
7
8
|
export * from "./response-validation.js";
|
|
8
9
|
export * from "./secret-sharing.js";
|
|
9
10
|
export * from "./signing.js";
|
|
11
|
+
export * from "./token-identifier.js";
|
|
10
12
|
export * from "./token-transactions.js";
|
|
11
13
|
export * from "./transfer_package.js";
|
|
12
14
|
export * from "./transaction.js";
|
package/src/utils/network.ts
CHANGED
|
@@ -23,6 +23,23 @@ export const NetworkToProto: Record<Network, NetworkProto> = {
|
|
|
23
23
|
[Network.LOCAL]: NetworkProto.REGTEST,
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
export const protoToNetwork = (
|
|
27
|
+
protoNetwork: NetworkProto,
|
|
28
|
+
): Network | undefined => {
|
|
29
|
+
switch (protoNetwork) {
|
|
30
|
+
case NetworkProto.MAINNET:
|
|
31
|
+
return Network.MAINNET;
|
|
32
|
+
case NetworkProto.TESTNET:
|
|
33
|
+
return Network.TESTNET;
|
|
34
|
+
case NetworkProto.SIGNET:
|
|
35
|
+
return Network.SIGNET;
|
|
36
|
+
case NetworkProto.REGTEST:
|
|
37
|
+
return Network.REGTEST;
|
|
38
|
+
default:
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
26
43
|
const NetworkConfig: Record<Network, typeof btc.NETWORK> = {
|
|
27
44
|
[Network.MAINNET]: btc.NETWORK,
|
|
28
45
|
[Network.TESTNET]: btc.TEST_NETWORK,
|
|
@@ -3,8 +3,6 @@ import { secp256k1 } from "@noble/curves/secp256k1";
|
|
|
3
3
|
import { getCrypto } from "./crypto.js";
|
|
4
4
|
import { ValidationError } from "../errors/index.js";
|
|
5
5
|
|
|
6
|
-
const crypto = getCrypto();
|
|
7
|
-
|
|
8
6
|
type Polynomial = {
|
|
9
7
|
fieldModulus: bigint;
|
|
10
8
|
coefficients: bigint[];
|
|
@@ -28,6 +26,7 @@ export function getRandomBigInt(max: bigint): bigint {
|
|
|
28
26
|
|
|
29
27
|
const mask = (1n << BigInt(max.toString(2).length)) - 1n;
|
|
30
28
|
while (true) {
|
|
29
|
+
const crypto = getCrypto();
|
|
31
30
|
const randBytes = crypto.getRandomValues(new Uint8Array(byteLength + 1));
|
|
32
31
|
|
|
33
32
|
const randValue = BigInt("0x" + bytesToHex(randBytes)) & mask;
|
package/src/utils/signing.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
2
2
|
import { ValidationError } from "../errors/index.js";
|
|
3
|
-
import type { SigningCommitment, SigningNonce } from "../signer/
|
|
3
|
+
import type { SigningCommitment, SigningNonce } from "../signer/types.js";
|
|
4
4
|
|
|
5
5
|
export function getRandomSigningNonce(): SigningNonce {
|
|
6
6
|
const binding = secp256k1.utils.randomPrivateKey();
|
|
@@ -2,10 +2,10 @@ import { bytesToHex, bytesToNumberBE } from "@noble/curves/abstract/utils";
|
|
|
2
2
|
import { OutputWithPreviousTransactionData } from "../proto/spark.js";
|
|
3
3
|
import { TokenBalanceMap } from "../spark-wallet/types.js";
|
|
4
4
|
|
|
5
|
-
export function
|
|
6
|
-
|
|
5
|
+
export function sumAvailableTokens(
|
|
6
|
+
outputs: OutputWithPreviousTransactionData[],
|
|
7
7
|
): bigint {
|
|
8
|
-
return
|
|
8
|
+
return outputs.reduce(
|
|
9
9
|
(sum, output) => sum + BigInt(bytesToNumberBE(output.output!.tokenAmount!)),
|
|
10
10
|
BigInt(0),
|
|
11
11
|
);
|
|
@@ -493,6 +493,38 @@ export async function constructUnilateralExitFeeBumpPackages(
|
|
|
493
493
|
undefined,
|
|
494
494
|
);
|
|
495
495
|
|
|
496
|
+
const feeBumpTx = btc.Transaction.fromPSBT(
|
|
497
|
+
hexToBytes(refundFeeBump.feeBumpPsbt),
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
var feeBumpOut: psbt.TransactionOutput | null =
|
|
501
|
+
feeBumpTx.outputsLength === 1 ? feeBumpTx.getOutput(0) : null;
|
|
502
|
+
var feeBumpOutPubKey: string | null = null;
|
|
503
|
+
|
|
504
|
+
// Remove used UTXOs from the available list
|
|
505
|
+
for (const usedUtxo of usedUtxos) {
|
|
506
|
+
if (feeBumpOut && bytesToHex(feeBumpOut.script!) == usedUtxo.script) {
|
|
507
|
+
feeBumpOutPubKey = usedUtxo.publicKey;
|
|
508
|
+
}
|
|
509
|
+
const index = availableUtxos.findIndex(
|
|
510
|
+
(u) => u.txid === usedUtxo.txid && u.vout === usedUtxo.vout,
|
|
511
|
+
);
|
|
512
|
+
if (index !== -1) {
|
|
513
|
+
availableUtxos.splice(index, 1);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (feeBumpOut)
|
|
518
|
+
// Add to end instead of the beginning in case there are other available UTXOs we can use first
|
|
519
|
+
// We don't want to wait on leaf 1 to be broadcasted to broadcast leaf 2 if we can use a different available UTXO
|
|
520
|
+
availableUtxos.push({
|
|
521
|
+
txid: getTxId(feeBumpTx),
|
|
522
|
+
vout: 0,
|
|
523
|
+
value: feeBumpOut.amount!,
|
|
524
|
+
script: bytesToHex(feeBumpOut.script!),
|
|
525
|
+
publicKey: feeBumpOutPubKey!,
|
|
526
|
+
});
|
|
527
|
+
|
|
496
528
|
txPackages.push({
|
|
497
529
|
tx: refundTxHex,
|
|
498
530
|
feeBumpPsbt: refundFeeBump.feeBumpPsbt,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** This is an enum identifying a particular Bitcoin Network. **/
|
|
2
|
-
declare enum BitcoinNetwork {
|
|
3
|
-
/**
|
|
4
|
-
* This is an enum value that represents values that could be added in the future.
|
|
5
|
-
* Clients should support unknown values as more of them could be added without notice.
|
|
6
|
-
*/
|
|
7
|
-
FUTURE_VALUE = "FUTURE_VALUE",
|
|
8
|
-
/** The production version of the Bitcoin Blockchain. **/
|
|
9
|
-
MAINNET = "MAINNET",
|
|
10
|
-
/** A test version of the Bitcoin Blockchain, maintained by Lightspark. **/
|
|
11
|
-
REGTEST = "REGTEST",
|
|
12
|
-
/** A test version of the Bitcoin Blockchain, maintained by a centralized organization. Not in use at Lightspark. **/
|
|
13
|
-
SIGNET = "SIGNET",
|
|
14
|
-
/** A test version of the Bitcoin Blockchain, publicly available. **/
|
|
15
|
-
TESTNET = "TESTNET"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { BitcoinNetwork as B };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** This is an enum identifying a particular Bitcoin Network. **/
|
|
2
|
-
declare enum BitcoinNetwork {
|
|
3
|
-
/**
|
|
4
|
-
* This is an enum value that represents values that could be added in the future.
|
|
5
|
-
* Clients should support unknown values as more of them could be added without notice.
|
|
6
|
-
*/
|
|
7
|
-
FUTURE_VALUE = "FUTURE_VALUE",
|
|
8
|
-
/** The production version of the Bitcoin Blockchain. **/
|
|
9
|
-
MAINNET = "MAINNET",
|
|
10
|
-
/** A test version of the Bitcoin Blockchain, maintained by Lightspark. **/
|
|
11
|
-
REGTEST = "REGTEST",
|
|
12
|
-
/** A test version of the Bitcoin Blockchain, maintained by a centralized organization. Not in use at Lightspark. **/
|
|
13
|
-
SIGNET = "SIGNET",
|
|
14
|
-
/** A test version of the Bitcoin Blockchain, publicly available. **/
|
|
15
|
-
TESTNET = "TESTNET"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { BitcoinNetwork as B };
|