@buildonspark/spark-sdk 0.1.47 → 0.2.0
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 +12 -0
- package/dist/{chunk-BGGEVUJK.js → chunk-2ENZX6LT.js} +241 -7
- package/dist/{chunk-LHRD2WT6.js → chunk-4JD4HIAN.js} +23 -3
- package/dist/chunk-BYXBJQAS.js +0 -0
- package/dist/{chunk-EAP3U3CW.js → chunk-CDLETEDT.js} +25 -17
- package/dist/{chunk-OBFKIEMP.js → chunk-TM6CHQXC.js} +1 -1
- package/dist/{chunk-NNX4OK44.js → chunk-UDK3EBE5.js} +5544 -1678
- package/dist/chunk-XYTKKLCV.js +7 -0
- package/dist/{client-D7KgLN44.d.ts → client-DKbwpcnl.d.ts} +73 -61
- package/dist/{client-CvpTRpcw.d.cts → client-Drs5Lapg.d.cts} +73 -61
- package/dist/debug.cjs +32358 -0
- package/dist/debug.d.cts +126 -0
- package/dist/debug.d.ts +126 -0
- package/dist/debug.js +21 -0
- package/dist/graphql/objects/index.d.cts +2 -5
- package/dist/graphql/objects/index.d.ts +2 -5
- package/dist/graphql/objects/index.js +2 -4
- package/dist/index.cjs +791 -474
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +32 -36
- package/dist/index.node.cjs +791 -474
- package/dist/index.node.d.cts +12 -132
- package/dist/index.node.d.ts +12 -132
- package/dist/index.node.js +31 -31
- package/dist/native/index.cjs +885 -575
- package/dist/native/index.d.cts +419 -335
- package/dist/native/index.d.ts +419 -335
- package/dist/native/index.js +857 -550
- package/dist/proto/lrc20.d.cts +1 -1
- package/dist/proto/lrc20.d.ts +1 -1
- package/dist/proto/lrc20.js +1 -1
- package/dist/proto/spark.cjs +241 -7
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark.js +5 -1
- package/dist/proto/spark_token.cjs +22 -2
- package/dist/proto/spark_token.d.cts +8 -1
- package/dist/proto/spark_token.d.ts +8 -1
- package/dist/proto/spark_token.js +2 -2
- package/dist/{sdk-types-BGCeea0G.d.ts → sdk-types-DCIVdKUT.d.ts} +1 -1
- package/dist/{sdk-types-XUeQMLFP.d.cts → sdk-types-DJ2ve9YY.d.cts} +1 -1
- package/dist/{spark-BbUrbvZz.d.ts → spark-BUOx3U7Q.d.cts} +103 -5
- package/dist/{spark-BbUrbvZz.d.cts → spark-BUOx3U7Q.d.ts} +103 -5
- package/dist/{spark-wallet-CJkQW8pK.d.ts → spark-wallet-CF8Oxjqs.d.ts} +143 -131
- package/dist/{spark-wallet-BAFPpPtY.d.cts → spark-wallet-DOLSa3oF.d.cts} +143 -131
- package/dist/tests/test-utils.cjs +7137 -5744
- package/dist/tests/test-utils.d.cts +5 -5
- package/dist/tests/test-utils.d.ts +5 -5
- package/dist/tests/test-utils.js +16 -8
- package/dist/types/index.cjs +239 -7
- package/dist/types/index.d.cts +3 -3
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +6 -8
- package/dist/xchain-address-C2xMs9nz.d.cts +126 -0
- package/dist/xchain-address-Ckto9oEz.d.ts +126 -0
- package/package.json +5 -1
- package/src/debug.ts +13 -0
- package/src/proto/mock.ts +76 -0
- package/src/proto/spark.ts +354 -6
- package/src/proto/spark_token.ts +34 -2
- package/src/services/coop-exit.ts +6 -3
- package/src/services/deposit.ts +9 -8
- package/src/services/lightning.ts +3 -1
- package/src/services/signing.ts +10 -6
- package/src/services/token-transactions.ts +95 -80
- package/src/services/transfer.ts +88 -60
- package/src/services/tree-creation.ts +17 -9
- package/src/signer/signer.react-native.ts +3 -5
- package/src/signer/signer.ts +153 -297
- package/src/signer/types.ts +18 -7
- package/src/spark-wallet/spark-wallet.ts +170 -136
- package/src/spark-wallet/types.ts +18 -4
- package/src/tests/integration/adaptor-signature.test.ts +8 -9
- package/src/tests/integration/coop-exit.test.ts +212 -201
- package/src/tests/integration/lightning.test.ts +126 -101
- package/src/tests/integration/swap.test.ts +115 -83
- package/src/tests/integration/transfer.test.ts +287 -210
- package/src/tests/integration/tree-creation.test.ts +0 -5
- package/src/tests/test-utils.ts +10 -4
- package/src/tests/token-identifier.test.ts +6 -6
- package/src/utils/token-identifier.ts +27 -21
- package/src/utils/token-transaction-validation.ts +34 -0
- package/src/utils/token-transactions.ts +9 -5
- package/dist/chunk-GWFQ7EBA.js +0 -3773
- package/dist/chunk-HMLOC6TE.js +0 -14
- package/ios/spark_frost.kt +0 -1900
package/src/services/deposit.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
GenerateDepositAddressResponse,
|
|
13
13
|
StartDepositTreeCreationResponse,
|
|
14
14
|
} from "../proto/spark.js";
|
|
15
|
+
import { KeyDerivation } from "../signer/types.js";
|
|
15
16
|
import {
|
|
16
17
|
getP2TRAddressFromPublicKey,
|
|
17
18
|
getSigHashFromTx,
|
|
@@ -20,10 +21,7 @@ import {
|
|
|
20
21
|
import { subtractPublicKeys } from "../utils/keys.js";
|
|
21
22
|
import { getNetwork } from "../utils/network.js";
|
|
22
23
|
import { proofOfPossessionMessageHashForDepositAddress } from "../utils/proof.js";
|
|
23
|
-
import {
|
|
24
|
-
DEFAULT_FEE_SATS,
|
|
25
|
-
getEphemeralAnchorOutput,
|
|
26
|
-
} from "../utils/transaction.js";
|
|
24
|
+
import { getEphemeralAnchorOutput } from "../utils/transaction.js";
|
|
27
25
|
import { WalletConfigService } from "./config.js";
|
|
28
26
|
import { ConnectionManager } from "./connection.js";
|
|
29
27
|
|
|
@@ -39,7 +37,7 @@ export type GenerateDepositAddressParams = {
|
|
|
39
37
|
};
|
|
40
38
|
|
|
41
39
|
export type CreateTreeRootParams = {
|
|
42
|
-
|
|
40
|
+
keyDerivation: KeyDerivation;
|
|
43
41
|
verifyingKey: Uint8Array;
|
|
44
42
|
depositTx: Transaction;
|
|
45
43
|
vout: number;
|
|
@@ -182,7 +180,7 @@ export class DepositService {
|
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
async createTreeRoot({
|
|
185
|
-
|
|
183
|
+
keyDerivation,
|
|
186
184
|
verifyingKey,
|
|
187
185
|
depositTx,
|
|
188
186
|
vout,
|
|
@@ -242,6 +240,9 @@ export class DepositService {
|
|
|
242
240
|
sequence,
|
|
243
241
|
});
|
|
244
242
|
|
|
243
|
+
const signingPubKey =
|
|
244
|
+
await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
245
|
+
|
|
245
246
|
const refundP2trAddress = getP2TRAddressFromPublicKey(
|
|
246
247
|
signingPubKey,
|
|
247
248
|
this.config.getNetwork(),
|
|
@@ -346,7 +347,7 @@ export class DepositService {
|
|
|
346
347
|
const rootSignature = await this.config.signer.signFrost({
|
|
347
348
|
message: rootTxSighash,
|
|
348
349
|
publicKey: signingPubKey,
|
|
349
|
-
|
|
350
|
+
keyDerivation,
|
|
350
351
|
verifyingKey,
|
|
351
352
|
selfCommitment: rootNonceCommitment,
|
|
352
353
|
statechainCommitments:
|
|
@@ -358,7 +359,7 @@ export class DepositService {
|
|
|
358
359
|
const refundSignature = await this.config.signer.signFrost({
|
|
359
360
|
message: refundTxSighash,
|
|
360
361
|
publicKey: signingPubKey,
|
|
361
|
-
|
|
362
|
+
keyDerivation,
|
|
362
363
|
verifyingKey,
|
|
363
364
|
selfCommitment: refundNonceCommitment,
|
|
364
365
|
statechainCommitments:
|
|
@@ -236,7 +236,9 @@ export class LightningService {
|
|
|
236
236
|
);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
amountSats = isZeroAmountInvoice
|
|
239
|
+
amountSats = isZeroAmountInvoice
|
|
240
|
+
? amountSatsToSend!
|
|
241
|
+
: Math.ceil(amountMsats / 1000);
|
|
240
242
|
|
|
241
243
|
if (isNaN(amountSats) || amountSats <= 0) {
|
|
242
244
|
throw new ValidationError("Invalid amount", {
|
package/src/services/signing.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { TransactionInput } from "@scure/btc-signer/psbt";
|
|
2
1
|
import { hexToBytes } from "@noble/curves/abstract/utils";
|
|
2
|
+
import { TransactionInput } from "@scure/btc-signer/psbt";
|
|
3
3
|
import { ValidationError } from "../errors/types.js";
|
|
4
4
|
import {
|
|
5
5
|
RequestedSigningCommitments,
|
|
6
6
|
UserSignedTxSigningJob,
|
|
7
7
|
} from "../proto/spark.js";
|
|
8
|
-
import type { LeafKeyTweak } from "./transfer.js";
|
|
9
|
-
import { WalletConfigService } from "./config.js";
|
|
10
8
|
import {
|
|
11
9
|
getSigHashFromTx,
|
|
12
10
|
getTxFromRawTxBytes,
|
|
@@ -16,6 +14,8 @@ import {
|
|
|
16
14
|
createRefundTx,
|
|
17
15
|
getNextTransactionSequence,
|
|
18
16
|
} from "../utils/transaction.js";
|
|
17
|
+
import { WalletConfigService } from "./config.js";
|
|
18
|
+
import type { LeafKeyTweak } from "./transfer.js";
|
|
19
19
|
|
|
20
20
|
export class SigningService {
|
|
21
21
|
private readonly config: WalletConfigService;
|
|
@@ -83,8 +83,10 @@ export class SigningService {
|
|
|
83
83
|
}
|
|
84
84
|
const signingResult = await this.config.signer.signFrost({
|
|
85
85
|
message: sighash,
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
keyDerivation: leaf.keyDerivation,
|
|
87
|
+
publicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
88
|
+
leaf.keyDerivation,
|
|
89
|
+
),
|
|
88
90
|
selfCommitment: signingCommitment,
|
|
89
91
|
statechainCommitments: signingNonceCommitments,
|
|
90
92
|
adaptorPubKey: new Uint8Array(),
|
|
@@ -93,7 +95,9 @@ export class SigningService {
|
|
|
93
95
|
|
|
94
96
|
leafSigningJobs.push({
|
|
95
97
|
leafId: leaf.leaf.id,
|
|
96
|
-
signingPublicKey:
|
|
98
|
+
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
99
|
+
leaf.keyDerivation,
|
|
100
|
+
),
|
|
97
101
|
rawTx: refundTx.toBytes(),
|
|
98
102
|
signingNonceCommitment: signingCommitment,
|
|
99
103
|
userSignature: signingResult,
|
|
@@ -3,53 +3,59 @@ import {
|
|
|
3
3
|
bytesToNumberBE,
|
|
4
4
|
numberToBytesBE,
|
|
5
5
|
} from "@noble/curves/abstract/utils";
|
|
6
|
+
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
7
|
+
import { hexToBytes } from "@noble/hashes/utils";
|
|
8
|
+
import {
|
|
9
|
+
InternalValidationError,
|
|
10
|
+
NetworkError,
|
|
11
|
+
ValidationError,
|
|
12
|
+
} from "../errors/types.js";
|
|
6
13
|
import {
|
|
7
|
-
OutputWithPreviousTransactionData,
|
|
8
|
-
OperatorSpecificTokenTransactionSignablePayload,
|
|
9
|
-
SignTokenTransactionResponse,
|
|
10
14
|
OperatorSpecificOwnerSignature,
|
|
15
|
+
OperatorSpecificTokenTransactionSignablePayload,
|
|
16
|
+
OutputWithPreviousTransactionData,
|
|
17
|
+
QueryTokenTransactionsRequest as QueryTokenTransactionsRequestV0,
|
|
11
18
|
RevocationSecretWithIndex,
|
|
19
|
+
SignTokenTransactionResponse,
|
|
20
|
+
TokenTransaction as TokenTransactionV0,
|
|
12
21
|
TokenTransactionWithStatus as TokenTransactionWithStatusV0,
|
|
13
|
-
QueryTokenTransactionsRequest as QueryTokenTransactionsRequestV0,
|
|
14
22
|
} from "../proto/spark.js";
|
|
15
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
InputTtxoSignaturesPerOperator,
|
|
25
|
+
QueryTokenTransactionsRequest as QueryTokenTransactionsRequestV1,
|
|
26
|
+
SignatureWithIndex,
|
|
27
|
+
TokenOutput,
|
|
28
|
+
TokenTransaction,
|
|
29
|
+
TokenTransactionWithStatus as TokenTransactionWithStatusV1,
|
|
30
|
+
} from "../proto/spark_token.js";
|
|
31
|
+
import { TokenOutputsMap } from "../spark-wallet/types.js";
|
|
16
32
|
import { SparkCallOptions } from "../types/grpc.js";
|
|
33
|
+
import { decodeSparkAddress } from "../utils/address.js";
|
|
34
|
+
import { collectResponses } from "../utils/response-validation.js";
|
|
17
35
|
import {
|
|
18
36
|
hashOperatorSpecificTokenTransactionSignablePayload,
|
|
19
|
-
hashTokenTransactionV0,
|
|
20
37
|
hashTokenTransaction,
|
|
38
|
+
hashTokenTransactionV0,
|
|
21
39
|
} from "../utils/token-hashing.js";
|
|
22
40
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} from "../utils/token-
|
|
41
|
+
Bech32mTokenIdentifier,
|
|
42
|
+
decodeBech32mTokenIdentifier,
|
|
43
|
+
} from "../utils/token-identifier.js";
|
|
44
|
+
import {
|
|
45
|
+
KeyshareWithOperatorIndex,
|
|
46
|
+
recoverRevocationSecretFromKeyshares,
|
|
47
|
+
} from "../utils/token-keyshares.js";
|
|
26
48
|
import {
|
|
27
|
-
validateTokenTransactionV0,
|
|
28
49
|
validateTokenTransaction,
|
|
50
|
+
validateTokenTransactionV0,
|
|
29
51
|
} from "../utils/token-transaction-validation.js";
|
|
52
|
+
import {
|
|
53
|
+
checkIfSelectedOutputsAreAvailable,
|
|
54
|
+
sumAvailableTokens,
|
|
55
|
+
} from "../utils/token-transactions.js";
|
|
30
56
|
import { WalletConfigService } from "./config.js";
|
|
31
57
|
import { ConnectionManager } from "./connection.js";
|
|
32
|
-
import {
|
|
33
|
-
ValidationError,
|
|
34
|
-
NetworkError,
|
|
35
|
-
InternalValidationError,
|
|
36
|
-
} from "../errors/types.js";
|
|
37
58
|
import { SigningOperator } from "./wallet-config.js";
|
|
38
|
-
import { hexToBytes } from "@noble/hashes/utils";
|
|
39
|
-
import { decodeSparkAddress } from "../utils/address.js";
|
|
40
|
-
import {
|
|
41
|
-
TokenTransaction,
|
|
42
|
-
SignatureWithIndex,
|
|
43
|
-
InputTtxoSignaturesPerOperator,
|
|
44
|
-
QueryTokenTransactionsRequest as QueryTokenTransactionsRequestV1,
|
|
45
|
-
TokenTransactionWithStatus as TokenTransactionWithStatusV1,
|
|
46
|
-
} from "../proto/spark_token.js";
|
|
47
|
-
import { TokenTransaction as TokenTransactionV0 } from "../proto/spark.js";
|
|
48
|
-
import { collectResponses } from "../utils/response-validation.js";
|
|
49
|
-
import {
|
|
50
|
-
KeyshareWithOperatorIndex,
|
|
51
|
-
recoverRevocationSecretFromKeyshares,
|
|
52
|
-
} from "../utils/token-keyshares.js";
|
|
53
59
|
|
|
54
60
|
const MAX_TOKEN_OUTPUTS = 500;
|
|
55
61
|
|
|
@@ -80,16 +86,16 @@ export class TokenTransactionService {
|
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
public async tokenTransfer(
|
|
83
|
-
tokenOutputs:
|
|
89
|
+
tokenOutputs: TokenOutputsMap,
|
|
84
90
|
receiverOutputs: {
|
|
85
|
-
|
|
91
|
+
tokenIdentifier: Bech32mTokenIdentifier;
|
|
86
92
|
tokenAmount: bigint;
|
|
87
93
|
receiverSparkAddress: string;
|
|
88
94
|
}[],
|
|
89
95
|
outputSelectionStrategy: "SMALL_FIRST" | "LARGE_FIRST" = "SMALL_FIRST",
|
|
90
96
|
selectedOutputs?: OutputWithPreviousTransactionData[],
|
|
91
97
|
): Promise<string> {
|
|
92
|
-
if (receiverOutputs.length === 0) {
|
|
98
|
+
if (!Array.isArray(receiverOutputs) || receiverOutputs.length === 0) {
|
|
93
99
|
throw new ValidationError("No receiver outputs provided", {
|
|
94
100
|
field: "receiverOutputs",
|
|
95
101
|
value: receiverOutputs,
|
|
@@ -101,9 +107,11 @@ export class TokenTransactionService {
|
|
|
101
107
|
(sum, transfer) => sum + transfer.tokenAmount,
|
|
102
108
|
0n,
|
|
103
109
|
);
|
|
104
|
-
|
|
105
110
|
let outputsToUse: OutputWithPreviousTransactionData[];
|
|
106
111
|
|
|
112
|
+
const tokenIdentifier: Bech32mTokenIdentifier =
|
|
113
|
+
receiverOutputs[0]!!.tokenIdentifier;
|
|
114
|
+
|
|
107
115
|
if (selectedOutputs) {
|
|
108
116
|
outputsToUse = selectedOutputs;
|
|
109
117
|
|
|
@@ -111,7 +119,7 @@ export class TokenTransactionService {
|
|
|
111
119
|
!checkIfSelectedOutputsAreAvailable(
|
|
112
120
|
outputsToUse,
|
|
113
121
|
tokenOutputs,
|
|
114
|
-
|
|
122
|
+
tokenIdentifier,
|
|
115
123
|
)
|
|
116
124
|
) {
|
|
117
125
|
throw new ValidationError(
|
|
@@ -125,16 +133,14 @@ export class TokenTransactionService {
|
|
|
125
133
|
}
|
|
126
134
|
} else {
|
|
127
135
|
outputsToUse = this.selectTokenOutputs(
|
|
128
|
-
tokenOutputs.get(
|
|
136
|
+
tokenOutputs.get(tokenIdentifier)!!,
|
|
129
137
|
totalTokenAmount,
|
|
130
138
|
outputSelectionStrategy,
|
|
131
139
|
);
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
if (outputsToUse.length > MAX_TOKEN_OUTPUTS) {
|
|
135
|
-
const availableOutputs = tokenOutputs.get(
|
|
136
|
-
receiverOutputs[0]!!.tokenPublicKey,
|
|
137
|
-
)!!;
|
|
143
|
+
const availableOutputs = tokenOutputs.get(tokenIdentifier)!!;
|
|
138
144
|
|
|
139
145
|
// Sort outputs by the same strategy as in selectTokenOutputs
|
|
140
146
|
const sortedOutputs = [...availableOutputs];
|
|
@@ -154,6 +160,23 @@ export class TokenTransactionService {
|
|
|
154
160
|
);
|
|
155
161
|
}
|
|
156
162
|
|
|
163
|
+
const rawTokenIdentifier: Uint8Array = decodeBech32mTokenIdentifier(
|
|
164
|
+
tokenIdentifier,
|
|
165
|
+
this.config.getNetworkType(),
|
|
166
|
+
).tokenIdentifier;
|
|
167
|
+
|
|
168
|
+
// remove for full v0 deprecation
|
|
169
|
+
let tokenPublicKey: Uint8Array;
|
|
170
|
+
if (this.config.getTokenTransactionVersion() === "V0") {
|
|
171
|
+
const tokenClient = await this.connectionManager.createSparkTokenClient(
|
|
172
|
+
this.config.getCoordinatorAddress(),
|
|
173
|
+
);
|
|
174
|
+
const tokenMetadata = await tokenClient.query_token_metadata({
|
|
175
|
+
tokenIdentifiers: [rawTokenIdentifier],
|
|
176
|
+
});
|
|
177
|
+
tokenPublicKey = tokenMetadata.tokenMetadata[0]!.issuerPublicKey;
|
|
178
|
+
}
|
|
179
|
+
|
|
157
180
|
const tokenOutputData = receiverOutputs.map((transfer) => {
|
|
158
181
|
const receiverAddress = decodeSparkAddress(
|
|
159
182
|
transfer.receiverSparkAddress,
|
|
@@ -161,7 +184,8 @@ export class TokenTransactionService {
|
|
|
161
184
|
);
|
|
162
185
|
return {
|
|
163
186
|
receiverSparkAddress: hexToBytes(receiverAddress.identityPublicKey),
|
|
164
|
-
|
|
187
|
+
rawTokenIdentifier,
|
|
188
|
+
tokenPublicKey, // Remove for full v0 deprecation
|
|
165
189
|
tokenAmount: transfer.tokenAmount,
|
|
166
190
|
};
|
|
167
191
|
});
|
|
@@ -169,6 +193,7 @@ export class TokenTransactionService {
|
|
|
169
193
|
let tokenTransaction: TokenTransactionV0 | TokenTransaction;
|
|
170
194
|
|
|
171
195
|
if (this.config.getTokenTransactionVersion() === "V0") {
|
|
196
|
+
// remove for full v0 deprecation
|
|
172
197
|
tokenTransaction = await this.constructTransferTokenTransactionV0(
|
|
173
198
|
outputsToUse,
|
|
174
199
|
tokenOutputData,
|
|
@@ -179,7 +204,6 @@ export class TokenTransactionService {
|
|
|
179
204
|
tokenOutputData,
|
|
180
205
|
);
|
|
181
206
|
}
|
|
182
|
-
|
|
183
207
|
const txId = await this.broadcastTokenTransaction(
|
|
184
208
|
tokenTransaction,
|
|
185
209
|
outputsToUse.map((output) => output.output!.ownerPublicKey),
|
|
@@ -247,7 +271,7 @@ export class TokenTransactionService {
|
|
|
247
271
|
selectedOutputs: OutputWithPreviousTransactionData[],
|
|
248
272
|
tokenOutputData: Array<{
|
|
249
273
|
receiverSparkAddress: Uint8Array;
|
|
250
|
-
|
|
274
|
+
rawTokenIdentifier: Uint8Array;
|
|
251
275
|
tokenAmount: bigint;
|
|
252
276
|
}>,
|
|
253
277
|
): Promise<TokenTransaction> {
|
|
@@ -261,19 +285,21 @@ export class TokenTransactionService {
|
|
|
261
285
|
0n,
|
|
262
286
|
);
|
|
263
287
|
|
|
264
|
-
const tokenOutputs = tokenOutputData.map(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
288
|
+
const tokenOutputs: TokenOutput[] = tokenOutputData.map(
|
|
289
|
+
(output): TokenOutput => ({
|
|
290
|
+
ownerPublicKey: output.receiverSparkAddress,
|
|
291
|
+
tokenIdentifier: output.rawTokenIdentifier,
|
|
292
|
+
tokenAmount: numberToBytesBE(output.tokenAmount, 16),
|
|
293
|
+
}),
|
|
294
|
+
);
|
|
269
295
|
|
|
270
296
|
if (availableTokenAmount > totalRequestedAmount) {
|
|
271
297
|
const changeAmount = availableTokenAmount - totalRequestedAmount;
|
|
272
|
-
const
|
|
298
|
+
const firstTokenIdentifierBytes = tokenOutputData[0]!!.rawTokenIdentifier;
|
|
273
299
|
|
|
274
300
|
tokenOutputs.push({
|
|
275
301
|
ownerPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
276
|
-
|
|
302
|
+
tokenIdentifier: firstTokenIdentifierBytes,
|
|
277
303
|
tokenAmount: numberToBytesBE(changeAmount, 16),
|
|
278
304
|
});
|
|
279
305
|
}
|
|
@@ -614,19 +640,27 @@ export class TokenTransactionService {
|
|
|
614
640
|
|
|
615
641
|
const ownerSignaturesWithIndex: SignatureWithIndex[] = [];
|
|
616
642
|
if (tokenTransaction.tokenInputs!.$case === "mintInput") {
|
|
617
|
-
const
|
|
618
|
-
tokenTransaction.tokenInputs!.mintInput.
|
|
619
|
-
if (!
|
|
643
|
+
const tokenIdentifier =
|
|
644
|
+
tokenTransaction.tokenInputs!.mintInput.tokenIdentifier;
|
|
645
|
+
if (!tokenIdentifier) {
|
|
620
646
|
throw new ValidationError("Invalid mint input", {
|
|
621
|
-
field: "
|
|
647
|
+
field: "tokenIdentifier",
|
|
622
648
|
value: null,
|
|
623
|
-
expected: "Non-null
|
|
649
|
+
expected: "Non-null tokenIdentifier",
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
const ownerPubkey = tokenTransaction.tokenOutputs[0]!.ownerPublicKey;
|
|
653
|
+
if (!ownerPubkey) {
|
|
654
|
+
throw new ValidationError("Invalid mint input", {
|
|
655
|
+
field: "ownerPubkey",
|
|
656
|
+
value: null,
|
|
657
|
+
expected: "Non-null ownerPubkey",
|
|
624
658
|
});
|
|
625
659
|
}
|
|
626
660
|
|
|
627
661
|
const ownerSignature = await this.signMessageWithKey(
|
|
628
662
|
partialTokenTransactionHash,
|
|
629
|
-
|
|
663
|
+
ownerPubkey,
|
|
630
664
|
);
|
|
631
665
|
|
|
632
666
|
ownerSignaturesWithIndex.push({
|
|
@@ -1028,6 +1062,7 @@ export class TokenTransactionService {
|
|
|
1028
1062
|
tokenTransaction: v1TokenTransaction,
|
|
1029
1063
|
status: tx.status,
|
|
1030
1064
|
confirmationMetadata: tx.confirmationMetadata,
|
|
1065
|
+
tokenTransactionHash: tx.tokenTransactionHash,
|
|
1031
1066
|
};
|
|
1032
1067
|
});
|
|
1033
1068
|
} catch (error) {
|
|
@@ -1084,23 +1119,6 @@ export class TokenTransactionService {
|
|
|
1084
1119
|
}
|
|
1085
1120
|
}
|
|
1086
1121
|
|
|
1087
|
-
public async syncTokenOutputs(
|
|
1088
|
-
tokenOutputs: Map<string, OutputWithPreviousTransactionData[]>,
|
|
1089
|
-
) {
|
|
1090
|
-
const unsortedTokenOutputs = await this.fetchOwnedTokenOutputs({
|
|
1091
|
-
ownerPublicKeys: await this.config.signer.getTrackedPublicKeys(),
|
|
1092
|
-
});
|
|
1093
|
-
|
|
1094
|
-
unsortedTokenOutputs.forEach((output) => {
|
|
1095
|
-
const tokenKey = bytesToHex(output.output!.tokenPublicKey!);
|
|
1096
|
-
const index = output.previousTransactionVout!;
|
|
1097
|
-
|
|
1098
|
-
tokenOutputs.set(tokenKey, [
|
|
1099
|
-
{ ...output, previousTransactionVout: index },
|
|
1100
|
-
]);
|
|
1101
|
-
});
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
1122
|
public selectTokenOutputs(
|
|
1105
1123
|
tokenOutputs: OutputWithPreviousTransactionData[],
|
|
1106
1124
|
tokenAmount: bigint,
|
|
@@ -1187,14 +1205,11 @@ export class TokenTransactionService {
|
|
|
1187
1205
|
return await this.config.signer.signMessageWithIdentityKey(message);
|
|
1188
1206
|
}
|
|
1189
1207
|
} else {
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
publicKey,
|
|
1196
|
-
);
|
|
1197
|
-
}
|
|
1208
|
+
throw new ValidationError("Invalid public key", {
|
|
1209
|
+
field: "publicKey",
|
|
1210
|
+
value: bytesToHex(publicKey),
|
|
1211
|
+
expected: bytesToHex(await this.config.signer.getIdentityPublicKey()),
|
|
1212
|
+
});
|
|
1198
1213
|
}
|
|
1199
1214
|
}
|
|
1200
1215
|
|