@taquito/sapling 24.2.0 → 24.3.0-beta.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/dist/lib/errors.js +10 -10
- package/dist/lib/sapling-forger/sapling-forger.js +3 -3
- package/dist/lib/sapling-keys/helpers.js +3 -3
- package/dist/lib/sapling-keys/in-memory-proving-key.js +16 -30
- package/dist/lib/sapling-keys/in-memory-spending-key.js +48 -68
- package/dist/lib/sapling-keys/in-memory-viewing-key.js +20 -37
- package/dist/lib/sapling-module-wrapper.js +33 -57
- package/dist/lib/sapling-state/sapling-state.js +83 -106
- package/dist/lib/sapling-state/utils.js +7 -18
- package/dist/lib/sapling-tx-builder/sapling-transactions-builder.js +194 -216
- package/dist/lib/sapling-tx-viewer/sapling-transaction-viewer.js +98 -135
- package/dist/lib/taquito-sapling.js +84 -119
- package/dist/lib/version.js +2 -2
- package/dist/taquito-sapling.es6.js +605 -727
- package/dist/taquito-sapling.es6.js.map +1 -1
- package/dist/taquito-sapling.umd.js +604 -726
- package/dist/taquito-sapling.umd.js.map +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/dist/types/errors.d.ts +11 -8
- package/dist/types/sapling-forger/sapling-forger.d.ts +5 -5
- package/dist/types/sapling-keys/helpers.d.ts +1 -1
- package/dist/types/sapling-keys/in-memory-proving-key.d.ts +3 -4
- package/dist/types/sapling-keys/in-memory-spending-key.d.ts +4 -5
- package/dist/types/sapling-keys/in-memory-viewing-key.d.ts +9 -9
- package/dist/types/sapling-module-wrapper.d.ts +11 -11
- package/dist/types/sapling-state/sapling-state.d.ts +1 -1
- package/dist/types/sapling-state/utils.d.ts +1 -1
- package/dist/types/sapling-tx-builder/sapling-transactions-builder.d.ts +3 -3
- package/dist/types/sapling-tx-viewer/helpers.d.ts +1 -1
- package/dist/types/sapling-tx-viewer/sapling-transaction-viewer.d.ts +4 -4
- package/dist/types/taquito-sapling.d.ts +5 -5
- package/package.json +26 -13
- package/LICENSE +0 -202
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
3
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
4
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
@@ -19,17 +10,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
19
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
12
|
};
|
|
22
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
23
|
-
var t = {};
|
|
24
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
25
|
-
t[p] = s[p];
|
|
26
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
27
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
28
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
29
|
-
t[p[i]] = s[p[i]];
|
|
30
|
-
}
|
|
31
|
-
return t;
|
|
32
|
-
};
|
|
33
13
|
var _SaplingTransactionViewer_viewingKeyProvider, _SaplingTransactionViewer_readProvider, _SaplingTransactionViewer_saplingContractId;
|
|
34
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
15
|
exports.SaplingTransactionViewer = void 0;
|
|
@@ -42,7 +22,7 @@ const helpers_1 = require("./helpers");
|
|
|
42
22
|
const constants_1 = require("../constants");
|
|
43
23
|
const errors_1 = require("../errors");
|
|
44
24
|
/**
|
|
45
|
-
*
|
|
25
|
+
* Allows to retrieve and decrypt sapling transactions using on a viewing key
|
|
46
26
|
*
|
|
47
27
|
* @param inMemoryViewingKey Holds the sapling viewing key
|
|
48
28
|
* @param saplingContractId Address of the sapling contract or sapling id if the smart contract contains multiple sapling states
|
|
@@ -58,102 +38,120 @@ class SaplingTransactionViewer {
|
|
|
58
38
|
__classPrivateFieldSet(this, _SaplingTransactionViewer_readProvider, readProvider, "f");
|
|
59
39
|
}
|
|
60
40
|
/**
|
|
61
|
-
*
|
|
41
|
+
* Retrieve the unspent balance associated with the configured viewing key and sapling state
|
|
62
42
|
*
|
|
63
43
|
* @returns the balance in mutez represented as a BigNumber
|
|
64
44
|
*
|
|
65
45
|
*/
|
|
66
|
-
getBalance() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
balance = balance.plus(valueBigNumber);
|
|
77
|
-
}
|
|
46
|
+
async getBalance() {
|
|
47
|
+
let balance = new bignumber_js_1.default(0);
|
|
48
|
+
const { commitments_and_ciphertexts, nullifiers } = await this.getSaplingDiff();
|
|
49
|
+
for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
|
|
50
|
+
const decrypted = await this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
|
|
51
|
+
if (decrypted) {
|
|
52
|
+
const valueBigNumber = (0, helpers_1.convertValueToBigNumber)(decrypted.value);
|
|
53
|
+
const isSpent = await this.isSpent(decrypted.paymentAddress, valueBigNumber.toString(), decrypted.randomCommitmentTrapdoor, i, nullifiers);
|
|
54
|
+
if (!isSpent) {
|
|
55
|
+
balance = balance.plus(valueBigNumber);
|
|
78
56
|
}
|
|
79
57
|
}
|
|
80
|
-
|
|
81
|
-
|
|
58
|
+
}
|
|
59
|
+
return balance;
|
|
82
60
|
}
|
|
83
61
|
/**
|
|
84
|
-
*
|
|
62
|
+
* Retrieve all the incoming and outgoing transactions associated with the configured viewing key.
|
|
85
63
|
* The response properties are in Uint8Array format; use the getIncomingAndOutgoingTransactions method for readable properties
|
|
86
64
|
*
|
|
87
65
|
*/
|
|
88
|
-
getIncomingAndOutgoingTransactionsRaw() {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
incoming.push(Object.assign(Object.assign({}, decryptedAsReceiver), { isSpent, position: i }));
|
|
100
|
-
}
|
|
101
|
-
if (decryptedAsSender) {
|
|
102
|
-
outgoing.push(decryptedAsSender);
|
|
103
|
-
}
|
|
66
|
+
async getIncomingAndOutgoingTransactionsRaw() {
|
|
67
|
+
const incoming = [];
|
|
68
|
+
const outgoing = [];
|
|
69
|
+
const { commitments_and_ciphertexts, nullifiers } = await this.getSaplingDiff();
|
|
70
|
+
for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
|
|
71
|
+
const decryptedAsReceiver = await this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
|
|
72
|
+
const decryptedAsSender = await this.decryptCiphertextAsSender(commitments_and_ciphertexts[i]);
|
|
73
|
+
if (decryptedAsReceiver) {
|
|
74
|
+
const balance = (0, helpers_1.convertValueToBigNumber)(decryptedAsReceiver.value);
|
|
75
|
+
const isSpent = await this.isSpent(decryptedAsReceiver.paymentAddress, balance.toString(), decryptedAsReceiver.randomCommitmentTrapdoor, i, nullifiers);
|
|
76
|
+
incoming.push({ ...decryptedAsReceiver, isSpent, position: i });
|
|
104
77
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
78
|
+
if (decryptedAsSender) {
|
|
79
|
+
outgoing.push(decryptedAsSender);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
incoming,
|
|
84
|
+
outgoing,
|
|
85
|
+
};
|
|
110
86
|
}
|
|
111
87
|
/**
|
|
112
|
-
*
|
|
88
|
+
* Retrieve all the incoming and outgoing decoded transactions associated with the configured viewing key
|
|
113
89
|
*
|
|
114
90
|
*/
|
|
115
|
-
getIncomingAndOutgoingTransactions() {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
var { isSpent } = _a, rest = __rest(_a, ["isSpent"]);
|
|
120
|
-
return Object.assign(Object.assign({}, (0, helpers_1.readableFormat)(rest)), { isSpent });
|
|
121
|
-
});
|
|
122
|
-
const outgoing = tx.outgoing.map((outgoingTx) => {
|
|
123
|
-
return (0, helpers_1.readableFormat)(outgoingTx);
|
|
124
|
-
});
|
|
125
|
-
return { incoming, outgoing };
|
|
91
|
+
async getIncomingAndOutgoingTransactions() {
|
|
92
|
+
const tx = await this.getIncomingAndOutgoingTransactionsRaw();
|
|
93
|
+
const incoming = tx.incoming.map(({ isSpent, ...rest }) => {
|
|
94
|
+
return { ...(0, helpers_1.readableFormat)(rest), isSpent };
|
|
126
95
|
});
|
|
96
|
+
const outgoing = tx.outgoing.map((outgoingTx) => {
|
|
97
|
+
return (0, helpers_1.readableFormat)(outgoingTx);
|
|
98
|
+
});
|
|
99
|
+
return { incoming, outgoing };
|
|
127
100
|
}
|
|
128
|
-
getSaplingDiff() {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
101
|
+
async getSaplingDiff() {
|
|
102
|
+
let saplingDiffResponse;
|
|
103
|
+
if (__classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").saplingId) {
|
|
104
|
+
saplingDiffResponse = await __classPrivateFieldGet(this, _SaplingTransactionViewer_readProvider, "f").getSaplingDiffById({ id: __classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").saplingId }, 'head');
|
|
105
|
+
}
|
|
106
|
+
else if (__classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").contractAddress) {
|
|
107
|
+
saplingDiffResponse = await __classPrivateFieldGet(this, _SaplingTransactionViewer_readProvider, "f").getSaplingDiffByContract(__classPrivateFieldGet(this, _SaplingTransactionViewer_saplingContractId, "f").contractAddress, 'head');
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
throw new errors_1.SaplingTransactionViewerError('A contract address or a sapling id was expected in the SaplingTransactionViewer constructor.');
|
|
111
|
+
}
|
|
112
|
+
return saplingDiffResponse;
|
|
113
|
+
}
|
|
114
|
+
async decryptCiphertextAsReceiver(commitmentsAndCiphertexts) {
|
|
115
|
+
const commitment = commitmentsAndCiphertexts[0];
|
|
116
|
+
const { epk, payload_enc, nonce_enc } = commitmentsAndCiphertexts[1];
|
|
117
|
+
const incomingViewingKey = await __classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getIncomingViewingKey();
|
|
118
|
+
const keyAgreement = await sapling.keyAgreement(epk, incomingViewingKey);
|
|
119
|
+
const keyAgreementHash = blakejs_1.default.blake2b(keyAgreement, Buffer.from(constants_1.KDF_KEY), 32);
|
|
120
|
+
const decrypted = await this.decryptCiphertext(keyAgreementHash, (0, utils_1.hex2buf)(nonce_enc), (0, utils_1.hex2buf)(payload_enc));
|
|
121
|
+
if (decrypted) {
|
|
122
|
+
const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decrypted);
|
|
123
|
+
const paymentAddress = (0, helpers_1.bufToUint8Array)(await sapling.getRawPaymentAddressFromIncomingViewingKey(incomingViewingKey, diversifier));
|
|
124
|
+
try {
|
|
125
|
+
const valid = await sapling.verifyCommitment(commitment, paymentAddress, (0, helpers_1.convertValueToBigNumber)(value).toString(), rcm);
|
|
126
|
+
if (valid) {
|
|
127
|
+
return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
|
|
128
|
+
}
|
|
136
129
|
}
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
catch (ex) {
|
|
131
|
+
if (!/invalid value/.test(ex)) {
|
|
132
|
+
throw ex;
|
|
133
|
+
}
|
|
139
134
|
}
|
|
140
|
-
|
|
141
|
-
});
|
|
135
|
+
}
|
|
142
136
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
137
|
+
async decryptCiphertextAsSender(commitmentsAndCiphertexts) {
|
|
138
|
+
const commitment = commitmentsAndCiphertexts[0];
|
|
139
|
+
const { epk, payload_enc, nonce_enc, payload_out, nonce_out, cv } = commitmentsAndCiphertexts[1];
|
|
140
|
+
const outgoingViewingKey = await __classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getOutgoingViewingKey();
|
|
141
|
+
const concat = cv.concat(commitment, epk, outgoingViewingKey.toString('hex'));
|
|
142
|
+
const outgoingCipherKey = blakejs_1.default.blake2b(Buffer.from(concat, 'hex'), Buffer.from(constants_1.OCK_KEY), 32);
|
|
143
|
+
const decryptedOut = await this.decryptCiphertext(outgoingCipherKey, (0, utils_1.hex2buf)(nonce_out), (0, utils_1.hex2buf)(payload_out));
|
|
144
|
+
if (decryptedOut) {
|
|
145
|
+
const { recipientDiversifiedTransmissionKey: pkd, ephemeralPrivateKey: esk } = this.extractPkdAndEsk(decryptedOut);
|
|
146
|
+
const keyAgreement = await sapling.keyAgreement(pkd, esk);
|
|
149
147
|
const keyAgreementHash = blakejs_1.default.blake2b(keyAgreement, Buffer.from(constants_1.KDF_KEY), 32);
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
-
const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(
|
|
153
|
-
const paymentAddress = (0,
|
|
148
|
+
const decryptedEnc = await this.decryptCiphertext(keyAgreementHash, (0, utils_1.hex2buf)(nonce_enc), (0, utils_1.hex2buf)(payload_enc));
|
|
149
|
+
if (decryptedEnc) {
|
|
150
|
+
const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decryptedEnc);
|
|
151
|
+
const paymentAddress = (0, utils_1.mergebuf)(diversifier, pkd);
|
|
154
152
|
try {
|
|
155
|
-
const
|
|
156
|
-
if (
|
|
153
|
+
const isValid = await sapling.verifyCommitment(commitment, paymentAddress, (0, helpers_1.convertValueToBigNumber)(value).toString(), rcm);
|
|
154
|
+
if (isValid) {
|
|
157
155
|
return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
|
|
158
156
|
}
|
|
159
157
|
}
|
|
@@ -163,43 +161,10 @@ class SaplingTransactionViewer {
|
|
|
163
161
|
}
|
|
164
162
|
}
|
|
165
163
|
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
decryptCiphertextAsSender(commitmentsAndCiphertexts) {
|
|
169
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
-
const commitment = commitmentsAndCiphertexts[0];
|
|
171
|
-
const { epk, payload_enc, nonce_enc, payload_out, nonce_out, cv } = commitmentsAndCiphertexts[1];
|
|
172
|
-
const outgoingViewingKey = yield __classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getOutgoingViewingKey();
|
|
173
|
-
const concat = cv.concat(commitment, epk, outgoingViewingKey.toString('hex'));
|
|
174
|
-
const outgoingCipherKey = blakejs_1.default.blake2b(Buffer.from(concat, 'hex'), Buffer.from(constants_1.OCK_KEY), 32);
|
|
175
|
-
const decryptedOut = yield this.decryptCiphertext(outgoingCipherKey, (0, utils_1.hex2buf)(nonce_out), (0, utils_1.hex2buf)(payload_out));
|
|
176
|
-
if (decryptedOut) {
|
|
177
|
-
const { recipientDiversifiedTransmissionKey: pkd, ephemeralPrivateKey: esk } = this.extractPkdAndEsk(decryptedOut);
|
|
178
|
-
const keyAgreement = yield sapling.keyAgreement(pkd, esk);
|
|
179
|
-
const keyAgreementHash = blakejs_1.default.blake2b(keyAgreement, Buffer.from(constants_1.KDF_KEY), 32);
|
|
180
|
-
const decryptedEnc = yield this.decryptCiphertext(keyAgreementHash, (0, utils_1.hex2buf)(nonce_enc), (0, utils_1.hex2buf)(payload_enc));
|
|
181
|
-
if (decryptedEnc) {
|
|
182
|
-
const { diversifier, value, randomCommitmentTrapdoor: rcm, memo, } = this.extractTransactionProperties(decryptedEnc);
|
|
183
|
-
const paymentAddress = (0, utils_1.mergebuf)(diversifier, pkd);
|
|
184
|
-
try {
|
|
185
|
-
const isValid = yield sapling.verifyCommitment(commitment, paymentAddress, (0, helpers_1.convertValueToBigNumber)(value).toString(), rcm);
|
|
186
|
-
if (isValid) {
|
|
187
|
-
return { value, memo, paymentAddress, randomCommitmentTrapdoor: rcm };
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
catch (ex) {
|
|
191
|
-
if (!/invalid value/.test(ex)) {
|
|
192
|
-
throw ex;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
});
|
|
164
|
+
}
|
|
198
165
|
}
|
|
199
|
-
decryptCiphertext(keyAgreementHash, nonce, payload) {
|
|
200
|
-
return
|
|
201
|
-
return (0, nacl_1.openSecretBox)(keyAgreementHash, nonce, payload);
|
|
202
|
-
});
|
|
166
|
+
async decryptCiphertext(keyAgreementHash, nonce, payload) {
|
|
167
|
+
return (0, nacl_1.openSecretBox)(keyAgreementHash, nonce, payload);
|
|
203
168
|
}
|
|
204
169
|
extractTransactionProperties(decrypted) {
|
|
205
170
|
return {
|
|
@@ -216,11 +181,9 @@ class SaplingTransactionViewer {
|
|
|
216
181
|
ephemeralPrivateKey: decrypted.slice(32),
|
|
217
182
|
};
|
|
218
183
|
}
|
|
219
|
-
isSpent(address, value, randomCommitmentTrapdoor, position, nullifiers) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return nullifiers.includes(computedNullifier.toString('hex'));
|
|
223
|
-
});
|
|
184
|
+
async isSpent(address, value, randomCommitmentTrapdoor, position, nullifiers) {
|
|
185
|
+
const computedNullifier = await sapling.computeNullifier(__classPrivateFieldGet(this, _SaplingTransactionViewer_viewingKeyProvider, "f").getFullViewingKey(), address, value, randomCommitmentTrapdoor, position);
|
|
186
|
+
return nullifiers.includes(computedNullifier.toString('hex'));
|
|
224
187
|
}
|
|
225
188
|
}
|
|
226
189
|
exports.SaplingTransactionViewer = SaplingTransactionViewer;
|
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
* @module @taquito/sapling
|
|
5
5
|
*/
|
|
6
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
6
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
16
7
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
17
8
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
@@ -23,17 +14,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
23
14
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
24
15
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
25
16
|
};
|
|
26
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
27
|
-
var t = {};
|
|
28
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
29
|
-
t[p] = s[p];
|
|
30
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
31
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
32
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
33
|
-
t[p[i]] = s[p[i]];
|
|
34
|
-
}
|
|
35
|
-
return t;
|
|
36
|
-
};
|
|
37
17
|
var _SaplingToolkit_inMemorySpendingKey, _SaplingToolkit_saplingId, _SaplingToolkit_contractAddress, _SaplingToolkit_memoSize, _SaplingToolkit_readProvider, _SaplingToolkit_packer, _SaplingToolkit_saplingForger, _SaplingToolkit_saplingTxBuilder, _SaplingToolkit_saplingTransactionViewer;
|
|
38
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
19
|
exports.SaplingToolkit = exports.InMemoryProvingKey = exports.InMemorySpendingKey = exports.InMemoryViewingKey = exports.SaplingTransactionViewer = void 0;
|
|
@@ -56,7 +36,7 @@ Object.defineProperty(exports, "InMemorySpendingKey", { enumerable: true, get: f
|
|
|
56
36
|
var in_memory_proving_key_1 = require("./sapling-keys/in-memory-proving-key");
|
|
57
37
|
Object.defineProperty(exports, "InMemoryProvingKey", { enumerable: true, get: function () { return in_memory_proving_key_1.InMemoryProvingKey; } });
|
|
58
38
|
/**
|
|
59
|
-
*
|
|
39
|
+
* Class that surfaces all of the sapling capability allowing to read from a sapling state and prepare transactions
|
|
60
40
|
*
|
|
61
41
|
* @param keys.saplingSigner Holds the sapling spending key
|
|
62
42
|
* @param keys.saplingProver (Optional) Allows to generate the proofs with the proving key rather than the spending key
|
|
@@ -98,104 +78,95 @@ class SaplingToolkit {
|
|
|
98
78
|
__classPrivateFieldSet(this, _SaplingToolkit_saplingTxBuilder, saplingTxBuilder, "f");
|
|
99
79
|
}
|
|
100
80
|
/**
|
|
101
|
-
*
|
|
81
|
+
* Get an instance of `SaplingTransactionViewer` which allows to retrieve and decrypt sapling transactions and calculate the unspent balance.
|
|
102
82
|
*/
|
|
103
|
-
getSaplingTransactionViewer() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return __classPrivateFieldGet(this, _SaplingToolkit_saplingTransactionViewer, "f");
|
|
112
|
-
});
|
|
83
|
+
async getSaplingTransactionViewer() {
|
|
84
|
+
let saplingTransactionViewer;
|
|
85
|
+
if (!__classPrivateFieldGet(this, _SaplingToolkit_saplingTransactionViewer, "f")) {
|
|
86
|
+
const saplingViewingKey = await __classPrivateFieldGet(this, _SaplingToolkit_inMemorySpendingKey, "f").getSaplingViewingKeyProvider();
|
|
87
|
+
saplingTransactionViewer = new sapling_transaction_viewer_1.SaplingTransactionViewer(saplingViewingKey, this.getSaplingContractId(), __classPrivateFieldGet(this, _SaplingToolkit_readProvider, "f"));
|
|
88
|
+
__classPrivateFieldSet(this, _SaplingToolkit_saplingTransactionViewer, saplingTransactionViewer, "f");
|
|
89
|
+
}
|
|
90
|
+
return __classPrivateFieldGet(this, _SaplingToolkit_saplingTransactionViewer, "f");
|
|
113
91
|
}
|
|
114
92
|
/**
|
|
115
|
-
*
|
|
93
|
+
* Prepare a shielded transaction
|
|
116
94
|
* @param shieldedTxParams `to` is the payment address that will receive the shielded tokens (zet).
|
|
117
95
|
* `amount` is the amount of shielded tokens in tez by default.
|
|
118
96
|
* `mutez` needs to be set to true if the amount of shielded tokens is in mutez.
|
|
119
97
|
* `memo` is an empty string by default.
|
|
120
98
|
* @returns a string representing the sapling transaction
|
|
121
99
|
*/
|
|
122
|
-
prepareShieldedTransaction(shieldedTxParams) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
signature,
|
|
134
|
-
});
|
|
135
|
-
return forgedSaplingTx.toString('hex');
|
|
100
|
+
async prepareShieldedTransaction(shieldedTxParams) {
|
|
101
|
+
const { formatedParams, totalAmount } = this.formatTransactionParams(shieldedTxParams, this.validateDestinationSaplingAddress);
|
|
102
|
+
const root = await this.getRoot();
|
|
103
|
+
const { inputs, outputs, signature, balance } = await __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createShieldedTx(formatedParams, totalAmount, constants_1.DEFAULT_BOUND_DATA);
|
|
104
|
+
const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
|
|
105
|
+
inputs,
|
|
106
|
+
outputs,
|
|
107
|
+
balance,
|
|
108
|
+
root,
|
|
109
|
+
boundData: constants_1.DEFAULT_BOUND_DATA,
|
|
110
|
+
signature,
|
|
136
111
|
});
|
|
112
|
+
return forgedSaplingTx.toString('hex');
|
|
137
113
|
}
|
|
138
114
|
/**
|
|
139
|
-
*
|
|
115
|
+
* Prepare an unshielded transaction
|
|
140
116
|
* @param unshieldedTxParams `to` is the Tezos address that will receive the unshielded tokens (tz1, tz2 or tz3).
|
|
141
117
|
* `amount` is the amount of unshielded tokens in tez by default.
|
|
142
118
|
* `mutez` needs to be set to true if the amount of unshielded tokens is in mutez.
|
|
143
119
|
* @returns a string representing the sapling transaction.
|
|
144
120
|
*/
|
|
145
|
-
prepareUnshieldedTransaction(unshieldedTxParams) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
signature,
|
|
159
|
-
});
|
|
160
|
-
return forgedSaplingTx.toString('hex');
|
|
121
|
+
async prepareUnshieldedTransaction(unshieldedTxParams) {
|
|
122
|
+
const { formatedParams, totalAmount } = this.formatTransactionParams([unshieldedTxParams], this.validateDestinationImplicitAddress);
|
|
123
|
+
const boundData = await this.createBoundData(formatedParams[0].to);
|
|
124
|
+
const root = await this.getRoot();
|
|
125
|
+
const chosenInputs = await this.selectInputsToSpend(new bignumber_js_1.default(formatedParams[0].amount));
|
|
126
|
+
const { inputs, outputs, signature, balance } = await __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createSaplingTx([], totalAmount, boundData, chosenInputs);
|
|
127
|
+
const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
|
|
128
|
+
inputs,
|
|
129
|
+
outputs,
|
|
130
|
+
balance,
|
|
131
|
+
root,
|
|
132
|
+
boundData,
|
|
133
|
+
signature,
|
|
161
134
|
});
|
|
135
|
+
return forgedSaplingTx.toString('hex');
|
|
162
136
|
}
|
|
163
137
|
/**
|
|
164
|
-
*
|
|
138
|
+
* Prepare a sapling transaction (zet to zet)
|
|
165
139
|
* @param saplingTxParams `to` is the payment address that will receive the shielded tokens (zet).
|
|
166
140
|
* `amount` is the amount of unshielded tokens in tez by default.
|
|
167
141
|
* `mutez` needs to be set to true if the amount of unshielded tokens is in mutez.
|
|
168
142
|
* `memo` is an empty string by default.
|
|
169
143
|
* @returns a string representing the sapling transaction.
|
|
170
144
|
*/
|
|
171
|
-
prepareSaplingTransaction(saplingTxParams) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
signature,
|
|
184
|
-
});
|
|
185
|
-
return forgedSaplingTx.toString('hex');
|
|
145
|
+
async prepareSaplingTransaction(saplingTxParams) {
|
|
146
|
+
const { formatedParams, totalAmount } = this.formatTransactionParams(saplingTxParams, this.validateDestinationSaplingAddress);
|
|
147
|
+
const root = await this.getRoot();
|
|
148
|
+
const chosenInputs = await this.selectInputsToSpend(totalAmount);
|
|
149
|
+
const { inputs, outputs, signature, balance } = await __classPrivateFieldGet(this, _SaplingToolkit_saplingTxBuilder, "f").createSaplingTx(formatedParams, totalAmount, constants_1.DEFAULT_BOUND_DATA, chosenInputs);
|
|
150
|
+
const forgedSaplingTx = __classPrivateFieldGet(this, _SaplingToolkit_saplingForger, "f").forgeSaplingTransaction({
|
|
151
|
+
inputs,
|
|
152
|
+
outputs,
|
|
153
|
+
balance,
|
|
154
|
+
root,
|
|
155
|
+
boundData: constants_1.DEFAULT_BOUND_DATA,
|
|
156
|
+
signature,
|
|
186
157
|
});
|
|
158
|
+
return forgedSaplingTx.toString('hex');
|
|
187
159
|
}
|
|
188
160
|
formatTransactionParams(txParams, validateDestination) {
|
|
189
161
|
const formatedParams = [];
|
|
190
162
|
let totalAmount = new bignumber_js_1.default(0);
|
|
191
163
|
txParams.forEach((param) => {
|
|
192
|
-
var _a;
|
|
193
164
|
validateDestination(param.to);
|
|
194
165
|
const amountMutez = param.mutez
|
|
195
166
|
? param.amount.toString()
|
|
196
167
|
: (0, utils_1.format)('tz', 'mutez', param.amount).toString();
|
|
197
168
|
totalAmount = totalAmount.plus(new bignumber_js_1.default(amountMutez));
|
|
198
|
-
const memo =
|
|
169
|
+
const memo = param.memo ?? constants_1.DEFAULT_MEMO;
|
|
199
170
|
if (memo.length > __classPrivateFieldGet(this, _SaplingToolkit_memoSize, "f")) {
|
|
200
171
|
throw new errors_1.InvalidMemo(memo, `expecting length to be less than ${__classPrivateFieldGet(this, _SaplingToolkit_memoSize, "f")}`);
|
|
201
172
|
}
|
|
@@ -203,27 +174,23 @@ class SaplingToolkit {
|
|
|
203
174
|
});
|
|
204
175
|
return { formatedParams, totalAmount };
|
|
205
176
|
}
|
|
206
|
-
getRoot() {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
});
|
|
177
|
+
async getRoot() {
|
|
178
|
+
if (__classPrivateFieldGet(this, _SaplingToolkit_saplingId, "f")) {
|
|
179
|
+
const { root } = await __classPrivateFieldGet(this, _SaplingToolkit_readProvider, "f").getSaplingDiffById({ id: __classPrivateFieldGet(this, _SaplingToolkit_saplingId, "f") }, 'head');
|
|
180
|
+
return root;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
const { root } = await __classPrivateFieldGet(this, _SaplingToolkit_readProvider, "f").getSaplingDiffByContract(__classPrivateFieldGet(this, _SaplingToolkit_contractAddress, "f"), 'head');
|
|
184
|
+
return root;
|
|
185
|
+
}
|
|
217
186
|
}
|
|
218
|
-
createBoundData(destination) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
type: { prim: 'bytes' },
|
|
224
|
-
});
|
|
225
|
-
return Buffer.from(packedDestination.packed, 'hex');
|
|
187
|
+
async createBoundData(destination) {
|
|
188
|
+
const bytes = (0, utils_1.b58DecodePublicKeyHash)(destination, 'hex');
|
|
189
|
+
const packedDestination = await __classPrivateFieldGet(this, _SaplingToolkit_packer, "f").packData({
|
|
190
|
+
data: { bytes },
|
|
191
|
+
type: { prim: 'bytes' },
|
|
226
192
|
});
|
|
193
|
+
return Buffer.from(packedDestination.packed, 'hex');
|
|
227
194
|
}
|
|
228
195
|
validateDestinationImplicitAddress(to) {
|
|
229
196
|
const toValidation = (0, utils_1.validateKeyHash)(to);
|
|
@@ -235,7 +202,7 @@ class SaplingToolkit {
|
|
|
235
202
|
try {
|
|
236
203
|
(0, utils_1.b58DecodeAndCheckPrefix)(to, [utils_1.PrefixV2.SaplingAddress]);
|
|
237
204
|
}
|
|
238
|
-
catch
|
|
205
|
+
catch {
|
|
239
206
|
throw new core_1.InvalidAddressError(to, `expecting prefix ${utils_1.PrefixV2.SaplingAddress}.`);
|
|
240
207
|
}
|
|
241
208
|
}
|
|
@@ -249,25 +216,23 @@ class SaplingToolkit {
|
|
|
249
216
|
}
|
|
250
217
|
return saplingContractId;
|
|
251
218
|
}
|
|
252
|
-
selectInputsToSpend(amountMutez) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
inputsToSpend.push(rest);
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
if (sumSelectedInputs.isLessThan(new bignumber_js_1.default(amountMutez))) {
|
|
267
|
-
throw new errors_1.InsufficientBalance(sumSelectedInputs.toString(), amountMutez.toString());
|
|
219
|
+
async selectInputsToSpend(amountMutez) {
|
|
220
|
+
const saplingTxViewer = await this.getSaplingTransactionViewer();
|
|
221
|
+
const { incoming } = await saplingTxViewer.getIncomingAndOutgoingTransactionsRaw();
|
|
222
|
+
const inputsToSpend = [];
|
|
223
|
+
let sumSelectedInputs = new bignumber_js_1.default(0);
|
|
224
|
+
incoming.forEach((input) => {
|
|
225
|
+
if (!input.isSpent && sumSelectedInputs.isLessThan(amountMutez)) {
|
|
226
|
+
const txAmount = (0, helpers_1.convertValueToBigNumber)(input.value);
|
|
227
|
+
sumSelectedInputs = sumSelectedInputs.plus(txAmount);
|
|
228
|
+
const { isSpent: _isSpent, ...rest } = input;
|
|
229
|
+
inputsToSpend.push(rest);
|
|
268
230
|
}
|
|
269
|
-
return { inputsToSpend, sumSelectedInputs };
|
|
270
231
|
});
|
|
232
|
+
if (sumSelectedInputs.isLessThan(new bignumber_js_1.default(amountMutez))) {
|
|
233
|
+
throw new errors_1.InsufficientBalance(sumSelectedInputs.toString(), amountMutez.toString());
|
|
234
|
+
}
|
|
235
|
+
return { inputsToSpend, sumSelectedInputs };
|
|
271
236
|
}
|
|
272
237
|
}
|
|
273
238
|
exports.SaplingToolkit = SaplingToolkit;
|
package/dist/lib/version.js
CHANGED
|
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VERSION = void 0;
|
|
4
4
|
// IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT!
|
|
5
5
|
exports.VERSION = {
|
|
6
|
-
"commitHash": "
|
|
7
|
-
"version": "24.
|
|
6
|
+
"commitHash": "27675679db6515e8b092195ef5c58c2c0ea5f5c8",
|
|
7
|
+
"version": "24.3.0-beta.0"
|
|
8
8
|
};
|