@solana/web3.js 0.0.0-development → 0.0.0-pr-29130
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/README.md +18 -16
- package/lib/index.browser.cjs.js +1955 -1660
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +2058 -1770
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +4733 -1870
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +3451 -2821
- package/lib/index.esm.js +4761 -1909
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +5212 -5553
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +7 -14
- package/lib/index.iife.min.js.map +1 -1
- package/lib/index.native.js +1955 -1660
- package/lib/index.native.js.map +1 -1
- package/package.json +18 -21
- package/src/account.ts +19 -10
- package/src/bpf-loader.ts +2 -2
- package/src/connection.ts +1377 -185
- package/src/epoch-schedule.ts +1 -1
- package/src/keypair.ts +20 -25
- package/src/layout.ts +29 -0
- package/src/message/account-keys.ts +79 -0
- package/src/message/compiled-keys.ts +165 -0
- package/src/message/index.ts +21 -6
- package/src/message/legacy.ts +103 -16
- package/src/message/v0.ts +496 -0
- package/src/message/versioned.ts +36 -0
- package/src/nonce-account.ts +7 -3
- package/src/programs/address-lookup-table/state.ts +1 -1
- package/src/programs/compute-budget.ts +3 -0
- package/src/programs/ed25519.ts +2 -2
- package/src/programs/secp256k1.ts +5 -7
- package/src/programs/vote.ts +109 -2
- package/src/publickey.ts +25 -73
- package/src/transaction/constants.ts +2 -0
- package/src/transaction/expiry-custom-errors.ts +13 -0
- package/src/transaction/index.ts +2 -0
- package/src/transaction/legacy.ts +46 -9
- package/src/transaction/message.ts +140 -0
- package/src/transaction/versioned.ts +126 -0
- package/src/utils/ed25519.ts +46 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/send-and-confirm-raw-transaction.ts +13 -0
- package/src/utils/send-and-confirm-transaction.ts +53 -19
- package/src/agent-manager.ts +0 -44
package/lib/index.browser.cjs.js
CHANGED
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var nacl = require('tweetnacl');
|
|
6
5
|
var buffer = require('buffer');
|
|
6
|
+
var sha512 = require('@noble/hashes/sha512');
|
|
7
|
+
var ed25519 = require('@noble/ed25519');
|
|
7
8
|
var BN = require('bn.js');
|
|
8
9
|
var bs58 = require('bs58');
|
|
10
|
+
var sha256 = require('@noble/hashes/sha256');
|
|
9
11
|
var borsh = require('borsh');
|
|
10
12
|
var BufferLayout = require('@solana/buffer-layout');
|
|
11
13
|
var bigintBuffer = require('bigint-buffer');
|
|
12
14
|
var superstruct = require('superstruct');
|
|
13
15
|
var rpcWebsockets = require('rpc-websockets');
|
|
14
16
|
var RpcClient = require('jayson/lib/client/browser');
|
|
15
|
-
var sha3 = require('
|
|
17
|
+
var sha3 = require('@noble/hashes/sha3');
|
|
18
|
+
var hmac = require('@noble/hashes/hmac');
|
|
19
|
+
var secp256k1 = require('@noble/secp256k1');
|
|
16
20
|
|
|
17
21
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
18
22
|
|
|
@@ -34,12 +38,46 @@ function _interopNamespace(e) {
|
|
|
34
38
|
return Object.freeze(n);
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
var
|
|
41
|
+
var ed25519__namespace = /*#__PURE__*/_interopNamespace(ed25519);
|
|
38
42
|
var BN__default = /*#__PURE__*/_interopDefaultLegacy(BN);
|
|
39
43
|
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
40
44
|
var BufferLayout__namespace = /*#__PURE__*/_interopNamespace(BufferLayout);
|
|
41
45
|
var RpcClient__default = /*#__PURE__*/_interopDefaultLegacy(RpcClient);
|
|
42
|
-
var
|
|
46
|
+
var secp256k1__namespace = /*#__PURE__*/_interopNamespace(secp256k1);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A 64 byte secret key, the first 32 bytes of which is the
|
|
50
|
+
* private scalar and the last 32 bytes is the public key.
|
|
51
|
+
* Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
ed25519__namespace.utils.sha512Sync = (...m) => sha512.sha512(ed25519__namespace.utils.concatBytes(...m));
|
|
55
|
+
|
|
56
|
+
const generatePrivateKey = ed25519__namespace.utils.randomPrivateKey;
|
|
57
|
+
const generateKeypair = () => {
|
|
58
|
+
const privateScalar = ed25519__namespace.utils.randomPrivateKey();
|
|
59
|
+
const publicKey = getPublicKey(privateScalar);
|
|
60
|
+
const secretKey = new Uint8Array(64);
|
|
61
|
+
secretKey.set(privateScalar);
|
|
62
|
+
secretKey.set(publicKey, 32);
|
|
63
|
+
return {
|
|
64
|
+
publicKey,
|
|
65
|
+
secretKey
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const getPublicKey = ed25519__namespace.sync.getPublicKey;
|
|
69
|
+
function isOnCurve(publicKey) {
|
|
70
|
+
try {
|
|
71
|
+
ed25519__namespace.Point.fromHex(publicKey, true
|
|
72
|
+
/* strict */
|
|
73
|
+
);
|
|
74
|
+
return true;
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const sign = (message, secretKey) => ed25519__namespace.sync.sign(message, secretKey.slice(0, 32));
|
|
80
|
+
const verify = ed25519__namespace.sync.verify;
|
|
43
81
|
|
|
44
82
|
const toBuffer = arr => {
|
|
45
83
|
if (buffer.Buffer.isBuffer(arr)) {
|
|
@@ -51,298 +89,6 @@ const toBuffer = arr => {
|
|
|
51
89
|
}
|
|
52
90
|
};
|
|
53
91
|
|
|
54
|
-
function number(n) {
|
|
55
|
-
if (!Number.isSafeInteger(n) || n < 0)
|
|
56
|
-
throw new Error(`Wrong positive integer: ${n}`);
|
|
57
|
-
}
|
|
58
|
-
function bool(b) {
|
|
59
|
-
if (typeof b !== 'boolean')
|
|
60
|
-
throw new Error(`Expected boolean, not ${b}`);
|
|
61
|
-
}
|
|
62
|
-
function bytes(b, ...lengths) {
|
|
63
|
-
if (!(b instanceof Uint8Array))
|
|
64
|
-
throw new TypeError('Expected Uint8Array');
|
|
65
|
-
if (lengths.length > 0 && !lengths.includes(b.length))
|
|
66
|
-
throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
|
|
67
|
-
}
|
|
68
|
-
function hash(hash) {
|
|
69
|
-
if (typeof hash !== 'function' || typeof hash.create !== 'function')
|
|
70
|
-
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
|
71
|
-
number(hash.outputLen);
|
|
72
|
-
number(hash.blockLen);
|
|
73
|
-
}
|
|
74
|
-
function exists(instance, checkFinished = true) {
|
|
75
|
-
if (instance.destroyed)
|
|
76
|
-
throw new Error('Hash instance has been destroyed');
|
|
77
|
-
if (checkFinished && instance.finished)
|
|
78
|
-
throw new Error('Hash#digest() has already been called');
|
|
79
|
-
}
|
|
80
|
-
function output(out, instance) {
|
|
81
|
-
bytes(out);
|
|
82
|
-
const min = instance.outputLen;
|
|
83
|
-
if (out.length < min) {
|
|
84
|
-
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const assert$1 = {
|
|
88
|
-
number,
|
|
89
|
-
bool,
|
|
90
|
-
bytes,
|
|
91
|
-
hash,
|
|
92
|
-
exists,
|
|
93
|
-
output,
|
|
94
|
-
};
|
|
95
|
-
var assert$2 = assert$1;
|
|
96
|
-
|
|
97
|
-
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
98
|
-
// Cast array to view
|
|
99
|
-
const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
100
|
-
// The rotate right (circular right shift) operation for uint32
|
|
101
|
-
const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
|
|
102
|
-
const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
|
|
103
|
-
// There is almost no big endian hardware, but js typed arrays uses platform specific endianness.
|
|
104
|
-
// So, just to be sure not to corrupt anything.
|
|
105
|
-
if (!isLE)
|
|
106
|
-
throw new Error('Non little-endian hardware is not supported');
|
|
107
|
-
Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
|
108
|
-
function utf8ToBytes(str) {
|
|
109
|
-
if (typeof str !== 'string') {
|
|
110
|
-
throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
|
|
111
|
-
}
|
|
112
|
-
return new TextEncoder().encode(str);
|
|
113
|
-
}
|
|
114
|
-
function toBytes(data) {
|
|
115
|
-
if (typeof data === 'string')
|
|
116
|
-
data = utf8ToBytes(data);
|
|
117
|
-
if (!(data instanceof Uint8Array))
|
|
118
|
-
throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
|
|
119
|
-
return data;
|
|
120
|
-
}
|
|
121
|
-
// For runtime check if class implements interface
|
|
122
|
-
class Hash {
|
|
123
|
-
// Safe version that clones internal state
|
|
124
|
-
clone() {
|
|
125
|
-
return this._cloneInto();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function wrapConstructor(hashConstructor) {
|
|
129
|
-
const hashC = (message) => hashConstructor().update(toBytes(message)).digest();
|
|
130
|
-
const tmp = hashConstructor();
|
|
131
|
-
hashC.outputLen = tmp.outputLen;
|
|
132
|
-
hashC.blockLen = tmp.blockLen;
|
|
133
|
-
hashC.create = () => hashConstructor();
|
|
134
|
-
return hashC;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Polyfill for Safari 14
|
|
138
|
-
function setBigUint64(view, byteOffset, value, isLE) {
|
|
139
|
-
if (typeof view.setBigUint64 === 'function')
|
|
140
|
-
return view.setBigUint64(byteOffset, value, isLE);
|
|
141
|
-
const _32n = BigInt(32);
|
|
142
|
-
const _u32_max = BigInt(0xffffffff);
|
|
143
|
-
const wh = Number((value >> _32n) & _u32_max);
|
|
144
|
-
const wl = Number(value & _u32_max);
|
|
145
|
-
const h = isLE ? 4 : 0;
|
|
146
|
-
const l = isLE ? 0 : 4;
|
|
147
|
-
view.setUint32(byteOffset + h, wh, isLE);
|
|
148
|
-
view.setUint32(byteOffset + l, wl, isLE);
|
|
149
|
-
}
|
|
150
|
-
// Base SHA2 class (RFC 6234)
|
|
151
|
-
class SHA2 extends Hash {
|
|
152
|
-
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
153
|
-
super();
|
|
154
|
-
this.blockLen = blockLen;
|
|
155
|
-
this.outputLen = outputLen;
|
|
156
|
-
this.padOffset = padOffset;
|
|
157
|
-
this.isLE = isLE;
|
|
158
|
-
this.finished = false;
|
|
159
|
-
this.length = 0;
|
|
160
|
-
this.pos = 0;
|
|
161
|
-
this.destroyed = false;
|
|
162
|
-
this.buffer = new Uint8Array(blockLen);
|
|
163
|
-
this.view = createView(this.buffer);
|
|
164
|
-
}
|
|
165
|
-
update(data) {
|
|
166
|
-
assert$2.exists(this);
|
|
167
|
-
const { view, buffer, blockLen } = this;
|
|
168
|
-
data = toBytes(data);
|
|
169
|
-
const len = data.length;
|
|
170
|
-
for (let pos = 0; pos < len;) {
|
|
171
|
-
const take = Math.min(blockLen - this.pos, len - pos);
|
|
172
|
-
// Fast path: we have at least one block in input, cast it to view and process
|
|
173
|
-
if (take === blockLen) {
|
|
174
|
-
const dataView = createView(data);
|
|
175
|
-
for (; blockLen <= len - pos; pos += blockLen)
|
|
176
|
-
this.process(dataView, pos);
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
180
|
-
this.pos += take;
|
|
181
|
-
pos += take;
|
|
182
|
-
if (this.pos === blockLen) {
|
|
183
|
-
this.process(view, 0);
|
|
184
|
-
this.pos = 0;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
this.length += data.length;
|
|
188
|
-
this.roundClean();
|
|
189
|
-
return this;
|
|
190
|
-
}
|
|
191
|
-
digestInto(out) {
|
|
192
|
-
assert$2.exists(this);
|
|
193
|
-
assert$2.output(out, this);
|
|
194
|
-
this.finished = true;
|
|
195
|
-
// Padding
|
|
196
|
-
// We can avoid allocation of buffer for padding completely if it
|
|
197
|
-
// was previously not allocated here. But it won't change performance.
|
|
198
|
-
const { buffer, view, blockLen, isLE } = this;
|
|
199
|
-
let { pos } = this;
|
|
200
|
-
// append the bit '1' to the message
|
|
201
|
-
buffer[pos++] = 0b10000000;
|
|
202
|
-
this.buffer.subarray(pos).fill(0);
|
|
203
|
-
// we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
|
|
204
|
-
if (this.padOffset > blockLen - pos) {
|
|
205
|
-
this.process(view, 0);
|
|
206
|
-
pos = 0;
|
|
207
|
-
}
|
|
208
|
-
// Pad until full block byte with zeros
|
|
209
|
-
for (let i = pos; i < blockLen; i++)
|
|
210
|
-
buffer[i] = 0;
|
|
211
|
-
// Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
|
|
212
|
-
// You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
|
|
213
|
-
// So we just write lowest 64 bits of that value.
|
|
214
|
-
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
|
|
215
|
-
this.process(view, 0);
|
|
216
|
-
const oview = createView(out);
|
|
217
|
-
this.get().forEach((v, i) => oview.setUint32(4 * i, v, isLE));
|
|
218
|
-
}
|
|
219
|
-
digest() {
|
|
220
|
-
const { buffer, outputLen } = this;
|
|
221
|
-
this.digestInto(buffer);
|
|
222
|
-
const res = buffer.slice(0, outputLen);
|
|
223
|
-
this.destroy();
|
|
224
|
-
return res;
|
|
225
|
-
}
|
|
226
|
-
_cloneInto(to) {
|
|
227
|
-
to || (to = new this.constructor());
|
|
228
|
-
to.set(...this.get());
|
|
229
|
-
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
230
|
-
to.length = length;
|
|
231
|
-
to.pos = pos;
|
|
232
|
-
to.finished = finished;
|
|
233
|
-
to.destroyed = destroyed;
|
|
234
|
-
if (length % blockLen)
|
|
235
|
-
to.buffer.set(buffer);
|
|
236
|
-
return to;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Choice: a ? b : c
|
|
241
|
-
const Chi = (a, b, c) => (a & b) ^ (~a & c);
|
|
242
|
-
// Majority function, true if any two inpust is true
|
|
243
|
-
const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
|
|
244
|
-
// Round constants:
|
|
245
|
-
// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
|
|
246
|
-
// prettier-ignore
|
|
247
|
-
const SHA256_K = new Uint32Array([
|
|
248
|
-
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
249
|
-
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
250
|
-
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
251
|
-
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
252
|
-
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
253
|
-
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
254
|
-
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
255
|
-
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
256
|
-
]);
|
|
257
|
-
// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
|
|
258
|
-
// prettier-ignore
|
|
259
|
-
const IV = new Uint32Array([
|
|
260
|
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
|
261
|
-
]);
|
|
262
|
-
// Temporary buffer, not used to store anything between runs
|
|
263
|
-
// Named this way because it matches specification.
|
|
264
|
-
const SHA256_W = new Uint32Array(64);
|
|
265
|
-
class SHA256 extends SHA2 {
|
|
266
|
-
constructor() {
|
|
267
|
-
super(64, 32, 8, false);
|
|
268
|
-
// We cannot use array here since array allows indexing by variable
|
|
269
|
-
// which means optimizer/compiler cannot use registers.
|
|
270
|
-
this.A = IV[0] | 0;
|
|
271
|
-
this.B = IV[1] | 0;
|
|
272
|
-
this.C = IV[2] | 0;
|
|
273
|
-
this.D = IV[3] | 0;
|
|
274
|
-
this.E = IV[4] | 0;
|
|
275
|
-
this.F = IV[5] | 0;
|
|
276
|
-
this.G = IV[6] | 0;
|
|
277
|
-
this.H = IV[7] | 0;
|
|
278
|
-
}
|
|
279
|
-
get() {
|
|
280
|
-
const { A, B, C, D, E, F, G, H } = this;
|
|
281
|
-
return [A, B, C, D, E, F, G, H];
|
|
282
|
-
}
|
|
283
|
-
// prettier-ignore
|
|
284
|
-
set(A, B, C, D, E, F, G, H) {
|
|
285
|
-
this.A = A | 0;
|
|
286
|
-
this.B = B | 0;
|
|
287
|
-
this.C = C | 0;
|
|
288
|
-
this.D = D | 0;
|
|
289
|
-
this.E = E | 0;
|
|
290
|
-
this.F = F | 0;
|
|
291
|
-
this.G = G | 0;
|
|
292
|
-
this.H = H | 0;
|
|
293
|
-
}
|
|
294
|
-
process(view, offset) {
|
|
295
|
-
// Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
|
|
296
|
-
for (let i = 0; i < 16; i++, offset += 4)
|
|
297
|
-
SHA256_W[i] = view.getUint32(offset, false);
|
|
298
|
-
for (let i = 16; i < 64; i++) {
|
|
299
|
-
const W15 = SHA256_W[i - 15];
|
|
300
|
-
const W2 = SHA256_W[i - 2];
|
|
301
|
-
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
|
|
302
|
-
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
|
|
303
|
-
SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
|
|
304
|
-
}
|
|
305
|
-
// Compression function main loop, 64 rounds
|
|
306
|
-
let { A, B, C, D, E, F, G, H } = this;
|
|
307
|
-
for (let i = 0; i < 64; i++) {
|
|
308
|
-
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
309
|
-
const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
|
310
|
-
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
311
|
-
const T2 = (sigma0 + Maj(A, B, C)) | 0;
|
|
312
|
-
H = G;
|
|
313
|
-
G = F;
|
|
314
|
-
F = E;
|
|
315
|
-
E = (D + T1) | 0;
|
|
316
|
-
D = C;
|
|
317
|
-
C = B;
|
|
318
|
-
B = A;
|
|
319
|
-
A = (T1 + T2) | 0;
|
|
320
|
-
}
|
|
321
|
-
// Add the compressed chunk to the current hash value
|
|
322
|
-
A = (A + this.A) | 0;
|
|
323
|
-
B = (B + this.B) | 0;
|
|
324
|
-
C = (C + this.C) | 0;
|
|
325
|
-
D = (D + this.D) | 0;
|
|
326
|
-
E = (E + this.E) | 0;
|
|
327
|
-
F = (F + this.F) | 0;
|
|
328
|
-
G = (G + this.G) | 0;
|
|
329
|
-
H = (H + this.H) | 0;
|
|
330
|
-
this.set(A, B, C, D, E, F, G, H);
|
|
331
|
-
}
|
|
332
|
-
roundClean() {
|
|
333
|
-
SHA256_W.fill(0);
|
|
334
|
-
}
|
|
335
|
-
destroy() {
|
|
336
|
-
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
337
|
-
this.buffer.fill(0);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* SHA2-256 hash function
|
|
342
|
-
* @param message - data that would be hashed
|
|
343
|
-
*/
|
|
344
|
-
const sha256 = wrapConstructor(() => new SHA256());
|
|
345
|
-
|
|
346
92
|
class Struct {
|
|
347
93
|
constructor(properties) {
|
|
348
94
|
Object.assign(this, properties);
|
|
@@ -396,12 +142,14 @@ const PUBLIC_KEY_LENGTH = 32;
|
|
|
396
142
|
|
|
397
143
|
function isPublicKeyData(value) {
|
|
398
144
|
return value._bn !== undefined;
|
|
399
|
-
}
|
|
145
|
+
} // local counter used by PublicKey.unique()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
let uniquePublicKeyCounter = 1;
|
|
400
149
|
/**
|
|
401
150
|
* A public key
|
|
402
151
|
*/
|
|
403
152
|
|
|
404
|
-
|
|
405
153
|
class PublicKey extends Struct {
|
|
406
154
|
/** @internal */
|
|
407
155
|
|
|
@@ -429,13 +177,24 @@ class PublicKey extends Struct {
|
|
|
429
177
|
this._bn = new BN__default["default"](value);
|
|
430
178
|
}
|
|
431
179
|
|
|
432
|
-
if (this._bn.byteLength() >
|
|
180
|
+
if (this._bn.byteLength() > PUBLIC_KEY_LENGTH) {
|
|
433
181
|
throw new Error(`Invalid public key input`);
|
|
434
182
|
}
|
|
435
183
|
}
|
|
436
184
|
}
|
|
437
185
|
/**
|
|
438
|
-
*
|
|
186
|
+
* Returns a unique PublicKey for tests and benchmarks using a counter
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
static unique() {
|
|
191
|
+
const key = new PublicKey(uniquePublicKeyCounter);
|
|
192
|
+
uniquePublicKeyCounter += 1;
|
|
193
|
+
return new PublicKey(key.toBuffer());
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Default public key value. The base58-encoded string representation is all ones (as seen below)
|
|
197
|
+
* The underlying BN number is 32 bytes that are all zeros
|
|
439
198
|
*/
|
|
440
199
|
|
|
441
200
|
|
|
@@ -500,8 +259,8 @@ class PublicKey extends Struct {
|
|
|
500
259
|
|
|
501
260
|
static async createWithSeed(fromPublicKey, seed, programId) {
|
|
502
261
|
const buffer$1 = buffer.Buffer.concat([fromPublicKey.toBuffer(), buffer.Buffer.from(seed), programId.toBuffer()]);
|
|
503
|
-
const
|
|
504
|
-
return new PublicKey(
|
|
262
|
+
const publicKeyBytes = sha256.sha256(buffer$1);
|
|
263
|
+
return new PublicKey(publicKeyBytes);
|
|
505
264
|
}
|
|
506
265
|
/**
|
|
507
266
|
* Derive a program address from seeds and a program ID.
|
|
@@ -520,10 +279,9 @@ class PublicKey extends Struct {
|
|
|
520
279
|
buffer$1 = buffer.Buffer.concat([buffer$1, toBuffer(seed)]);
|
|
521
280
|
});
|
|
522
281
|
buffer$1 = buffer.Buffer.concat([buffer$1, programId.toBuffer(), buffer.Buffer.from('ProgramDerivedAddress')]);
|
|
523
|
-
const
|
|
524
|
-
let publicKeyBytes = new BN__default["default"](hash, 16).toArray(undefined, 32);
|
|
282
|
+
const publicKeyBytes = sha256.sha256(buffer$1);
|
|
525
283
|
|
|
526
|
-
if (
|
|
284
|
+
if (isOnCurve(publicKeyBytes)) {
|
|
527
285
|
throw new Error(`Invalid seeds, address must fall off the curve`);
|
|
528
286
|
}
|
|
529
287
|
|
|
@@ -532,6 +290,8 @@ class PublicKey extends Struct {
|
|
|
532
290
|
/**
|
|
533
291
|
* Async version of createProgramAddressSync
|
|
534
292
|
* For backwards compatibility
|
|
293
|
+
*
|
|
294
|
+
* @deprecated Use {@link createProgramAddressSync} instead
|
|
535
295
|
*/
|
|
536
296
|
|
|
537
297
|
/* eslint-disable require-await */
|
|
@@ -574,6 +334,8 @@ class PublicKey extends Struct {
|
|
|
574
334
|
/**
|
|
575
335
|
* Async version of findProgramAddressSync
|
|
576
336
|
* For backwards compatibility
|
|
337
|
+
*
|
|
338
|
+
* @deprecated Use {@link findProgramAddressSync} instead
|
|
577
339
|
*/
|
|
578
340
|
|
|
579
341
|
|
|
@@ -587,7 +349,7 @@ class PublicKey extends Struct {
|
|
|
587
349
|
|
|
588
350
|
static isOnCurve(pubkeyData) {
|
|
589
351
|
const pubkey = new PublicKey(pubkeyData);
|
|
590
|
-
return
|
|
352
|
+
return isOnCurve(pubkey.toBytes());
|
|
591
353
|
}
|
|
592
354
|
|
|
593
355
|
}
|
|
@@ -595,56 +357,7 @@ PublicKey.default = new PublicKey('11111111111111111111111111111111');
|
|
|
595
357
|
SOLANA_SCHEMA.set(PublicKey, {
|
|
596
358
|
kind: 'struct',
|
|
597
359
|
fields: [['_bn', 'u256']]
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
let naclLowLevel = nacl__default["default"].lowlevel; // Check that a pubkey is on the curve.
|
|
601
|
-
// This function and its dependents were sourced from:
|
|
602
|
-
// https://github.com/dchest/tweetnacl-js/blob/f1ec050ceae0861f34280e62498b1d3ed9c350c6/nacl.js#L792
|
|
603
|
-
|
|
604
|
-
function is_on_curve(p) {
|
|
605
|
-
var r = [naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf()];
|
|
606
|
-
var t = naclLowLevel.gf(),
|
|
607
|
-
chk = naclLowLevel.gf(),
|
|
608
|
-
num = naclLowLevel.gf(),
|
|
609
|
-
den = naclLowLevel.gf(),
|
|
610
|
-
den2 = naclLowLevel.gf(),
|
|
611
|
-
den4 = naclLowLevel.gf(),
|
|
612
|
-
den6 = naclLowLevel.gf();
|
|
613
|
-
naclLowLevel.set25519(r[2], gf1);
|
|
614
|
-
naclLowLevel.unpack25519(r[1], p);
|
|
615
|
-
naclLowLevel.S(num, r[1]);
|
|
616
|
-
naclLowLevel.M(den, num, naclLowLevel.D);
|
|
617
|
-
naclLowLevel.Z(num, num, r[2]);
|
|
618
|
-
naclLowLevel.A(den, r[2], den);
|
|
619
|
-
naclLowLevel.S(den2, den);
|
|
620
|
-
naclLowLevel.S(den4, den2);
|
|
621
|
-
naclLowLevel.M(den6, den4, den2);
|
|
622
|
-
naclLowLevel.M(t, den6, num);
|
|
623
|
-
naclLowLevel.M(t, t, den);
|
|
624
|
-
naclLowLevel.pow2523(t, t);
|
|
625
|
-
naclLowLevel.M(t, t, num);
|
|
626
|
-
naclLowLevel.M(t, t, den);
|
|
627
|
-
naclLowLevel.M(t, t, den);
|
|
628
|
-
naclLowLevel.M(r[0], t, den);
|
|
629
|
-
naclLowLevel.S(chk, r[0]);
|
|
630
|
-
naclLowLevel.M(chk, chk, den);
|
|
631
|
-
if (neq25519(chk, num)) naclLowLevel.M(r[0], r[0], I);
|
|
632
|
-
naclLowLevel.S(chk, r[0]);
|
|
633
|
-
naclLowLevel.M(chk, chk, den);
|
|
634
|
-
if (neq25519(chk, num)) return 0;
|
|
635
|
-
return 1;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
let gf1 = naclLowLevel.gf([1]);
|
|
639
|
-
let I = naclLowLevel.gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
|
|
640
|
-
|
|
641
|
-
function neq25519(a, b) {
|
|
642
|
-
var c = new Uint8Array(32),
|
|
643
|
-
d = new Uint8Array(32);
|
|
644
|
-
naclLowLevel.pack25519(c, a);
|
|
645
|
-
naclLowLevel.pack25519(d, b);
|
|
646
|
-
return naclLowLevel.crypto_verify_32(c, 0, d, 0);
|
|
647
|
-
}
|
|
360
|
+
});
|
|
648
361
|
|
|
649
362
|
/**
|
|
650
363
|
* An account key pair (public and secret keys).
|
|
@@ -655,6 +368,8 @@ function neq25519(a, b) {
|
|
|
655
368
|
class Account {
|
|
656
369
|
/** @internal */
|
|
657
370
|
|
|
371
|
+
/** @internal */
|
|
372
|
+
|
|
658
373
|
/**
|
|
659
374
|
* Create a new Account object
|
|
660
375
|
*
|
|
@@ -664,12 +379,21 @@ class Account {
|
|
|
664
379
|
* @param secretKey Secret key for the account
|
|
665
380
|
*/
|
|
666
381
|
constructor(secretKey) {
|
|
667
|
-
this.
|
|
382
|
+
this._publicKey = void 0;
|
|
383
|
+
this._secretKey = void 0;
|
|
668
384
|
|
|
669
385
|
if (secretKey) {
|
|
670
|
-
|
|
386
|
+
const secretKeyBuffer = toBuffer(secretKey);
|
|
387
|
+
|
|
388
|
+
if (secretKey.length !== 64) {
|
|
389
|
+
throw new Error('bad secret key size');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
this._publicKey = secretKeyBuffer.slice(32, 64);
|
|
393
|
+
this._secretKey = secretKeyBuffer.slice(0, 32);
|
|
671
394
|
} else {
|
|
672
|
-
this.
|
|
395
|
+
this._secretKey = toBuffer(generatePrivateKey());
|
|
396
|
+
this._publicKey = toBuffer(getPublicKey(this._secretKey));
|
|
673
397
|
}
|
|
674
398
|
}
|
|
675
399
|
/**
|
|
@@ -678,15 +402,17 @@ class Account {
|
|
|
678
402
|
|
|
679
403
|
|
|
680
404
|
get publicKey() {
|
|
681
|
-
return new PublicKey(this.
|
|
405
|
+
return new PublicKey(this._publicKey);
|
|
682
406
|
}
|
|
683
407
|
/**
|
|
684
|
-
* The **unencrypted** secret key for this account
|
|
408
|
+
* The **unencrypted** secret key for this account. The first 32 bytes
|
|
409
|
+
* is the private scalar and the last 32 bytes is the public key.
|
|
410
|
+
* Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
|
|
685
411
|
*/
|
|
686
412
|
|
|
687
413
|
|
|
688
414
|
get secretKey() {
|
|
689
|
-
return
|
|
415
|
+
return buffer.Buffer.concat([this._secretKey, this._publicKey], 64);
|
|
690
416
|
}
|
|
691
417
|
|
|
692
418
|
}
|
|
@@ -701,6 +427,7 @@ const BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey('BPFLoader111111111111111
|
|
|
701
427
|
* 8 bytes is the size of the fragment header
|
|
702
428
|
*/
|
|
703
429
|
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
430
|
+
const VERSION_PREFIX_MASK = 0x7f;
|
|
704
431
|
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
705
432
|
|
|
706
433
|
class TransactionExpiredBlockheightExceededError extends Error {
|
|
@@ -725,14 +452,96 @@ class TransactionExpiredTimeoutError extends Error {
|
|
|
725
452
|
Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
|
|
726
453
|
value: 'TransactionExpiredTimeoutError'
|
|
727
454
|
});
|
|
455
|
+
class TransactionExpiredNonceInvalidError extends Error {
|
|
456
|
+
constructor(signature) {
|
|
457
|
+
super(`Signature ${signature} has expired: the nonce is no longer valid.`);
|
|
458
|
+
this.signature = void 0;
|
|
459
|
+
this.signature = signature;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
}
|
|
463
|
+
Object.defineProperty(TransactionExpiredNonceInvalidError.prototype, 'name', {
|
|
464
|
+
value: 'TransactionExpiredNonceInvalidError'
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
class MessageAccountKeys {
|
|
468
|
+
constructor(staticAccountKeys, accountKeysFromLookups) {
|
|
469
|
+
this.staticAccountKeys = void 0;
|
|
470
|
+
this.accountKeysFromLookups = void 0;
|
|
471
|
+
this.staticAccountKeys = staticAccountKeys;
|
|
472
|
+
this.accountKeysFromLookups = accountKeysFromLookups;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
keySegments() {
|
|
476
|
+
const keySegments = [this.staticAccountKeys];
|
|
477
|
+
|
|
478
|
+
if (this.accountKeysFromLookups) {
|
|
479
|
+
keySegments.push(this.accountKeysFromLookups.writable);
|
|
480
|
+
keySegments.push(this.accountKeysFromLookups.readonly);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return keySegments;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
get(index) {
|
|
487
|
+
for (const keySegment of this.keySegments()) {
|
|
488
|
+
if (index < keySegment.length) {
|
|
489
|
+
return keySegment[index];
|
|
490
|
+
} else {
|
|
491
|
+
index -= keySegment.length;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
get length() {
|
|
499
|
+
return this.keySegments().flat().length;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
compileInstructions(instructions) {
|
|
503
|
+
// Bail early if any account indexes would overflow a u8
|
|
504
|
+
const U8_MAX = 255;
|
|
505
|
+
|
|
506
|
+
if (this.length > U8_MAX + 1) {
|
|
507
|
+
throw new Error('Account index overflow encountered during compilation');
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
const keyIndexMap = new Map();
|
|
511
|
+
this.keySegments().flat().forEach((key, index) => {
|
|
512
|
+
keyIndexMap.set(key.toBase58(), index);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
const findKeyIndex = key => {
|
|
516
|
+
const keyIndex = keyIndexMap.get(key.toBase58());
|
|
517
|
+
if (keyIndex === undefined) throw new Error('Encountered an unknown instruction account key during compilation');
|
|
518
|
+
return keyIndex;
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
return instructions.map(instruction => {
|
|
522
|
+
return {
|
|
523
|
+
programIdIndex: findKeyIndex(instruction.programId),
|
|
524
|
+
accountKeyIndexes: instruction.keys.map(meta => findKeyIndex(meta.pubkey)),
|
|
525
|
+
data: instruction.data
|
|
526
|
+
};
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
}
|
|
728
531
|
|
|
729
532
|
/**
|
|
730
533
|
* Layout for a public key
|
|
731
534
|
*/
|
|
732
|
-
|
|
733
535
|
const publicKey = (property = 'publicKey') => {
|
|
734
536
|
return BufferLayout__namespace.blob(32, property);
|
|
735
537
|
};
|
|
538
|
+
/**
|
|
539
|
+
* Layout for a signature
|
|
540
|
+
*/
|
|
541
|
+
|
|
542
|
+
const signature = (property = 'signature') => {
|
|
543
|
+
return BufferLayout__namespace.blob(64, property);
|
|
544
|
+
};
|
|
736
545
|
|
|
737
546
|
/**
|
|
738
547
|
* Layout for a Rust String type
|
|
@@ -786,6 +595,13 @@ const lockup = (property = 'lockup') => {
|
|
|
786
595
|
const voteInit = (property = 'voteInit') => {
|
|
787
596
|
return BufferLayout__namespace.struct([publicKey('nodePubkey'), publicKey('authorizedVoter'), publicKey('authorizedWithdrawer'), BufferLayout__namespace.u8('commission')], property);
|
|
788
597
|
};
|
|
598
|
+
/**
|
|
599
|
+
* Layout for a VoteAuthorizeWithSeedArgs object
|
|
600
|
+
*/
|
|
601
|
+
|
|
602
|
+
const voteAuthorizeWithSeedArgs = (property = 'voteAuthorizeWithSeedArgs') => {
|
|
603
|
+
return BufferLayout__namespace.struct([BufferLayout__namespace.u32('voteAuthorizationType'), publicKey('currentAuthorityDerivedKeyOwnerPubkey'), rustString('currentAuthorityDerivedKeySeed'), publicKey('newAuthorized')], property);
|
|
604
|
+
};
|
|
789
605
|
function getAlloc(type, fields) {
|
|
790
606
|
const getItemAlloc = item => {
|
|
791
607
|
if (item.span >= 0) {
|
|
@@ -798,6 +614,11 @@ function getAlloc(type, fields) {
|
|
|
798
614
|
if (Array.isArray(field)) {
|
|
799
615
|
return field.length * getItemAlloc(item.elementLayout);
|
|
800
616
|
}
|
|
617
|
+
} else if ('fields' in item) {
|
|
618
|
+
// This is a `Structure` whose size needs to be recursively measured.
|
|
619
|
+
return getAlloc({
|
|
620
|
+
layout: item
|
|
621
|
+
}, fields[item.property]);
|
|
801
622
|
} // Couldn't determine allocated size of layout
|
|
802
623
|
|
|
803
624
|
|
|
@@ -844,6 +665,129 @@ function encodeLength(bytes, len) {
|
|
|
844
665
|
}
|
|
845
666
|
}
|
|
846
667
|
|
|
668
|
+
function assert (condition, message) {
|
|
669
|
+
if (!condition) {
|
|
670
|
+
throw new Error(message || 'Assertion failed');
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
class CompiledKeys {
|
|
675
|
+
constructor(payer, keyMetaMap) {
|
|
676
|
+
this.payer = void 0;
|
|
677
|
+
this.keyMetaMap = void 0;
|
|
678
|
+
this.payer = payer;
|
|
679
|
+
this.keyMetaMap = keyMetaMap;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
static compile(instructions, payer) {
|
|
683
|
+
const keyMetaMap = new Map();
|
|
684
|
+
|
|
685
|
+
const getOrInsertDefault = pubkey => {
|
|
686
|
+
const address = pubkey.toBase58();
|
|
687
|
+
let keyMeta = keyMetaMap.get(address);
|
|
688
|
+
|
|
689
|
+
if (keyMeta === undefined) {
|
|
690
|
+
keyMeta = {
|
|
691
|
+
isSigner: false,
|
|
692
|
+
isWritable: false,
|
|
693
|
+
isInvoked: false
|
|
694
|
+
};
|
|
695
|
+
keyMetaMap.set(address, keyMeta);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return keyMeta;
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
const payerKeyMeta = getOrInsertDefault(payer);
|
|
702
|
+
payerKeyMeta.isSigner = true;
|
|
703
|
+
payerKeyMeta.isWritable = true;
|
|
704
|
+
|
|
705
|
+
for (const ix of instructions) {
|
|
706
|
+
getOrInsertDefault(ix.programId).isInvoked = true;
|
|
707
|
+
|
|
708
|
+
for (const accountMeta of ix.keys) {
|
|
709
|
+
const keyMeta = getOrInsertDefault(accountMeta.pubkey);
|
|
710
|
+
keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
|
|
711
|
+
keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return new CompiledKeys(payer, keyMetaMap);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
getMessageComponents() {
|
|
719
|
+
const mapEntries = [...this.keyMetaMap.entries()];
|
|
720
|
+
assert(mapEntries.length <= 256, 'Max static account keys length exceeded');
|
|
721
|
+
const writableSigners = mapEntries.filter(([, meta]) => meta.isSigner && meta.isWritable);
|
|
722
|
+
const readonlySigners = mapEntries.filter(([, meta]) => meta.isSigner && !meta.isWritable);
|
|
723
|
+
const writableNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && meta.isWritable);
|
|
724
|
+
const readonlyNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && !meta.isWritable);
|
|
725
|
+
const header = {
|
|
726
|
+
numRequiredSignatures: writableSigners.length + readonlySigners.length,
|
|
727
|
+
numReadonlySignedAccounts: readonlySigners.length,
|
|
728
|
+
numReadonlyUnsignedAccounts: readonlyNonSigners.length
|
|
729
|
+
}; // sanity checks
|
|
730
|
+
|
|
731
|
+
{
|
|
732
|
+
assert(writableSigners.length > 0, 'Expected at least one writable signer key');
|
|
733
|
+
const [payerAddress] = writableSigners[0];
|
|
734
|
+
assert(payerAddress === this.payer.toBase58(), 'Expected first writable signer key to be the fee payer');
|
|
735
|
+
}
|
|
736
|
+
const staticAccountKeys = [...writableSigners.map(([address]) => new PublicKey(address)), ...readonlySigners.map(([address]) => new PublicKey(address)), ...writableNonSigners.map(([address]) => new PublicKey(address)), ...readonlyNonSigners.map(([address]) => new PublicKey(address))];
|
|
737
|
+
return [header, staticAccountKeys];
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
extractTableLookup(lookupTable) {
|
|
741
|
+
const [writableIndexes, drainedWritableKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && keyMeta.isWritable);
|
|
742
|
+
const [readonlyIndexes, drainedReadonlyKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && !keyMeta.isWritable); // Don't extract lookup if no keys were found
|
|
743
|
+
|
|
744
|
+
if (writableIndexes.length === 0 && readonlyIndexes.length === 0) {
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
return [{
|
|
749
|
+
accountKey: lookupTable.key,
|
|
750
|
+
writableIndexes,
|
|
751
|
+
readonlyIndexes
|
|
752
|
+
}, {
|
|
753
|
+
writable: drainedWritableKeys,
|
|
754
|
+
readonly: drainedReadonlyKeys
|
|
755
|
+
}];
|
|
756
|
+
}
|
|
757
|
+
/** @internal */
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
drainKeysFoundInLookupTable(lookupTableEntries, keyMetaFilter) {
|
|
761
|
+
const lookupTableIndexes = new Array();
|
|
762
|
+
const drainedKeys = new Array();
|
|
763
|
+
|
|
764
|
+
for (const [address, keyMeta] of this.keyMetaMap.entries()) {
|
|
765
|
+
if (keyMetaFilter(keyMeta)) {
|
|
766
|
+
const key = new PublicKey(address);
|
|
767
|
+
const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
|
|
768
|
+
|
|
769
|
+
if (lookupTableIndex >= 0) {
|
|
770
|
+
assert(lookupTableIndex < 256, 'Max lookup table index exceeded');
|
|
771
|
+
lookupTableIndexes.push(lookupTableIndex);
|
|
772
|
+
drainedKeys.push(key);
|
|
773
|
+
this.keyMetaMap.delete(address);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
return [lookupTableIndexes, drainedKeys];
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* An instruction to execute by a program
|
|
785
|
+
*
|
|
786
|
+
* @property {number} programIdIndex
|
|
787
|
+
* @property {number[]} accounts
|
|
788
|
+
* @property {string} data
|
|
789
|
+
*/
|
|
790
|
+
|
|
847
791
|
/**
|
|
848
792
|
* List of instructions to be processed atomically
|
|
849
793
|
*/
|
|
@@ -861,12 +805,63 @@ class Message {
|
|
|
861
805
|
this.instructions.forEach(ix => this.indexToProgramIds.set(ix.programIdIndex, this.accountKeys[ix.programIdIndex]));
|
|
862
806
|
}
|
|
863
807
|
|
|
808
|
+
get version() {
|
|
809
|
+
return 'legacy';
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
get staticAccountKeys() {
|
|
813
|
+
return this.accountKeys;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
get compiledInstructions() {
|
|
817
|
+
return this.instructions.map(ix => ({
|
|
818
|
+
programIdIndex: ix.programIdIndex,
|
|
819
|
+
accountKeyIndexes: ix.accounts,
|
|
820
|
+
data: bs58__default["default"].decode(ix.data)
|
|
821
|
+
}));
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
get addressTableLookups() {
|
|
825
|
+
return [];
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
getAccountKeys() {
|
|
829
|
+
return new MessageAccountKeys(this.staticAccountKeys);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
static compile(args) {
|
|
833
|
+
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
|
|
834
|
+
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
|
|
835
|
+
const accountKeys = new MessageAccountKeys(staticAccountKeys);
|
|
836
|
+
const instructions = accountKeys.compileInstructions(args.instructions).map(ix => ({
|
|
837
|
+
programIdIndex: ix.programIdIndex,
|
|
838
|
+
accounts: ix.accountKeyIndexes,
|
|
839
|
+
data: bs58__default["default"].encode(ix.data)
|
|
840
|
+
}));
|
|
841
|
+
return new Message({
|
|
842
|
+
header,
|
|
843
|
+
accountKeys: staticAccountKeys,
|
|
844
|
+
recentBlockhash: args.recentBlockhash,
|
|
845
|
+
instructions
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
|
|
864
849
|
isAccountSigner(index) {
|
|
865
850
|
return index < this.header.numRequiredSignatures;
|
|
866
851
|
}
|
|
867
852
|
|
|
868
853
|
isAccountWritable(index) {
|
|
869
|
-
|
|
854
|
+
const numSignedAccounts = this.header.numRequiredSignatures;
|
|
855
|
+
|
|
856
|
+
if (index >= this.header.numRequiredSignatures) {
|
|
857
|
+
const unsignedAccountIndex = index - numSignedAccounts;
|
|
858
|
+
const numUnsignedAccounts = this.accountKeys.length - numSignedAccounts;
|
|
859
|
+
const numWritableUnsignedAccounts = numUnsignedAccounts - this.header.numReadonlyUnsignedAccounts;
|
|
860
|
+
return unsignedAccountIndex < numWritableUnsignedAccounts;
|
|
861
|
+
} else {
|
|
862
|
+
const numWritableSignedAccounts = numSignedAccounts - this.header.numReadonlySignedAccounts;
|
|
863
|
+
return index < numWritableSignedAccounts;
|
|
864
|
+
}
|
|
870
865
|
}
|
|
871
866
|
|
|
872
867
|
isProgramId(index) {
|
|
@@ -937,6 +932,11 @@ class Message {
|
|
|
937
932
|
// Slice up wire data
|
|
938
933
|
let byteArray = [...buffer$1];
|
|
939
934
|
const numRequiredSignatures = byteArray.shift();
|
|
935
|
+
|
|
936
|
+
if (numRequiredSignatures !== (numRequiredSignatures & VERSION_PREFIX_MASK)) {
|
|
937
|
+
throw new Error('Versioned messages must be deserialized with VersionedMessage.deserialize()');
|
|
938
|
+
}
|
|
939
|
+
|
|
940
940
|
const numReadonlySignedAccounts = byteArray.shift();
|
|
941
941
|
const numReadonlyUnsignedAccounts = byteArray.shift();
|
|
942
942
|
const accountCount = decodeLength(byteArray);
|
|
@@ -945,7 +945,7 @@ class Message {
|
|
|
945
945
|
for (let i = 0; i < accountCount; i++) {
|
|
946
946
|
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
947
947
|
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
948
|
-
accountKeys.push(
|
|
948
|
+
accountKeys.push(new PublicKey(buffer.Buffer.from(account)));
|
|
949
949
|
}
|
|
950
950
|
|
|
951
951
|
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
@@ -984,12 +984,313 @@ class Message {
|
|
|
984
984
|
|
|
985
985
|
}
|
|
986
986
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
987
|
+
/**
|
|
988
|
+
* Message constructor arguments
|
|
989
|
+
*/
|
|
990
|
+
|
|
991
|
+
class MessageV0 {
|
|
992
|
+
constructor(args) {
|
|
993
|
+
this.header = void 0;
|
|
994
|
+
this.staticAccountKeys = void 0;
|
|
995
|
+
this.recentBlockhash = void 0;
|
|
996
|
+
this.compiledInstructions = void 0;
|
|
997
|
+
this.addressTableLookups = void 0;
|
|
998
|
+
this.header = args.header;
|
|
999
|
+
this.staticAccountKeys = args.staticAccountKeys;
|
|
1000
|
+
this.recentBlockhash = args.recentBlockhash;
|
|
1001
|
+
this.compiledInstructions = args.compiledInstructions;
|
|
1002
|
+
this.addressTableLookups = args.addressTableLookups;
|
|
990
1003
|
}
|
|
1004
|
+
|
|
1005
|
+
get version() {
|
|
1006
|
+
return 0;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
get numAccountKeysFromLookups() {
|
|
1010
|
+
let count = 0;
|
|
1011
|
+
|
|
1012
|
+
for (const lookup of this.addressTableLookups) {
|
|
1013
|
+
count += lookup.readonlyIndexes.length + lookup.writableIndexes.length;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
return count;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
getAccountKeys(args) {
|
|
1020
|
+
let accountKeysFromLookups;
|
|
1021
|
+
|
|
1022
|
+
if (args && 'accountKeysFromLookups' in args && args.accountKeysFromLookups) {
|
|
1023
|
+
if (this.numAccountKeysFromLookups != args.accountKeysFromLookups.writable.length + args.accountKeysFromLookups.readonly.length) {
|
|
1024
|
+
throw new Error('Failed to get account keys because of a mismatch in the number of account keys from lookups');
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
accountKeysFromLookups = args.accountKeysFromLookups;
|
|
1028
|
+
} else if (args && 'addressLookupTableAccounts' in args && args.addressLookupTableAccounts) {
|
|
1029
|
+
accountKeysFromLookups = this.resolveAddressTableLookups(args.addressLookupTableAccounts);
|
|
1030
|
+
} else if (this.addressTableLookups.length > 0) {
|
|
1031
|
+
throw new Error('Failed to get account keys because address table lookups were not resolved');
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
return new MessageAccountKeys(this.staticAccountKeys, accountKeysFromLookups);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
isAccountSigner(index) {
|
|
1038
|
+
return index < this.header.numRequiredSignatures;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
isAccountWritable(index) {
|
|
1042
|
+
const numSignedAccounts = this.header.numRequiredSignatures;
|
|
1043
|
+
const numStaticAccountKeys = this.staticAccountKeys.length;
|
|
1044
|
+
|
|
1045
|
+
if (index >= numStaticAccountKeys) {
|
|
1046
|
+
const lookupAccountKeysIndex = index - numStaticAccountKeys;
|
|
1047
|
+
const numWritableLookupAccountKeys = this.addressTableLookups.reduce((count, lookup) => count + lookup.writableIndexes.length, 0);
|
|
1048
|
+
return lookupAccountKeysIndex < numWritableLookupAccountKeys;
|
|
1049
|
+
} else if (index >= this.header.numRequiredSignatures) {
|
|
1050
|
+
const unsignedAccountIndex = index - numSignedAccounts;
|
|
1051
|
+
const numUnsignedAccounts = numStaticAccountKeys - numSignedAccounts;
|
|
1052
|
+
const numWritableUnsignedAccounts = numUnsignedAccounts - this.header.numReadonlyUnsignedAccounts;
|
|
1053
|
+
return unsignedAccountIndex < numWritableUnsignedAccounts;
|
|
1054
|
+
} else {
|
|
1055
|
+
const numWritableSignedAccounts = numSignedAccounts - this.header.numReadonlySignedAccounts;
|
|
1056
|
+
return index < numWritableSignedAccounts;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
resolveAddressTableLookups(addressLookupTableAccounts) {
|
|
1061
|
+
const accountKeysFromLookups = {
|
|
1062
|
+
writable: [],
|
|
1063
|
+
readonly: []
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
for (const tableLookup of this.addressTableLookups) {
|
|
1067
|
+
const tableAccount = addressLookupTableAccounts.find(account => account.key.equals(tableLookup.accountKey));
|
|
1068
|
+
|
|
1069
|
+
if (!tableAccount) {
|
|
1070
|
+
throw new Error(`Failed to find address lookup table account for table key ${tableLookup.accountKey.toBase58()}`);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
for (const index of tableLookup.writableIndexes) {
|
|
1074
|
+
if (index < tableAccount.state.addresses.length) {
|
|
1075
|
+
accountKeysFromLookups.writable.push(tableAccount.state.addresses[index]);
|
|
1076
|
+
} else {
|
|
1077
|
+
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
for (const index of tableLookup.readonlyIndexes) {
|
|
1082
|
+
if (index < tableAccount.state.addresses.length) {
|
|
1083
|
+
accountKeysFromLookups.readonly.push(tableAccount.state.addresses[index]);
|
|
1084
|
+
} else {
|
|
1085
|
+
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
return accountKeysFromLookups;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
static compile(args) {
|
|
1094
|
+
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
|
|
1095
|
+
const addressTableLookups = new Array();
|
|
1096
|
+
const accountKeysFromLookups = {
|
|
1097
|
+
writable: new Array(),
|
|
1098
|
+
readonly: new Array()
|
|
1099
|
+
};
|
|
1100
|
+
const lookupTableAccounts = args.addressLookupTableAccounts || [];
|
|
1101
|
+
|
|
1102
|
+
for (const lookupTable of lookupTableAccounts) {
|
|
1103
|
+
const extractResult = compiledKeys.extractTableLookup(lookupTable);
|
|
1104
|
+
|
|
1105
|
+
if (extractResult !== undefined) {
|
|
1106
|
+
const [addressTableLookup, {
|
|
1107
|
+
writable,
|
|
1108
|
+
readonly
|
|
1109
|
+
}] = extractResult;
|
|
1110
|
+
addressTableLookups.push(addressTableLookup);
|
|
1111
|
+
accountKeysFromLookups.writable.push(...writable);
|
|
1112
|
+
accountKeysFromLookups.readonly.push(...readonly);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
|
|
1117
|
+
const accountKeys = new MessageAccountKeys(staticAccountKeys, accountKeysFromLookups);
|
|
1118
|
+
const compiledInstructions = accountKeys.compileInstructions(args.instructions);
|
|
1119
|
+
return new MessageV0({
|
|
1120
|
+
header,
|
|
1121
|
+
staticAccountKeys,
|
|
1122
|
+
recentBlockhash: args.recentBlockhash,
|
|
1123
|
+
compiledInstructions,
|
|
1124
|
+
addressTableLookups
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
serialize() {
|
|
1129
|
+
const encodedStaticAccountKeysLength = Array();
|
|
1130
|
+
encodeLength(encodedStaticAccountKeysLength, this.staticAccountKeys.length);
|
|
1131
|
+
const serializedInstructions = this.serializeInstructions();
|
|
1132
|
+
const encodedInstructionsLength = Array();
|
|
1133
|
+
encodeLength(encodedInstructionsLength, this.compiledInstructions.length);
|
|
1134
|
+
const serializedAddressTableLookups = this.serializeAddressTableLookups();
|
|
1135
|
+
const encodedAddressTableLookupsLength = Array();
|
|
1136
|
+
encodeLength(encodedAddressTableLookupsLength, this.addressTableLookups.length);
|
|
1137
|
+
const messageLayout = BufferLayout__namespace.struct([BufferLayout__namespace.u8('prefix'), BufferLayout__namespace.struct([BufferLayout__namespace.u8('numRequiredSignatures'), BufferLayout__namespace.u8('numReadonlySignedAccounts'), BufferLayout__namespace.u8('numReadonlyUnsignedAccounts')], 'header'), BufferLayout__namespace.blob(encodedStaticAccountKeysLength.length, 'staticAccountKeysLength'), BufferLayout__namespace.seq(publicKey(), this.staticAccountKeys.length, 'staticAccountKeys'), publicKey('recentBlockhash'), BufferLayout__namespace.blob(encodedInstructionsLength.length, 'instructionsLength'), BufferLayout__namespace.blob(serializedInstructions.length, 'serializedInstructions'), BufferLayout__namespace.blob(encodedAddressTableLookupsLength.length, 'addressTableLookupsLength'), BufferLayout__namespace.blob(serializedAddressTableLookups.length, 'serializedAddressTableLookups')]);
|
|
1138
|
+
const serializedMessage = new Uint8Array(PACKET_DATA_SIZE);
|
|
1139
|
+
const MESSAGE_VERSION_0_PREFIX = 1 << 7;
|
|
1140
|
+
const serializedMessageLength = messageLayout.encode({
|
|
1141
|
+
prefix: MESSAGE_VERSION_0_PREFIX,
|
|
1142
|
+
header: this.header,
|
|
1143
|
+
staticAccountKeysLength: new Uint8Array(encodedStaticAccountKeysLength),
|
|
1144
|
+
staticAccountKeys: this.staticAccountKeys.map(key => key.toBytes()),
|
|
1145
|
+
recentBlockhash: bs58__default["default"].decode(this.recentBlockhash),
|
|
1146
|
+
instructionsLength: new Uint8Array(encodedInstructionsLength),
|
|
1147
|
+
serializedInstructions,
|
|
1148
|
+
addressTableLookupsLength: new Uint8Array(encodedAddressTableLookupsLength),
|
|
1149
|
+
serializedAddressTableLookups
|
|
1150
|
+
}, serializedMessage);
|
|
1151
|
+
return serializedMessage.slice(0, serializedMessageLength);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
serializeInstructions() {
|
|
1155
|
+
let serializedLength = 0;
|
|
1156
|
+
const serializedInstructions = new Uint8Array(PACKET_DATA_SIZE);
|
|
1157
|
+
|
|
1158
|
+
for (const instruction of this.compiledInstructions) {
|
|
1159
|
+
const encodedAccountKeyIndexesLength = Array();
|
|
1160
|
+
encodeLength(encodedAccountKeyIndexesLength, instruction.accountKeyIndexes.length);
|
|
1161
|
+
const encodedDataLength = Array();
|
|
1162
|
+
encodeLength(encodedDataLength, instruction.data.length);
|
|
1163
|
+
const instructionLayout = BufferLayout__namespace.struct([BufferLayout__namespace.u8('programIdIndex'), BufferLayout__namespace.blob(encodedAccountKeyIndexesLength.length, 'encodedAccountKeyIndexesLength'), BufferLayout__namespace.seq(BufferLayout__namespace.u8(), instruction.accountKeyIndexes.length, 'accountKeyIndexes'), BufferLayout__namespace.blob(encodedDataLength.length, 'encodedDataLength'), BufferLayout__namespace.blob(instruction.data.length, 'data')]);
|
|
1164
|
+
serializedLength += instructionLayout.encode({
|
|
1165
|
+
programIdIndex: instruction.programIdIndex,
|
|
1166
|
+
encodedAccountKeyIndexesLength: new Uint8Array(encodedAccountKeyIndexesLength),
|
|
1167
|
+
accountKeyIndexes: instruction.accountKeyIndexes,
|
|
1168
|
+
encodedDataLength: new Uint8Array(encodedDataLength),
|
|
1169
|
+
data: instruction.data
|
|
1170
|
+
}, serializedInstructions, serializedLength);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
return serializedInstructions.slice(0, serializedLength);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
serializeAddressTableLookups() {
|
|
1177
|
+
let serializedLength = 0;
|
|
1178
|
+
const serializedAddressTableLookups = new Uint8Array(PACKET_DATA_SIZE);
|
|
1179
|
+
|
|
1180
|
+
for (const lookup of this.addressTableLookups) {
|
|
1181
|
+
const encodedWritableIndexesLength = Array();
|
|
1182
|
+
encodeLength(encodedWritableIndexesLength, lookup.writableIndexes.length);
|
|
1183
|
+
const encodedReadonlyIndexesLength = Array();
|
|
1184
|
+
encodeLength(encodedReadonlyIndexesLength, lookup.readonlyIndexes.length);
|
|
1185
|
+
const addressTableLookupLayout = BufferLayout__namespace.struct([publicKey('accountKey'), BufferLayout__namespace.blob(encodedWritableIndexesLength.length, 'encodedWritableIndexesLength'), BufferLayout__namespace.seq(BufferLayout__namespace.u8(), lookup.writableIndexes.length, 'writableIndexes'), BufferLayout__namespace.blob(encodedReadonlyIndexesLength.length, 'encodedReadonlyIndexesLength'), BufferLayout__namespace.seq(BufferLayout__namespace.u8(), lookup.readonlyIndexes.length, 'readonlyIndexes')]);
|
|
1186
|
+
serializedLength += addressTableLookupLayout.encode({
|
|
1187
|
+
accountKey: lookup.accountKey.toBytes(),
|
|
1188
|
+
encodedWritableIndexesLength: new Uint8Array(encodedWritableIndexesLength),
|
|
1189
|
+
writableIndexes: lookup.writableIndexes,
|
|
1190
|
+
encodedReadonlyIndexesLength: new Uint8Array(encodedReadonlyIndexesLength),
|
|
1191
|
+
readonlyIndexes: lookup.readonlyIndexes
|
|
1192
|
+
}, serializedAddressTableLookups, serializedLength);
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
return serializedAddressTableLookups.slice(0, serializedLength);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
static deserialize(serializedMessage) {
|
|
1199
|
+
let byteArray = [...serializedMessage];
|
|
1200
|
+
const prefix = byteArray.shift();
|
|
1201
|
+
const maskedPrefix = prefix & VERSION_PREFIX_MASK;
|
|
1202
|
+
assert(prefix !== maskedPrefix, `Expected versioned message but received legacy message`);
|
|
1203
|
+
const version = maskedPrefix;
|
|
1204
|
+
assert(version === 0, `Expected versioned message with version 0 but found version ${version}`);
|
|
1205
|
+
const header = {
|
|
1206
|
+
numRequiredSignatures: byteArray.shift(),
|
|
1207
|
+
numReadonlySignedAccounts: byteArray.shift(),
|
|
1208
|
+
numReadonlyUnsignedAccounts: byteArray.shift()
|
|
1209
|
+
};
|
|
1210
|
+
const staticAccountKeys = [];
|
|
1211
|
+
const staticAccountKeysLength = decodeLength(byteArray);
|
|
1212
|
+
|
|
1213
|
+
for (let i = 0; i < staticAccountKeysLength; i++) {
|
|
1214
|
+
staticAccountKeys.push(new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH)));
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
const recentBlockhash = bs58__default["default"].encode(byteArray.splice(0, PUBLIC_KEY_LENGTH));
|
|
1218
|
+
const instructionCount = decodeLength(byteArray);
|
|
1219
|
+
const compiledInstructions = [];
|
|
1220
|
+
|
|
1221
|
+
for (let i = 0; i < instructionCount; i++) {
|
|
1222
|
+
const programIdIndex = byteArray.shift();
|
|
1223
|
+
const accountKeyIndexesLength = decodeLength(byteArray);
|
|
1224
|
+
const accountKeyIndexes = byteArray.splice(0, accountKeyIndexesLength);
|
|
1225
|
+
const dataLength = decodeLength(byteArray);
|
|
1226
|
+
const data = new Uint8Array(byteArray.splice(0, dataLength));
|
|
1227
|
+
compiledInstructions.push({
|
|
1228
|
+
programIdIndex,
|
|
1229
|
+
accountKeyIndexes,
|
|
1230
|
+
data
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
const addressTableLookupsCount = decodeLength(byteArray);
|
|
1235
|
+
const addressTableLookups = [];
|
|
1236
|
+
|
|
1237
|
+
for (let i = 0; i < addressTableLookupsCount; i++) {
|
|
1238
|
+
const accountKey = new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH));
|
|
1239
|
+
const writableIndexesLength = decodeLength(byteArray);
|
|
1240
|
+
const writableIndexes = byteArray.splice(0, writableIndexesLength);
|
|
1241
|
+
const readonlyIndexesLength = decodeLength(byteArray);
|
|
1242
|
+
const readonlyIndexes = byteArray.splice(0, readonlyIndexesLength);
|
|
1243
|
+
addressTableLookups.push({
|
|
1244
|
+
accountKey,
|
|
1245
|
+
writableIndexes,
|
|
1246
|
+
readonlyIndexes
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
return new MessageV0({
|
|
1251
|
+
header,
|
|
1252
|
+
staticAccountKeys,
|
|
1253
|
+
recentBlockhash,
|
|
1254
|
+
compiledInstructions,
|
|
1255
|
+
addressTableLookups
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
|
|
991
1259
|
}
|
|
992
1260
|
|
|
1261
|
+
// eslint-disable-next-line no-redeclare
|
|
1262
|
+
const VersionedMessage = {
|
|
1263
|
+
deserializeMessageVersion(serializedMessage) {
|
|
1264
|
+
const prefix = serializedMessage[0];
|
|
1265
|
+
const maskedPrefix = prefix & VERSION_PREFIX_MASK; // if the highest bit of the prefix is not set, the message is not versioned
|
|
1266
|
+
|
|
1267
|
+
if (maskedPrefix === prefix) {
|
|
1268
|
+
return 'legacy';
|
|
1269
|
+
} // the lower 7 bits of the prefix indicate the message version
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
return maskedPrefix;
|
|
1273
|
+
},
|
|
1274
|
+
|
|
1275
|
+
deserialize: serializedMessage => {
|
|
1276
|
+
const version = VersionedMessage.deserializeMessageVersion(serializedMessage);
|
|
1277
|
+
|
|
1278
|
+
if (version === 'legacy') {
|
|
1279
|
+
return Message.from(serializedMessage);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
if (version === 0) {
|
|
1283
|
+
return MessageV0.deserialize(serializedMessage);
|
|
1284
|
+
} else {
|
|
1285
|
+
throw new Error(`Transaction message version ${version} deserialization is not supported`);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
|
|
1290
|
+
/**
|
|
1291
|
+
* Transaction signature as base-58 encoded string
|
|
1292
|
+
*/
|
|
1293
|
+
|
|
993
1294
|
exports.TransactionStatus = void 0;
|
|
994
1295
|
/**
|
|
995
1296
|
* Default (empty) signature
|
|
@@ -999,6 +1300,7 @@ exports.TransactionStatus = void 0;
|
|
|
999
1300
|
TransactionStatus[TransactionStatus["BLOCKHEIGHT_EXCEEDED"] = 0] = "BLOCKHEIGHT_EXCEEDED";
|
|
1000
1301
|
TransactionStatus[TransactionStatus["PROCESSED"] = 1] = "PROCESSED";
|
|
1001
1302
|
TransactionStatus[TransactionStatus["TIMED_OUT"] = 2] = "TIMED_OUT";
|
|
1303
|
+
TransactionStatus[TransactionStatus["NONCE_INVALID"] = 3] = "NONCE_INVALID";
|
|
1002
1304
|
})(exports.TransactionStatus || (exports.TransactionStatus = {}));
|
|
1003
1305
|
|
|
1004
1306
|
const DEFAULT_SIGNATURE = buffer.Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
@@ -1093,6 +1395,7 @@ class Transaction {
|
|
|
1093
1395
|
this.recentBlockhash = void 0;
|
|
1094
1396
|
this.lastValidBlockHeight = void 0;
|
|
1095
1397
|
this.nonceInfo = void 0;
|
|
1398
|
+
this.minNonceContextSlot = void 0;
|
|
1096
1399
|
this._message = void 0;
|
|
1097
1400
|
this._json = void 0;
|
|
1098
1401
|
|
|
@@ -1108,7 +1411,14 @@ class Transaction {
|
|
|
1108
1411
|
this.signatures = opts.signatures;
|
|
1109
1412
|
}
|
|
1110
1413
|
|
|
1111
|
-
if (Object.prototype.hasOwnProperty.call(opts, '
|
|
1414
|
+
if (Object.prototype.hasOwnProperty.call(opts, 'nonceInfo')) {
|
|
1415
|
+
const {
|
|
1416
|
+
minContextSlot,
|
|
1417
|
+
nonceInfo
|
|
1418
|
+
} = opts;
|
|
1419
|
+
this.minNonceContextSlot = minContextSlot;
|
|
1420
|
+
this.nonceInfo = nonceInfo;
|
|
1421
|
+
} else if (Object.prototype.hasOwnProperty.call(opts, 'lastValidBlockHeight')) {
|
|
1112
1422
|
const {
|
|
1113
1423
|
blockhash,
|
|
1114
1424
|
lastValidBlockHeight
|
|
@@ -1515,7 +1825,7 @@ class Transaction {
|
|
|
1515
1825
|
_partialSign(message, ...signers) {
|
|
1516
1826
|
const signData = message.serialize();
|
|
1517
1827
|
signers.forEach(signer => {
|
|
1518
|
-
const signature =
|
|
1828
|
+
const signature = sign(signData, signer.secretKey);
|
|
1519
1829
|
|
|
1520
1830
|
this._addSignature(signer.publicKey, toBuffer(signature));
|
|
1521
1831
|
});
|
|
@@ -1571,7 +1881,7 @@ class Transaction {
|
|
|
1571
1881
|
return false;
|
|
1572
1882
|
}
|
|
1573
1883
|
} else {
|
|
1574
|
-
if (!
|
|
1884
|
+
if (!verify(signature, signData, publicKey.toBytes())) {
|
|
1575
1885
|
return false;
|
|
1576
1886
|
}
|
|
1577
1887
|
}
|
|
@@ -1718,6 +2028,184 @@ class Transaction {
|
|
|
1718
2028
|
|
|
1719
2029
|
}
|
|
1720
2030
|
|
|
2031
|
+
class TransactionMessage {
|
|
2032
|
+
constructor(args) {
|
|
2033
|
+
this.payerKey = void 0;
|
|
2034
|
+
this.instructions = void 0;
|
|
2035
|
+
this.recentBlockhash = void 0;
|
|
2036
|
+
this.payerKey = args.payerKey;
|
|
2037
|
+
this.instructions = args.instructions;
|
|
2038
|
+
this.recentBlockhash = args.recentBlockhash;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
static decompile(message, args) {
|
|
2042
|
+
const {
|
|
2043
|
+
header,
|
|
2044
|
+
compiledInstructions,
|
|
2045
|
+
recentBlockhash
|
|
2046
|
+
} = message;
|
|
2047
|
+
const {
|
|
2048
|
+
numRequiredSignatures,
|
|
2049
|
+
numReadonlySignedAccounts,
|
|
2050
|
+
numReadonlyUnsignedAccounts
|
|
2051
|
+
} = header;
|
|
2052
|
+
const numWritableSignedAccounts = numRequiredSignatures - numReadonlySignedAccounts;
|
|
2053
|
+
assert(numWritableSignedAccounts > 0, 'Message header is invalid');
|
|
2054
|
+
const numWritableUnsignedAccounts = message.staticAccountKeys.length - numRequiredSignatures - numReadonlyUnsignedAccounts;
|
|
2055
|
+
assert(numWritableUnsignedAccounts >= 0, 'Message header is invalid');
|
|
2056
|
+
const accountKeys = message.getAccountKeys(args);
|
|
2057
|
+
const payerKey = accountKeys.get(0);
|
|
2058
|
+
|
|
2059
|
+
if (payerKey === undefined) {
|
|
2060
|
+
throw new Error('Failed to decompile message because no account keys were found');
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
const instructions = [];
|
|
2064
|
+
|
|
2065
|
+
for (const compiledIx of compiledInstructions) {
|
|
2066
|
+
const keys = [];
|
|
2067
|
+
|
|
2068
|
+
for (const keyIndex of compiledIx.accountKeyIndexes) {
|
|
2069
|
+
const pubkey = accountKeys.get(keyIndex);
|
|
2070
|
+
|
|
2071
|
+
if (pubkey === undefined) {
|
|
2072
|
+
throw new Error(`Failed to find key for account key index ${keyIndex}`);
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
const isSigner = keyIndex < numRequiredSignatures;
|
|
2076
|
+
let isWritable;
|
|
2077
|
+
|
|
2078
|
+
if (isSigner) {
|
|
2079
|
+
isWritable = keyIndex < numWritableSignedAccounts;
|
|
2080
|
+
} else if (keyIndex < accountKeys.staticAccountKeys.length) {
|
|
2081
|
+
isWritable = keyIndex - numRequiredSignatures < numWritableUnsignedAccounts;
|
|
2082
|
+
} else {
|
|
2083
|
+
isWritable = keyIndex - accountKeys.staticAccountKeys.length < // accountKeysFromLookups cannot be undefined because we already found a pubkey for this index above
|
|
2084
|
+
accountKeys.accountKeysFromLookups.writable.length;
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
keys.push({
|
|
2088
|
+
pubkey,
|
|
2089
|
+
isSigner: keyIndex < header.numRequiredSignatures,
|
|
2090
|
+
isWritable
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
const programId = accountKeys.get(compiledIx.programIdIndex);
|
|
2095
|
+
|
|
2096
|
+
if (programId === undefined) {
|
|
2097
|
+
throw new Error(`Failed to find program id for program id index ${compiledIx.programIdIndex}`);
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
instructions.push(new TransactionInstruction({
|
|
2101
|
+
programId,
|
|
2102
|
+
data: toBuffer(compiledIx.data),
|
|
2103
|
+
keys
|
|
2104
|
+
}));
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
return new TransactionMessage({
|
|
2108
|
+
payerKey,
|
|
2109
|
+
instructions,
|
|
2110
|
+
recentBlockhash
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
compileToLegacyMessage() {
|
|
2115
|
+
return Message.compile({
|
|
2116
|
+
payerKey: this.payerKey,
|
|
2117
|
+
recentBlockhash: this.recentBlockhash,
|
|
2118
|
+
instructions: this.instructions
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
compileToV0Message(addressLookupTableAccounts) {
|
|
2123
|
+
return MessageV0.compile({
|
|
2124
|
+
payerKey: this.payerKey,
|
|
2125
|
+
recentBlockhash: this.recentBlockhash,
|
|
2126
|
+
instructions: this.instructions,
|
|
2127
|
+
addressLookupTableAccounts
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
/**
|
|
2134
|
+
* Versioned transaction class
|
|
2135
|
+
*/
|
|
2136
|
+
class VersionedTransaction {
|
|
2137
|
+
get version() {
|
|
2138
|
+
return this.message.version;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
constructor(message, signatures) {
|
|
2142
|
+
this.signatures = void 0;
|
|
2143
|
+
this.message = void 0;
|
|
2144
|
+
|
|
2145
|
+
if (signatures !== undefined) {
|
|
2146
|
+
assert(signatures.length === message.header.numRequiredSignatures, 'Expected signatures length to be equal to the number of required signatures');
|
|
2147
|
+
this.signatures = signatures;
|
|
2148
|
+
} else {
|
|
2149
|
+
const defaultSignatures = [];
|
|
2150
|
+
|
|
2151
|
+
for (let i = 0; i < message.header.numRequiredSignatures; i++) {
|
|
2152
|
+
defaultSignatures.push(new Uint8Array(SIGNATURE_LENGTH_IN_BYTES));
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
this.signatures = defaultSignatures;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
this.message = message;
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
serialize() {
|
|
2162
|
+
const serializedMessage = this.message.serialize();
|
|
2163
|
+
const encodedSignaturesLength = Array();
|
|
2164
|
+
encodeLength(encodedSignaturesLength, this.signatures.length);
|
|
2165
|
+
const transactionLayout = BufferLayout__namespace.struct([BufferLayout__namespace.blob(encodedSignaturesLength.length, 'encodedSignaturesLength'), BufferLayout__namespace.seq(signature(), this.signatures.length, 'signatures'), BufferLayout__namespace.blob(serializedMessage.length, 'serializedMessage')]);
|
|
2166
|
+
const serializedTransaction = new Uint8Array(2048);
|
|
2167
|
+
const serializedTransactionLength = transactionLayout.encode({
|
|
2168
|
+
encodedSignaturesLength: new Uint8Array(encodedSignaturesLength),
|
|
2169
|
+
signatures: this.signatures,
|
|
2170
|
+
serializedMessage
|
|
2171
|
+
}, serializedTransaction);
|
|
2172
|
+
return serializedTransaction.slice(0, serializedTransactionLength);
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
static deserialize(serializedTransaction) {
|
|
2176
|
+
let byteArray = [...serializedTransaction];
|
|
2177
|
+
const signatures = [];
|
|
2178
|
+
const signaturesLength = decodeLength(byteArray);
|
|
2179
|
+
|
|
2180
|
+
for (let i = 0; i < signaturesLength; i++) {
|
|
2181
|
+
signatures.push(new Uint8Array(byteArray.splice(0, SIGNATURE_LENGTH_IN_BYTES)));
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
const message = VersionedMessage.deserialize(new Uint8Array(byteArray));
|
|
2185
|
+
return new VersionedTransaction(message, signatures);
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
sign(signers) {
|
|
2189
|
+
const messageData = this.message.serialize();
|
|
2190
|
+
const signerPubkeys = this.message.staticAccountKeys.slice(0, this.message.header.numRequiredSignatures);
|
|
2191
|
+
|
|
2192
|
+
for (const signer of signers) {
|
|
2193
|
+
const signerIndex = signerPubkeys.findIndex(pubkey => pubkey.equals(signer.publicKey));
|
|
2194
|
+
assert(signerIndex >= 0, `Cannot sign with non signer key ${signer.publicKey.toBase58()}`);
|
|
2195
|
+
this.signatures[signerIndex] = sign(messageData, signer.secretKey);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
addSignature(publicKey, signature) {
|
|
2200
|
+
assert(signature.byteLength === 64, 'Signature must be 64 bytes long');
|
|
2201
|
+
const signerPubkeys = this.message.staticAccountKeys.slice(0, this.message.header.numRequiredSignatures);
|
|
2202
|
+
const signerIndex = signerPubkeys.findIndex(pubkey => pubkey.equals(publicKey));
|
|
2203
|
+
assert(signerIndex >= 0, `Can not add signature; \`${publicKey.toBase58()}\` is not required to sign this transaction`);
|
|
2204
|
+
this.signatures[signerIndex] = signature;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
}
|
|
2208
|
+
|
|
1721
2209
|
const SYSVAR_CLOCK_PUBKEY = new PublicKey('SysvarC1ock11111111111111111111111111111111');
|
|
1722
2210
|
const SYSVAR_EPOCH_SCHEDULE_PUBKEY = new PublicKey('SysvarEpochSchedu1e111111111111111111111111');
|
|
1723
2211
|
const SYSVAR_INSTRUCTIONS_PUBKEY = new PublicKey('Sysvar1nstructions1111111111111111111111111');
|
|
@@ -1747,11 +2235,34 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
|
|
|
1747
2235
|
minContextSlot: options.minContextSlot
|
|
1748
2236
|
};
|
|
1749
2237
|
const signature = await connection.sendTransaction(transaction, signers, sendOptions);
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2238
|
+
let status;
|
|
2239
|
+
|
|
2240
|
+
if (transaction.recentBlockhash != null && transaction.lastValidBlockHeight != null) {
|
|
2241
|
+
status = (await connection.confirmTransaction({
|
|
2242
|
+
abortSignal: options === null || options === void 0 ? void 0 : options.abortSignal,
|
|
2243
|
+
signature: signature,
|
|
2244
|
+
blockhash: transaction.recentBlockhash,
|
|
2245
|
+
lastValidBlockHeight: transaction.lastValidBlockHeight
|
|
2246
|
+
}, options && options.commitment)).value;
|
|
2247
|
+
} else if (transaction.minNonceContextSlot != null && transaction.nonceInfo != null) {
|
|
2248
|
+
const {
|
|
2249
|
+
nonceInstruction
|
|
2250
|
+
} = transaction.nonceInfo;
|
|
2251
|
+
const nonceAccountPubkey = nonceInstruction.keys[0].pubkey;
|
|
2252
|
+
status = (await connection.confirmTransaction({
|
|
2253
|
+
abortSignal: options === null || options === void 0 ? void 0 : options.abortSignal,
|
|
2254
|
+
minContextSlot: transaction.minNonceContextSlot,
|
|
2255
|
+
nonceAccountPubkey,
|
|
2256
|
+
nonceValue: transaction.nonceInfo.nonce,
|
|
2257
|
+
signature
|
|
2258
|
+
}, options && options.commitment)).value;
|
|
2259
|
+
} else {
|
|
2260
|
+
if ((options === null || options === void 0 ? void 0 : options.abortSignal) != null) {
|
|
2261
|
+
console.warn('sendAndConfirmTransaction(): A transaction with a deprecated confirmation strategy was ' + 'supplied along with an `abortSignal`. Only transactions having `lastValidBlockHeight` ' + 'or a combination of `nonceInfo` and `minNonceContextSlot` are abortable.');
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
|
|
2265
|
+
}
|
|
1755
2266
|
|
|
1756
2267
|
if (status.err) {
|
|
1757
2268
|
throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
|
|
@@ -1820,6 +2331,9 @@ const FeeCalculatorLayout = BufferLayout__namespace.nu64('lamportsPerSignature')
|
|
|
1820
2331
|
|
|
1821
2332
|
const NonceAccountLayout = BufferLayout__namespace.struct([BufferLayout__namespace.u32('version'), BufferLayout__namespace.u32('state'), publicKey('authorizedPubkey'), publicKey('nonce'), BufferLayout__namespace.struct([FeeCalculatorLayout], 'feeCalculator')]);
|
|
1822
2333
|
const NONCE_ACCOUNT_LENGTH = NonceAccountLayout.span;
|
|
2334
|
+
/**
|
|
2335
|
+
* A durable nonce is a 32 byte value encoded as a base58 string.
|
|
2336
|
+
*/
|
|
1823
2337
|
|
|
1824
2338
|
/**
|
|
1825
2339
|
* NonceAccount class
|
|
@@ -2789,12 +3303,12 @@ class BpfLoader {
|
|
|
2789
3303
|
return Loader.getMinNumSignatures(dataLength);
|
|
2790
3304
|
}
|
|
2791
3305
|
/**
|
|
2792
|
-
* Load a
|
|
3306
|
+
* Load a SBF program
|
|
2793
3307
|
*
|
|
2794
3308
|
* @param connection The connection to use
|
|
2795
3309
|
* @param payer Account that will pay program loading fees
|
|
2796
3310
|
* @param program Account to load the program into
|
|
2797
|
-
* @param elf The entire ELF containing the
|
|
3311
|
+
* @param elf The entire ELF containing the SBF program
|
|
2798
3312
|
* @param loaderProgramId The program id of the BPF loader to use
|
|
2799
3313
|
* @return true if program was loaded successfully, false if program was already loaded
|
|
2800
3314
|
*/
|
|
@@ -2910,7 +3424,7 @@ function nextPowerOfTwo(n) {
|
|
|
2910
3424
|
/**
|
|
2911
3425
|
* Epoch schedule
|
|
2912
3426
|
* (see https://docs.solana.com/terminology#epoch)
|
|
2913
|
-
* Can be retrieved with the {@link
|
|
3427
|
+
* Can be retrieved with the {@link Connection.getEpochSchedule} method
|
|
2914
3428
|
*/
|
|
2915
3429
|
|
|
2916
3430
|
|
|
@@ -3082,7 +3596,7 @@ class AddressLookupTableAccount {
|
|
|
3082
3596
|
}
|
|
3083
3597
|
|
|
3084
3598
|
isActive() {
|
|
3085
|
-
const U64_MAX =
|
|
3599
|
+
const U64_MAX = BigInt('0xffffffffffffffff');
|
|
3086
3600
|
return this.state.deactivationSlot === U64_MAX;
|
|
3087
3601
|
}
|
|
3088
3602
|
|
|
@@ -3244,6 +3758,28 @@ function notificationResultAndContext(value) {
|
|
|
3244
3758
|
value
|
|
3245
3759
|
});
|
|
3246
3760
|
}
|
|
3761
|
+
/**
|
|
3762
|
+
* @internal
|
|
3763
|
+
*/
|
|
3764
|
+
|
|
3765
|
+
|
|
3766
|
+
function versionedMessageFromResponse(version, response) {
|
|
3767
|
+
if (version === 0) {
|
|
3768
|
+
return new MessageV0({
|
|
3769
|
+
header: response.header,
|
|
3770
|
+
staticAccountKeys: response.accountKeys.map(accountKey => new PublicKey(accountKey)),
|
|
3771
|
+
recentBlockhash: response.recentBlockhash,
|
|
3772
|
+
compiledInstructions: response.instructions.map(ix => ({
|
|
3773
|
+
programIdIndex: ix.programIdIndex,
|
|
3774
|
+
accountKeyIndexes: ix.accounts,
|
|
3775
|
+
data: bs58__default["default"].decode(ix.data)
|
|
3776
|
+
})),
|
|
3777
|
+
addressTableLookups: response.addressTableLookups
|
|
3778
|
+
});
|
|
3779
|
+
} else {
|
|
3780
|
+
return new Message(response);
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3247
3783
|
/**
|
|
3248
3784
|
* The level of commitment desired when querying state
|
|
3249
3785
|
* <pre>
|
|
@@ -3355,8 +3891,15 @@ const BlockProductionResponseStruct = jsonRpcResultAndContext(superstruct.type({
|
|
|
3355
3891
|
* A performance sample
|
|
3356
3892
|
*/
|
|
3357
3893
|
|
|
3358
|
-
function createRpcClient(url, httpHeaders, customFetch, fetchMiddleware, disableRetryOnRateLimit) {
|
|
3894
|
+
function createRpcClient(url, httpHeaders, customFetch, fetchMiddleware, disableRetryOnRateLimit, httpAgent) {
|
|
3359
3895
|
const fetch = customFetch ? customFetch : fetchImpl;
|
|
3896
|
+
let agent;
|
|
3897
|
+
|
|
3898
|
+
{
|
|
3899
|
+
if (httpAgent != null) {
|
|
3900
|
+
console.warn('You have supplied an `httpAgent` when creating a `Connection` in a browser environment.' + 'It has been ignored; `httpAgent` is only used in Node environments.');
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3360
3903
|
|
|
3361
3904
|
let fetchWithMiddleware;
|
|
3362
3905
|
|
|
@@ -3374,7 +3917,6 @@ function createRpcClient(url, httpHeaders, customFetch, fetchMiddleware, disable
|
|
|
3374
3917
|
}
|
|
3375
3918
|
|
|
3376
3919
|
const clientBrowser = new RpcClient__default["default"](async (request, callback) => {
|
|
3377
|
-
const agent = undefined;
|
|
3378
3920
|
const options = {
|
|
3379
3921
|
method: 'POST',
|
|
3380
3922
|
body: request,
|
|
@@ -3426,7 +3968,6 @@ function createRpcClient(url, httpHeaders, customFetch, fetchMiddleware, disable
|
|
|
3426
3968
|
}
|
|
3427
3969
|
} catch (err) {
|
|
3428
3970
|
if (err instanceof Error) callback(err);
|
|
3429
|
-
} finally {
|
|
3430
3971
|
}
|
|
3431
3972
|
}, {});
|
|
3432
3973
|
return clientBrowser;
|
|
@@ -3799,6 +4340,11 @@ const GetSignatureStatusesRpcResult = jsonRpcResultAndContext(superstruct.array(
|
|
|
3799
4340
|
*/
|
|
3800
4341
|
|
|
3801
4342
|
const GetMinimumBalanceForRentExemptionRpcResult = jsonRpcResult(superstruct.number());
|
|
4343
|
+
const AddressTableLookupStruct = superstruct.type({
|
|
4344
|
+
accountKey: PublicKeyFromString,
|
|
4345
|
+
writableIndexes: superstruct.array(superstruct.number()),
|
|
4346
|
+
readonlyIndexes: superstruct.array(superstruct.number())
|
|
4347
|
+
});
|
|
3802
4348
|
const ConfirmedTransactionResult = superstruct.type({
|
|
3803
4349
|
signatures: superstruct.array(superstruct.string()),
|
|
3804
4350
|
message: superstruct.type({
|
|
@@ -3813,9 +4359,20 @@ const ConfirmedTransactionResult = superstruct.type({
|
|
|
3813
4359
|
data: superstruct.string(),
|
|
3814
4360
|
programIdIndex: superstruct.number()
|
|
3815
4361
|
})),
|
|
3816
|
-
recentBlockhash: superstruct.string()
|
|
4362
|
+
recentBlockhash: superstruct.string(),
|
|
4363
|
+
addressTableLookups: superstruct.optional(superstruct.array(AddressTableLookupStruct))
|
|
3817
4364
|
})
|
|
3818
4365
|
});
|
|
4366
|
+
const AnnotatedAccountKey = superstruct.type({
|
|
4367
|
+
pubkey: PublicKeyFromString,
|
|
4368
|
+
signer: superstruct.boolean(),
|
|
4369
|
+
writable: superstruct.boolean(),
|
|
4370
|
+
source: superstruct.optional(superstruct.union([superstruct.literal('transaction'), superstruct.literal('lookupTable')]))
|
|
4371
|
+
});
|
|
4372
|
+
const ConfirmedTransactionAccountsModeResult = superstruct.type({
|
|
4373
|
+
accountKeys: superstruct.array(AnnotatedAccountKey),
|
|
4374
|
+
signatures: superstruct.array(superstruct.string())
|
|
4375
|
+
});
|
|
3819
4376
|
const ParsedInstructionResult = superstruct.type({
|
|
3820
4377
|
parsed: superstruct.unknown(),
|
|
3821
4378
|
program: superstruct.string(),
|
|
@@ -3850,13 +4407,10 @@ const ParsedOrRawInstruction = superstruct.coerce(InstructionResult, UnknownInst
|
|
|
3850
4407
|
const ParsedConfirmedTransactionResult = superstruct.type({
|
|
3851
4408
|
signatures: superstruct.array(superstruct.string()),
|
|
3852
4409
|
message: superstruct.type({
|
|
3853
|
-
accountKeys: superstruct.array(
|
|
3854
|
-
pubkey: PublicKeyFromString,
|
|
3855
|
-
signer: superstruct.boolean(),
|
|
3856
|
-
writable: superstruct.boolean()
|
|
3857
|
-
})),
|
|
4410
|
+
accountKeys: superstruct.array(AnnotatedAccountKey),
|
|
3858
4411
|
instructions: superstruct.array(ParsedOrRawInstruction),
|
|
3859
|
-
recentBlockhash: superstruct.string()
|
|
4412
|
+
recentBlockhash: superstruct.string(),
|
|
4413
|
+
addressTableLookups: superstruct.optional(superstruct.nullable(superstruct.array(AddressTableLookupStruct)))
|
|
3860
4414
|
})
|
|
3861
4415
|
});
|
|
3862
4416
|
const TokenBalanceResult = superstruct.type({
|
|
@@ -3889,44 +4443,126 @@ const ConfirmedTransactionMetaResult = superstruct.type({
|
|
|
3889
4443
|
logMessages: superstruct.optional(superstruct.nullable(superstruct.array(superstruct.string()))),
|
|
3890
4444
|
preTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
|
|
3891
4445
|
postTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
|
|
3892
|
-
loadedAddresses: superstruct.optional(LoadedAddressesResult)
|
|
4446
|
+
loadedAddresses: superstruct.optional(LoadedAddressesResult),
|
|
4447
|
+
computeUnitsConsumed: superstruct.optional(superstruct.number())
|
|
4448
|
+
});
|
|
4449
|
+
/**
|
|
4450
|
+
* @internal
|
|
4451
|
+
*/
|
|
4452
|
+
|
|
4453
|
+
const ParsedConfirmedTransactionMetaResult = superstruct.type({
|
|
4454
|
+
err: TransactionErrorResult,
|
|
4455
|
+
fee: superstruct.number(),
|
|
4456
|
+
innerInstructions: superstruct.optional(superstruct.nullable(superstruct.array(superstruct.type({
|
|
4457
|
+
index: superstruct.number(),
|
|
4458
|
+
instructions: superstruct.array(ParsedOrRawInstruction)
|
|
4459
|
+
})))),
|
|
4460
|
+
preBalances: superstruct.array(superstruct.number()),
|
|
4461
|
+
postBalances: superstruct.array(superstruct.number()),
|
|
4462
|
+
logMessages: superstruct.optional(superstruct.nullable(superstruct.array(superstruct.string()))),
|
|
4463
|
+
preTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
|
|
4464
|
+
postTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
|
|
4465
|
+
loadedAddresses: superstruct.optional(LoadedAddressesResult),
|
|
4466
|
+
computeUnitsConsumed: superstruct.optional(superstruct.number())
|
|
4467
|
+
});
|
|
4468
|
+
const TransactionVersionStruct = superstruct.union([superstruct.literal(0), superstruct.literal('legacy')]);
|
|
4469
|
+
/** @internal */
|
|
4470
|
+
|
|
4471
|
+
const RewardsResult = superstruct.type({
|
|
4472
|
+
pubkey: superstruct.string(),
|
|
4473
|
+
lamports: superstruct.number(),
|
|
4474
|
+
postBalance: superstruct.nullable(superstruct.number()),
|
|
4475
|
+
rewardType: superstruct.nullable(superstruct.string())
|
|
3893
4476
|
});
|
|
3894
4477
|
/**
|
|
3895
|
-
*
|
|
4478
|
+
* Expected JSON RPC response for the "getBlock" message
|
|
4479
|
+
*/
|
|
4480
|
+
|
|
4481
|
+
const GetBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruct.type({
|
|
4482
|
+
blockhash: superstruct.string(),
|
|
4483
|
+
previousBlockhash: superstruct.string(),
|
|
4484
|
+
parentSlot: superstruct.number(),
|
|
4485
|
+
transactions: superstruct.array(superstruct.type({
|
|
4486
|
+
transaction: ConfirmedTransactionResult,
|
|
4487
|
+
meta: superstruct.nullable(ConfirmedTransactionMetaResult),
|
|
4488
|
+
version: superstruct.optional(TransactionVersionStruct)
|
|
4489
|
+
})),
|
|
4490
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
4491
|
+
blockTime: superstruct.nullable(superstruct.number()),
|
|
4492
|
+
blockHeight: superstruct.nullable(superstruct.number())
|
|
4493
|
+
})));
|
|
4494
|
+
/**
|
|
4495
|
+
* Expected JSON RPC response for the "getBlock" message when `transactionDetails` is `none`
|
|
4496
|
+
*/
|
|
4497
|
+
|
|
4498
|
+
const GetNoneModeBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruct.type({
|
|
4499
|
+
blockhash: superstruct.string(),
|
|
4500
|
+
previousBlockhash: superstruct.string(),
|
|
4501
|
+
parentSlot: superstruct.number(),
|
|
4502
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
4503
|
+
blockTime: superstruct.nullable(superstruct.number()),
|
|
4504
|
+
blockHeight: superstruct.nullable(superstruct.number())
|
|
4505
|
+
})));
|
|
4506
|
+
/**
|
|
4507
|
+
* Expected JSON RPC response for the "getBlock" message when `transactionDetails` is `accounts`
|
|
4508
|
+
*/
|
|
4509
|
+
|
|
4510
|
+
const GetAccountsModeBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruct.type({
|
|
4511
|
+
blockhash: superstruct.string(),
|
|
4512
|
+
previousBlockhash: superstruct.string(),
|
|
4513
|
+
parentSlot: superstruct.number(),
|
|
4514
|
+
transactions: superstruct.array(superstruct.type({
|
|
4515
|
+
transaction: ConfirmedTransactionAccountsModeResult,
|
|
4516
|
+
meta: superstruct.nullable(ConfirmedTransactionMetaResult),
|
|
4517
|
+
version: superstruct.optional(TransactionVersionStruct)
|
|
4518
|
+
})),
|
|
4519
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
4520
|
+
blockTime: superstruct.nullable(superstruct.number()),
|
|
4521
|
+
blockHeight: superstruct.nullable(superstruct.number())
|
|
4522
|
+
})));
|
|
4523
|
+
/**
|
|
4524
|
+
* Expected parsed JSON RPC response for the "getBlock" message
|
|
3896
4525
|
*/
|
|
3897
4526
|
|
|
3898
|
-
const
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
});
|
|
4527
|
+
const GetParsedBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruct.type({
|
|
4528
|
+
blockhash: superstruct.string(),
|
|
4529
|
+
previousBlockhash: superstruct.string(),
|
|
4530
|
+
parentSlot: superstruct.number(),
|
|
4531
|
+
transactions: superstruct.array(superstruct.type({
|
|
4532
|
+
transaction: ParsedConfirmedTransactionResult,
|
|
4533
|
+
meta: superstruct.nullable(ParsedConfirmedTransactionMetaResult),
|
|
4534
|
+
version: superstruct.optional(TransactionVersionStruct)
|
|
4535
|
+
})),
|
|
4536
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
4537
|
+
blockTime: superstruct.nullable(superstruct.number()),
|
|
4538
|
+
blockHeight: superstruct.nullable(superstruct.number())
|
|
4539
|
+
})));
|
|
3912
4540
|
/**
|
|
3913
|
-
* Expected JSON RPC response for the "getBlock" message
|
|
4541
|
+
* Expected parsed JSON RPC response for the "getBlock" message when `transactionDetails` is `accounts`
|
|
3914
4542
|
*/
|
|
3915
4543
|
|
|
3916
|
-
const
|
|
4544
|
+
const GetParsedAccountsModeBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruct.type({
|
|
3917
4545
|
blockhash: superstruct.string(),
|
|
3918
4546
|
previousBlockhash: superstruct.string(),
|
|
3919
4547
|
parentSlot: superstruct.number(),
|
|
3920
4548
|
transactions: superstruct.array(superstruct.type({
|
|
3921
|
-
transaction:
|
|
3922
|
-
meta: superstruct.nullable(
|
|
4549
|
+
transaction: ConfirmedTransactionAccountsModeResult,
|
|
4550
|
+
meta: superstruct.nullable(ParsedConfirmedTransactionMetaResult),
|
|
4551
|
+
version: superstruct.optional(TransactionVersionStruct)
|
|
3923
4552
|
})),
|
|
3924
|
-
rewards: superstruct.optional(superstruct.array(
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
4553
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
4554
|
+
blockTime: superstruct.nullable(superstruct.number()),
|
|
4555
|
+
blockHeight: superstruct.nullable(superstruct.number())
|
|
4556
|
+
})));
|
|
4557
|
+
/**
|
|
4558
|
+
* Expected parsed JSON RPC response for the "getBlock" message when `transactionDetails` is `none`
|
|
4559
|
+
*/
|
|
4560
|
+
|
|
4561
|
+
const GetParsedNoneModeBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruct.type({
|
|
4562
|
+
blockhash: superstruct.string(),
|
|
4563
|
+
previousBlockhash: superstruct.string(),
|
|
4564
|
+
parentSlot: superstruct.number(),
|
|
4565
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
3930
4566
|
blockTime: superstruct.nullable(superstruct.number()),
|
|
3931
4567
|
blockHeight: superstruct.nullable(superstruct.number())
|
|
3932
4568
|
})));
|
|
@@ -3944,12 +4580,7 @@ const GetConfirmedBlockRpcResult = jsonRpcResult(superstruct.nullable(superstruc
|
|
|
3944
4580
|
transaction: ConfirmedTransactionResult,
|
|
3945
4581
|
meta: superstruct.nullable(ConfirmedTransactionMetaResult)
|
|
3946
4582
|
})),
|
|
3947
|
-
rewards: superstruct.optional(superstruct.array(
|
|
3948
|
-
pubkey: superstruct.string(),
|
|
3949
|
-
lamports: superstruct.number(),
|
|
3950
|
-
postBalance: superstruct.nullable(superstruct.number()),
|
|
3951
|
-
rewardType: superstruct.nullable(superstruct.string())
|
|
3952
|
-
}))),
|
|
4583
|
+
rewards: superstruct.optional(superstruct.array(RewardsResult)),
|
|
3953
4584
|
blockTime: superstruct.nullable(superstruct.number())
|
|
3954
4585
|
})));
|
|
3955
4586
|
/**
|
|
@@ -3971,7 +4602,8 @@ const GetTransactionRpcResult = jsonRpcResult(superstruct.nullable(superstruct.t
|
|
|
3971
4602
|
slot: superstruct.number(),
|
|
3972
4603
|
meta: ConfirmedTransactionMetaResult,
|
|
3973
4604
|
blockTime: superstruct.optional(superstruct.nullable(superstruct.number())),
|
|
3974
|
-
transaction: ConfirmedTransactionResult
|
|
4605
|
+
transaction: ConfirmedTransactionResult,
|
|
4606
|
+
version: superstruct.optional(TransactionVersionStruct)
|
|
3975
4607
|
})));
|
|
3976
4608
|
/**
|
|
3977
4609
|
* Expected parsed JSON RPC response for the "getTransaction" message
|
|
@@ -3981,7 +4613,8 @@ const GetParsedTransactionRpcResult = jsonRpcResult(superstruct.nullable(superst
|
|
|
3981
4613
|
slot: superstruct.number(),
|
|
3982
4614
|
transaction: ParsedConfirmedTransactionResult,
|
|
3983
4615
|
meta: superstruct.nullable(ParsedConfirmedTransactionMetaResult),
|
|
3984
|
-
blockTime: superstruct.optional(superstruct.nullable(superstruct.number()))
|
|
4616
|
+
blockTime: superstruct.optional(superstruct.nullable(superstruct.number())),
|
|
4617
|
+
version: superstruct.optional(TransactionVersionStruct)
|
|
3985
4618
|
})));
|
|
3986
4619
|
/**
|
|
3987
4620
|
* Expected JSON RPC response for the "getRecentBlockhash" message
|
|
@@ -4113,6 +4746,10 @@ class Connection {
|
|
|
4113
4746
|
|
|
4114
4747
|
/** @internal */
|
|
4115
4748
|
|
|
4749
|
+
/** @internal */
|
|
4750
|
+
|
|
4751
|
+
/** @internal */
|
|
4752
|
+
|
|
4116
4753
|
/**
|
|
4117
4754
|
* Special case.
|
|
4118
4755
|
* After a signature is processed, RPCs automatically dispose of the
|
|
@@ -4158,6 +4795,8 @@ class Connection {
|
|
|
4158
4795
|
};
|
|
4159
4796
|
this._nextClientSubscriptionId = 0;
|
|
4160
4797
|
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
4798
|
+
this._subscriptionHashByClientSubscriptionId = {};
|
|
4799
|
+
this._subscriptionStateChangeCallbacksByHash = {};
|
|
4161
4800
|
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
4162
4801
|
this._subscriptionsByHash = {};
|
|
4163
4802
|
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
@@ -4166,6 +4805,7 @@ class Connection {
|
|
|
4166
4805
|
let fetch;
|
|
4167
4806
|
let fetchMiddleware;
|
|
4168
4807
|
let disableRetryOnRateLimit;
|
|
4808
|
+
let httpAgent;
|
|
4169
4809
|
|
|
4170
4810
|
if (commitmentOrConfig && typeof commitmentOrConfig === 'string') {
|
|
4171
4811
|
this._commitment = commitmentOrConfig;
|
|
@@ -4177,11 +4817,12 @@ class Connection {
|
|
|
4177
4817
|
fetch = commitmentOrConfig.fetch;
|
|
4178
4818
|
fetchMiddleware = commitmentOrConfig.fetchMiddleware;
|
|
4179
4819
|
disableRetryOnRateLimit = commitmentOrConfig.disableRetryOnRateLimit;
|
|
4820
|
+
httpAgent = commitmentOrConfig.httpAgent;
|
|
4180
4821
|
}
|
|
4181
4822
|
|
|
4182
4823
|
this._rpcEndpoint = assertEndpointUrl(endpoint);
|
|
4183
4824
|
this._rpcWsEndpoint = wsEndpoint || makeWebsocketUrl(endpoint);
|
|
4184
|
-
this._rpcClient = createRpcClient(endpoint, httpHeaders, fetch, fetchMiddleware, disableRetryOnRateLimit);
|
|
4825
|
+
this._rpcClient = createRpcClient(endpoint, httpHeaders, fetch, fetchMiddleware, disableRetryOnRateLimit, httpAgent);
|
|
4185
4826
|
this._rpcRequest = createRpcRequest(this._rpcClient);
|
|
4186
4827
|
this._rpcBatchRequest = createRpcBatchRequest(this._rpcClient);
|
|
4187
4828
|
this._rpcWebSocket = new rpcWebsockets.Client(this._rpcWsEndpoint, {
|
|
@@ -4536,6 +5177,29 @@ class Connection {
|
|
|
4536
5177
|
*/
|
|
4537
5178
|
|
|
4538
5179
|
|
|
5180
|
+
async getMultipleParsedAccounts(publicKeys, rawConfig) {
|
|
5181
|
+
const {
|
|
5182
|
+
commitment,
|
|
5183
|
+
config
|
|
5184
|
+
} = extractCommitmentFromConfig(rawConfig);
|
|
5185
|
+
const keys = publicKeys.map(key => key.toBase58());
|
|
5186
|
+
|
|
5187
|
+
const args = this._buildArgs([keys], commitment, 'jsonParsed', config);
|
|
5188
|
+
|
|
5189
|
+
const unsafeRes = await this._rpcRequest('getMultipleAccounts', args);
|
|
5190
|
+
const res = superstruct.create(unsafeRes, jsonRpcResultAndContext(superstruct.array(superstruct.nullable(ParsedAccountInfoResult))));
|
|
5191
|
+
|
|
5192
|
+
if ('error' in res) {
|
|
5193
|
+
throw new SolanaJSONRPCError(res.error, `failed to get info for accounts ${keys}`);
|
|
5194
|
+
}
|
|
5195
|
+
|
|
5196
|
+
return res.result;
|
|
5197
|
+
}
|
|
5198
|
+
/**
|
|
5199
|
+
* Fetch all the account info for multiple accounts specified by an array of public keys, return with context
|
|
5200
|
+
*/
|
|
5201
|
+
|
|
5202
|
+
|
|
4539
5203
|
async getMultipleAccountsInfoAndContext(publicKeys, commitmentOrConfig) {
|
|
4540
5204
|
const {
|
|
4541
5205
|
commitment,
|
|
@@ -4568,193 +5232,515 @@ class Connection {
|
|
|
4568
5232
|
*/
|
|
4569
5233
|
|
|
4570
5234
|
|
|
4571
|
-
async getStakeActivation(publicKey, commitmentOrConfig, epoch) {
|
|
5235
|
+
async getStakeActivation(publicKey, commitmentOrConfig, epoch) {
|
|
5236
|
+
const {
|
|
5237
|
+
commitment,
|
|
5238
|
+
config
|
|
5239
|
+
} = extractCommitmentFromConfig(commitmentOrConfig);
|
|
5240
|
+
|
|
5241
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment, undefined
|
|
5242
|
+
/* encoding */
|
|
5243
|
+
, { ...config,
|
|
5244
|
+
epoch: epoch != null ? epoch : config === null || config === void 0 ? void 0 : config.epoch
|
|
5245
|
+
});
|
|
5246
|
+
|
|
5247
|
+
const unsafeRes = await this._rpcRequest('getStakeActivation', args);
|
|
5248
|
+
const res = superstruct.create(unsafeRes, jsonRpcResult(StakeActivationResult));
|
|
5249
|
+
|
|
5250
|
+
if ('error' in res) {
|
|
5251
|
+
throw new SolanaJSONRPCError(res.error, `failed to get Stake Activation ${publicKey.toBase58()}`);
|
|
5252
|
+
}
|
|
5253
|
+
|
|
5254
|
+
return res.result;
|
|
5255
|
+
}
|
|
5256
|
+
/**
|
|
5257
|
+
* Fetch all the accounts owned by the specified program id
|
|
5258
|
+
*
|
|
5259
|
+
* @return {Promise<Array<{pubkey: PublicKey, account: AccountInfo<Buffer>}>>}
|
|
5260
|
+
*/
|
|
5261
|
+
|
|
5262
|
+
|
|
5263
|
+
async getProgramAccounts(programId, configOrCommitment) {
|
|
5264
|
+
const {
|
|
5265
|
+
commitment,
|
|
5266
|
+
config
|
|
5267
|
+
} = extractCommitmentFromConfig(configOrCommitment);
|
|
5268
|
+
const {
|
|
5269
|
+
encoding,
|
|
5270
|
+
...configWithoutEncoding
|
|
5271
|
+
} = config || {};
|
|
5272
|
+
|
|
5273
|
+
const args = this._buildArgs([programId.toBase58()], commitment, encoding || 'base64', configWithoutEncoding);
|
|
5274
|
+
|
|
5275
|
+
const unsafeRes = await this._rpcRequest('getProgramAccounts', args);
|
|
5276
|
+
const res = superstruct.create(unsafeRes, jsonRpcResult(superstruct.array(KeyedAccountInfoResult)));
|
|
5277
|
+
|
|
5278
|
+
if ('error' in res) {
|
|
5279
|
+
throw new SolanaJSONRPCError(res.error, `failed to get accounts owned by program ${programId.toBase58()}`);
|
|
5280
|
+
}
|
|
5281
|
+
|
|
5282
|
+
return res.result;
|
|
5283
|
+
}
|
|
5284
|
+
/**
|
|
5285
|
+
* Fetch and parse all the accounts owned by the specified program id
|
|
5286
|
+
*
|
|
5287
|
+
* @return {Promise<Array<{pubkey: PublicKey, account: AccountInfo<Buffer | ParsedAccountData>}>>}
|
|
5288
|
+
*/
|
|
5289
|
+
|
|
5290
|
+
|
|
5291
|
+
async getParsedProgramAccounts(programId, configOrCommitment) {
|
|
5292
|
+
const {
|
|
5293
|
+
commitment,
|
|
5294
|
+
config
|
|
5295
|
+
} = extractCommitmentFromConfig(configOrCommitment);
|
|
5296
|
+
|
|
5297
|
+
const args = this._buildArgs([programId.toBase58()], commitment, 'jsonParsed', config);
|
|
5298
|
+
|
|
5299
|
+
const unsafeRes = await this._rpcRequest('getProgramAccounts', args);
|
|
5300
|
+
const res = superstruct.create(unsafeRes, jsonRpcResult(superstruct.array(KeyedParsedAccountInfoResult)));
|
|
5301
|
+
|
|
5302
|
+
if ('error' in res) {
|
|
5303
|
+
throw new SolanaJSONRPCError(res.error, `failed to get accounts owned by program ${programId.toBase58()}`);
|
|
5304
|
+
}
|
|
5305
|
+
|
|
5306
|
+
return res.result;
|
|
5307
|
+
}
|
|
5308
|
+
|
|
5309
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
5310
|
+
async confirmTransaction(strategy, commitment) {
|
|
5311
|
+
let rawSignature;
|
|
5312
|
+
|
|
5313
|
+
if (typeof strategy == 'string') {
|
|
5314
|
+
rawSignature = strategy;
|
|
5315
|
+
} else {
|
|
5316
|
+
var _config$abortSignal;
|
|
5317
|
+
|
|
5318
|
+
const config = strategy;
|
|
5319
|
+
|
|
5320
|
+
if ((_config$abortSignal = config.abortSignal) !== null && _config$abortSignal !== void 0 && _config$abortSignal.aborted) {
|
|
5321
|
+
return Promise.reject(config.abortSignal.reason);
|
|
5322
|
+
}
|
|
5323
|
+
|
|
5324
|
+
rawSignature = config.signature;
|
|
5325
|
+
}
|
|
5326
|
+
|
|
5327
|
+
let decodedSignature;
|
|
5328
|
+
|
|
5329
|
+
try {
|
|
5330
|
+
decodedSignature = bs58__default["default"].decode(rawSignature);
|
|
5331
|
+
} catch (err) {
|
|
5332
|
+
throw new Error('signature must be base58 encoded: ' + rawSignature);
|
|
5333
|
+
}
|
|
5334
|
+
|
|
5335
|
+
assert(decodedSignature.length === 64, 'signature has invalid length');
|
|
5336
|
+
|
|
5337
|
+
if (typeof strategy === 'string') {
|
|
5338
|
+
return await this.confirmTransactionUsingLegacyTimeoutStrategy({
|
|
5339
|
+
commitment: commitment || this.commitment,
|
|
5340
|
+
signature: rawSignature
|
|
5341
|
+
});
|
|
5342
|
+
} else if ('lastValidBlockHeight' in strategy) {
|
|
5343
|
+
return await this.confirmTransactionUsingBlockHeightExceedanceStrategy({
|
|
5344
|
+
commitment: commitment || this.commitment,
|
|
5345
|
+
strategy
|
|
5346
|
+
});
|
|
5347
|
+
} else {
|
|
5348
|
+
return await this.confirmTransactionUsingDurableNonceStrategy({
|
|
5349
|
+
commitment: commitment || this.commitment,
|
|
5350
|
+
strategy
|
|
5351
|
+
});
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5354
|
+
|
|
5355
|
+
getCancellationPromise(signal) {
|
|
5356
|
+
return new Promise((_, reject) => {
|
|
5357
|
+
if (signal == null) {
|
|
5358
|
+
return;
|
|
5359
|
+
}
|
|
5360
|
+
|
|
5361
|
+
if (signal.aborted) {
|
|
5362
|
+
reject(signal.reason);
|
|
5363
|
+
} else {
|
|
5364
|
+
signal.addEventListener('abort', () => {
|
|
5365
|
+
reject(signal.reason);
|
|
5366
|
+
});
|
|
5367
|
+
}
|
|
5368
|
+
});
|
|
5369
|
+
}
|
|
5370
|
+
|
|
5371
|
+
getTransactionConfirmationPromise({
|
|
5372
|
+
commitment,
|
|
5373
|
+
signature
|
|
5374
|
+
}) {
|
|
5375
|
+
let signatureSubscriptionId;
|
|
5376
|
+
let disposeSignatureSubscriptionStateChangeObserver;
|
|
5377
|
+
let done = false;
|
|
5378
|
+
const confirmationPromise = new Promise((resolve, reject) => {
|
|
5379
|
+
try {
|
|
5380
|
+
signatureSubscriptionId = this.onSignature(signature, (result, context) => {
|
|
5381
|
+
signatureSubscriptionId = undefined;
|
|
5382
|
+
const response = {
|
|
5383
|
+
context,
|
|
5384
|
+
value: result
|
|
5385
|
+
};
|
|
5386
|
+
resolve({
|
|
5387
|
+
__type: exports.TransactionStatus.PROCESSED,
|
|
5388
|
+
response
|
|
5389
|
+
});
|
|
5390
|
+
}, commitment);
|
|
5391
|
+
const subscriptionSetupPromise = new Promise(resolveSubscriptionSetup => {
|
|
5392
|
+
if (signatureSubscriptionId == null) {
|
|
5393
|
+
resolveSubscriptionSetup();
|
|
5394
|
+
} else {
|
|
5395
|
+
disposeSignatureSubscriptionStateChangeObserver = this._onSubscriptionStateChange(signatureSubscriptionId, nextState => {
|
|
5396
|
+
if (nextState === 'subscribed') {
|
|
5397
|
+
resolveSubscriptionSetup();
|
|
5398
|
+
}
|
|
5399
|
+
});
|
|
5400
|
+
}
|
|
5401
|
+
});
|
|
5402
|
+
|
|
5403
|
+
(async () => {
|
|
5404
|
+
await subscriptionSetupPromise;
|
|
5405
|
+
if (done) return;
|
|
5406
|
+
const response = await this.getSignatureStatus(signature);
|
|
5407
|
+
if (done) return;
|
|
5408
|
+
|
|
5409
|
+
if (response == null) {
|
|
5410
|
+
return;
|
|
5411
|
+
}
|
|
5412
|
+
|
|
5413
|
+
const {
|
|
5414
|
+
context,
|
|
5415
|
+
value
|
|
5416
|
+
} = response;
|
|
5417
|
+
|
|
5418
|
+
if (value == null) {
|
|
5419
|
+
return;
|
|
5420
|
+
}
|
|
5421
|
+
|
|
5422
|
+
if (value !== null && value !== void 0 && value.err) {
|
|
5423
|
+
reject(value.err);
|
|
5424
|
+
} else {
|
|
5425
|
+
switch (commitment) {
|
|
5426
|
+
case 'confirmed':
|
|
5427
|
+
case 'single':
|
|
5428
|
+
case 'singleGossip':
|
|
5429
|
+
{
|
|
5430
|
+
if (value.confirmationStatus === 'processed') {
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
5433
|
+
|
|
5434
|
+
break;
|
|
5435
|
+
}
|
|
5436
|
+
|
|
5437
|
+
case 'finalized':
|
|
5438
|
+
case 'max':
|
|
5439
|
+
case 'root':
|
|
5440
|
+
{
|
|
5441
|
+
if (value.confirmationStatus === 'processed' || value.confirmationStatus === 'confirmed') {
|
|
5442
|
+
return;
|
|
5443
|
+
}
|
|
5444
|
+
|
|
5445
|
+
break;
|
|
5446
|
+
}
|
|
5447
|
+
// exhaust enums to ensure full coverage
|
|
5448
|
+
|
|
5449
|
+
case 'processed':
|
|
5450
|
+
case 'recent':
|
|
5451
|
+
}
|
|
5452
|
+
|
|
5453
|
+
done = true;
|
|
5454
|
+
resolve({
|
|
5455
|
+
__type: exports.TransactionStatus.PROCESSED,
|
|
5456
|
+
response: {
|
|
5457
|
+
context,
|
|
5458
|
+
value
|
|
5459
|
+
}
|
|
5460
|
+
});
|
|
5461
|
+
}
|
|
5462
|
+
})();
|
|
5463
|
+
} catch (err) {
|
|
5464
|
+
reject(err);
|
|
5465
|
+
}
|
|
5466
|
+
});
|
|
5467
|
+
|
|
5468
|
+
const abortConfirmation = () => {
|
|
5469
|
+
if (disposeSignatureSubscriptionStateChangeObserver) {
|
|
5470
|
+
disposeSignatureSubscriptionStateChangeObserver();
|
|
5471
|
+
disposeSignatureSubscriptionStateChangeObserver = undefined;
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5474
|
+
if (signatureSubscriptionId != null) {
|
|
5475
|
+
this.removeSignatureListener(signatureSubscriptionId);
|
|
5476
|
+
signatureSubscriptionId = undefined;
|
|
5477
|
+
}
|
|
5478
|
+
};
|
|
5479
|
+
|
|
5480
|
+
return {
|
|
5481
|
+
abortConfirmation,
|
|
5482
|
+
confirmationPromise
|
|
5483
|
+
};
|
|
5484
|
+
}
|
|
5485
|
+
|
|
5486
|
+
async confirmTransactionUsingBlockHeightExceedanceStrategy({
|
|
5487
|
+
commitment,
|
|
5488
|
+
strategy: {
|
|
5489
|
+
abortSignal,
|
|
5490
|
+
lastValidBlockHeight,
|
|
5491
|
+
signature
|
|
5492
|
+
}
|
|
5493
|
+
}) {
|
|
5494
|
+
let done = false;
|
|
5495
|
+
const expiryPromise = new Promise(resolve => {
|
|
5496
|
+
const checkBlockHeight = async () => {
|
|
5497
|
+
try {
|
|
5498
|
+
const blockHeight = await this.getBlockHeight(commitment);
|
|
5499
|
+
return blockHeight;
|
|
5500
|
+
} catch (_e) {
|
|
5501
|
+
return -1;
|
|
5502
|
+
}
|
|
5503
|
+
};
|
|
5504
|
+
|
|
5505
|
+
(async () => {
|
|
5506
|
+
let currentBlockHeight = await checkBlockHeight();
|
|
5507
|
+
if (done) return;
|
|
5508
|
+
|
|
5509
|
+
while (currentBlockHeight <= lastValidBlockHeight) {
|
|
5510
|
+
await sleep(1000);
|
|
5511
|
+
if (done) return;
|
|
5512
|
+
currentBlockHeight = await checkBlockHeight();
|
|
5513
|
+
if (done) return;
|
|
5514
|
+
}
|
|
5515
|
+
|
|
5516
|
+
resolve({
|
|
5517
|
+
__type: exports.TransactionStatus.BLOCKHEIGHT_EXCEEDED
|
|
5518
|
+
});
|
|
5519
|
+
})();
|
|
5520
|
+
});
|
|
4572
5521
|
const {
|
|
5522
|
+
abortConfirmation,
|
|
5523
|
+
confirmationPromise
|
|
5524
|
+
} = this.getTransactionConfirmationPromise({
|
|
4573
5525
|
commitment,
|
|
4574
|
-
|
|
4575
|
-
} = extractCommitmentFromConfig(commitmentOrConfig);
|
|
4576
|
-
|
|
4577
|
-
const args = this._buildArgs([publicKey.toBase58()], commitment, undefined
|
|
4578
|
-
/* encoding */
|
|
4579
|
-
, { ...config,
|
|
4580
|
-
epoch: epoch != null ? epoch : config === null || config === void 0 ? void 0 : config.epoch
|
|
5526
|
+
signature
|
|
4581
5527
|
});
|
|
5528
|
+
const cancellationPromise = this.getCancellationPromise(abortSignal);
|
|
5529
|
+
let result;
|
|
4582
5530
|
|
|
4583
|
-
|
|
4584
|
-
|
|
5531
|
+
try {
|
|
5532
|
+
const outcome = await Promise.race([cancellationPromise, confirmationPromise, expiryPromise]);
|
|
4585
5533
|
|
|
4586
|
-
|
|
4587
|
-
|
|
5534
|
+
if (outcome.__type === exports.TransactionStatus.PROCESSED) {
|
|
5535
|
+
result = outcome.response;
|
|
5536
|
+
} else {
|
|
5537
|
+
throw new TransactionExpiredBlockheightExceededError(signature);
|
|
5538
|
+
}
|
|
5539
|
+
} finally {
|
|
5540
|
+
done = true;
|
|
5541
|
+
abortConfirmation();
|
|
4588
5542
|
}
|
|
4589
5543
|
|
|
4590
|
-
return
|
|
5544
|
+
return result;
|
|
4591
5545
|
}
|
|
4592
|
-
/**
|
|
4593
|
-
* Fetch all the accounts owned by the specified program id
|
|
4594
|
-
*
|
|
4595
|
-
* @return {Promise<Array<{pubkey: PublicKey, account: AccountInfo<Buffer>}>>}
|
|
4596
|
-
*/
|
|
4597
5546
|
|
|
5547
|
+
async confirmTransactionUsingDurableNonceStrategy({
|
|
5548
|
+
commitment,
|
|
5549
|
+
strategy: {
|
|
5550
|
+
abortSignal,
|
|
5551
|
+
minContextSlot,
|
|
5552
|
+
nonceAccountPubkey,
|
|
5553
|
+
nonceValue,
|
|
5554
|
+
signature
|
|
5555
|
+
}
|
|
5556
|
+
}) {
|
|
5557
|
+
let done = false;
|
|
5558
|
+
const expiryPromise = new Promise(resolve => {
|
|
5559
|
+
let currentNonceValue = nonceValue;
|
|
5560
|
+
let lastCheckedSlot = null;
|
|
5561
|
+
|
|
5562
|
+
const getCurrentNonceValue = async () => {
|
|
5563
|
+
try {
|
|
5564
|
+
const {
|
|
5565
|
+
context,
|
|
5566
|
+
value: nonceAccount
|
|
5567
|
+
} = await this.getNonceAndContext(nonceAccountPubkey, {
|
|
5568
|
+
commitment,
|
|
5569
|
+
minContextSlot
|
|
5570
|
+
});
|
|
5571
|
+
lastCheckedSlot = context.slot;
|
|
5572
|
+
return nonceAccount === null || nonceAccount === void 0 ? void 0 : nonceAccount.nonce;
|
|
5573
|
+
} catch (e) {
|
|
5574
|
+
// If for whatever reason we can't reach/read the nonce
|
|
5575
|
+
// account, just keep using the last-known value.
|
|
5576
|
+
return currentNonceValue;
|
|
5577
|
+
}
|
|
5578
|
+
};
|
|
5579
|
+
|
|
5580
|
+
(async () => {
|
|
5581
|
+
currentNonceValue = await getCurrentNonceValue();
|
|
5582
|
+
if (done) return;
|
|
4598
5583
|
|
|
4599
|
-
|
|
5584
|
+
while (true // eslint-disable-line no-constant-condition
|
|
5585
|
+
) {
|
|
5586
|
+
if (nonceValue !== currentNonceValue) {
|
|
5587
|
+
resolve({
|
|
5588
|
+
__type: exports.TransactionStatus.NONCE_INVALID,
|
|
5589
|
+
slotInWhichNonceDidAdvance: lastCheckedSlot
|
|
5590
|
+
});
|
|
5591
|
+
return;
|
|
5592
|
+
}
|
|
5593
|
+
|
|
5594
|
+
await sleep(2000);
|
|
5595
|
+
if (done) return;
|
|
5596
|
+
currentNonceValue = await getCurrentNonceValue();
|
|
5597
|
+
if (done) return;
|
|
5598
|
+
}
|
|
5599
|
+
})();
|
|
5600
|
+
});
|
|
4600
5601
|
const {
|
|
5602
|
+
abortConfirmation,
|
|
5603
|
+
confirmationPromise
|
|
5604
|
+
} = this.getTransactionConfirmationPromise({
|
|
4601
5605
|
commitment,
|
|
4602
|
-
|
|
4603
|
-
}
|
|
4604
|
-
const
|
|
4605
|
-
|
|
4606
|
-
...configWithoutEncoding
|
|
4607
|
-
} = config || {};
|
|
4608
|
-
|
|
4609
|
-
const args = this._buildArgs([programId.toBase58()], commitment, encoding || 'base64', configWithoutEncoding);
|
|
5606
|
+
signature
|
|
5607
|
+
});
|
|
5608
|
+
const cancellationPromise = this.getCancellationPromise(abortSignal);
|
|
5609
|
+
let result;
|
|
4610
5610
|
|
|
4611
|
-
|
|
4612
|
-
|
|
5611
|
+
try {
|
|
5612
|
+
const outcome = await Promise.race([cancellationPromise, confirmationPromise, expiryPromise]);
|
|
4613
5613
|
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
5614
|
+
if (outcome.__type === exports.TransactionStatus.PROCESSED) {
|
|
5615
|
+
result = outcome.response;
|
|
5616
|
+
} else {
|
|
5617
|
+
var _signatureStatus;
|
|
4617
5618
|
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
/**
|
|
4621
|
-
* Fetch and parse all the accounts owned by the specified program id
|
|
4622
|
-
*
|
|
4623
|
-
* @return {Promise<Array<{pubkey: PublicKey, account: AccountInfo<Buffer | ParsedAccountData>}>>}
|
|
4624
|
-
*/
|
|
5619
|
+
// Double check that the transaction is indeed unconfirmed.
|
|
5620
|
+
let signatureStatus;
|
|
4625
5621
|
|
|
5622
|
+
while (true // eslint-disable-line no-constant-condition
|
|
5623
|
+
) {
|
|
5624
|
+
var _outcome$slotInWhichN;
|
|
4626
5625
|
|
|
4627
|
-
|
|
4628
|
-
const {
|
|
4629
|
-
commitment,
|
|
4630
|
-
config
|
|
4631
|
-
} = extractCommitmentFromConfig(configOrCommitment);
|
|
5626
|
+
const status = await this.getSignatureStatus(signature);
|
|
4632
5627
|
|
|
4633
|
-
|
|
5628
|
+
if (status == null) {
|
|
5629
|
+
break;
|
|
5630
|
+
}
|
|
4634
5631
|
|
|
4635
|
-
|
|
4636
|
-
|
|
5632
|
+
if (status.context.slot < ((_outcome$slotInWhichN = outcome.slotInWhichNonceDidAdvance) !== null && _outcome$slotInWhichN !== void 0 ? _outcome$slotInWhichN : minContextSlot)) {
|
|
5633
|
+
await sleep(400);
|
|
5634
|
+
continue;
|
|
5635
|
+
}
|
|
4637
5636
|
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
5637
|
+
signatureStatus = status;
|
|
5638
|
+
break;
|
|
5639
|
+
}
|
|
4641
5640
|
|
|
4642
|
-
|
|
4643
|
-
|
|
5641
|
+
if ((_signatureStatus = signatureStatus) !== null && _signatureStatus !== void 0 && _signatureStatus.value) {
|
|
5642
|
+
const commitmentForStatus = commitment || 'finalized';
|
|
5643
|
+
const {
|
|
5644
|
+
confirmationStatus
|
|
5645
|
+
} = signatureStatus.value;
|
|
5646
|
+
|
|
5647
|
+
switch (commitmentForStatus) {
|
|
5648
|
+
case 'processed':
|
|
5649
|
+
case 'recent':
|
|
5650
|
+
if (confirmationStatus !== 'processed' && confirmationStatus !== 'confirmed' && confirmationStatus !== 'finalized') {
|
|
5651
|
+
throw new TransactionExpiredNonceInvalidError(signature);
|
|
5652
|
+
}
|
|
4644
5653
|
|
|
4645
|
-
|
|
4646
|
-
async confirmTransaction(strategy, commitment) {
|
|
4647
|
-
let rawSignature;
|
|
5654
|
+
break;
|
|
4648
5655
|
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
5656
|
+
case 'confirmed':
|
|
5657
|
+
case 'single':
|
|
5658
|
+
case 'singleGossip':
|
|
5659
|
+
if (confirmationStatus !== 'confirmed' && confirmationStatus !== 'finalized') {
|
|
5660
|
+
throw new TransactionExpiredNonceInvalidError(signature);
|
|
5661
|
+
}
|
|
4655
5662
|
|
|
4656
|
-
|
|
5663
|
+
break;
|
|
4657
5664
|
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
5665
|
+
case 'finalized':
|
|
5666
|
+
case 'max':
|
|
5667
|
+
case 'root':
|
|
5668
|
+
if (confirmationStatus !== 'finalized') {
|
|
5669
|
+
throw new TransactionExpiredNonceInvalidError(signature);
|
|
5670
|
+
}
|
|
4663
5671
|
|
|
4664
|
-
assert(decodedSignature.length === 64, 'signature has invalid length');
|
|
4665
|
-
const subscriptionCommitment = commitment || this.commitment;
|
|
4666
|
-
let timeoutId;
|
|
4667
|
-
let subscriptionId;
|
|
4668
|
-
let done = false;
|
|
4669
|
-
const confirmationPromise = new Promise((resolve, reject) => {
|
|
4670
|
-
try {
|
|
4671
|
-
subscriptionId = this.onSignature(rawSignature, (result, context) => {
|
|
4672
|
-
subscriptionId = undefined;
|
|
4673
|
-
const response = {
|
|
4674
|
-
context,
|
|
4675
|
-
value: result
|
|
4676
|
-
};
|
|
4677
|
-
done = true;
|
|
4678
|
-
resolve({
|
|
4679
|
-
__type: exports.TransactionStatus.PROCESSED,
|
|
4680
|
-
response
|
|
4681
|
-
});
|
|
4682
|
-
}, subscriptionCommitment);
|
|
4683
|
-
} catch (err) {
|
|
4684
|
-
reject(err);
|
|
4685
|
-
}
|
|
4686
|
-
});
|
|
4687
|
-
const expiryPromise = new Promise(resolve => {
|
|
4688
|
-
if (typeof strategy === 'string') {
|
|
4689
|
-
let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
|
|
4690
|
-
|
|
4691
|
-
switch (subscriptionCommitment) {
|
|
4692
|
-
case 'processed':
|
|
4693
|
-
case 'recent':
|
|
4694
|
-
case 'single':
|
|
4695
|
-
case 'confirmed':
|
|
4696
|
-
case 'singleGossip':
|
|
4697
|
-
{
|
|
4698
|
-
timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
|
|
4699
5672
|
break;
|
|
4700
|
-
}
|
|
4701
|
-
}
|
|
4702
5673
|
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
} else {
|
|
4708
|
-
let config = strategy;
|
|
5674
|
+
default:
|
|
5675
|
+
// Exhaustive switch.
|
|
5676
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5677
|
+
(_ => {})(commitmentForStatus);
|
|
4709
5678
|
|
|
4710
|
-
const checkBlockHeight = async () => {
|
|
4711
|
-
try {
|
|
4712
|
-
const blockHeight = await this.getBlockHeight(commitment);
|
|
4713
|
-
return blockHeight;
|
|
4714
|
-
} catch (_e) {
|
|
4715
|
-
return -1;
|
|
4716
5679
|
}
|
|
4717
|
-
};
|
|
4718
5680
|
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
5681
|
+
result = {
|
|
5682
|
+
context: signatureStatus.context,
|
|
5683
|
+
value: {
|
|
5684
|
+
err: signatureStatus.value.err
|
|
5685
|
+
}
|
|
5686
|
+
};
|
|
5687
|
+
} else {
|
|
5688
|
+
throw new TransactionExpiredNonceInvalidError(signature);
|
|
5689
|
+
}
|
|
5690
|
+
}
|
|
5691
|
+
} finally {
|
|
5692
|
+
done = true;
|
|
5693
|
+
abortConfirmation();
|
|
5694
|
+
}
|
|
4722
5695
|
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
if (done) return;
|
|
4726
|
-
currentBlockHeight = await checkBlockHeight();
|
|
4727
|
-
if (done) return;
|
|
4728
|
-
}
|
|
5696
|
+
return result;
|
|
5697
|
+
}
|
|
4729
5698
|
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
5699
|
+
async confirmTransactionUsingLegacyTimeoutStrategy({
|
|
5700
|
+
commitment,
|
|
5701
|
+
signature
|
|
5702
|
+
}) {
|
|
5703
|
+
let timeoutId;
|
|
5704
|
+
const expiryPromise = new Promise(resolve => {
|
|
5705
|
+
let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
|
|
5706
|
+
|
|
5707
|
+
switch (commitment) {
|
|
5708
|
+
case 'processed':
|
|
5709
|
+
case 'recent':
|
|
5710
|
+
case 'single':
|
|
5711
|
+
case 'confirmed':
|
|
5712
|
+
case 'singleGossip':
|
|
5713
|
+
{
|
|
5714
|
+
timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
|
|
5715
|
+
break;
|
|
5716
|
+
}
|
|
4734
5717
|
}
|
|
5718
|
+
|
|
5719
|
+
timeoutId = setTimeout(() => resolve({
|
|
5720
|
+
__type: exports.TransactionStatus.TIMED_OUT,
|
|
5721
|
+
timeoutMs
|
|
5722
|
+
}), timeoutMs);
|
|
5723
|
+
});
|
|
5724
|
+
const {
|
|
5725
|
+
abortConfirmation,
|
|
5726
|
+
confirmationPromise
|
|
5727
|
+
} = this.getTransactionConfirmationPromise({
|
|
5728
|
+
commitment,
|
|
5729
|
+
signature
|
|
4735
5730
|
});
|
|
4736
5731
|
let result;
|
|
4737
5732
|
|
|
4738
5733
|
try {
|
|
4739
5734
|
const outcome = await Promise.race([confirmationPromise, expiryPromise]);
|
|
4740
5735
|
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
case exports.TransactionStatus.PROCESSED:
|
|
4746
|
-
result = outcome.response;
|
|
4747
|
-
break;
|
|
4748
|
-
|
|
4749
|
-
case exports.TransactionStatus.TIMED_OUT:
|
|
4750
|
-
throw new TransactionExpiredTimeoutError(rawSignature, outcome.timeoutMs / 1000);
|
|
5736
|
+
if (outcome.__type === exports.TransactionStatus.PROCESSED) {
|
|
5737
|
+
result = outcome.response;
|
|
5738
|
+
} else {
|
|
5739
|
+
throw new TransactionExpiredTimeoutError(signature, outcome.timeoutMs / 1000);
|
|
4751
5740
|
}
|
|
4752
5741
|
} finally {
|
|
4753
5742
|
clearTimeout(timeoutId);
|
|
4754
|
-
|
|
4755
|
-
if (subscriptionId) {
|
|
4756
|
-
this.removeSignatureListener(subscriptionId);
|
|
4757
|
-
}
|
|
5743
|
+
abortConfirmation();
|
|
4758
5744
|
}
|
|
4759
5745
|
|
|
4760
5746
|
return result;
|
|
@@ -5120,7 +6106,7 @@ class Connection {
|
|
|
5120
6106
|
|
|
5121
6107
|
|
|
5122
6108
|
async getFeeForMessage(message, commitment) {
|
|
5123
|
-
const wireMessage = message.serialize().toString('base64');
|
|
6109
|
+
const wireMessage = toBuffer(message.serialize()).toString('base64');
|
|
5124
6110
|
|
|
5125
6111
|
const args = this._buildArgs([wireMessage], commitment);
|
|
5126
6112
|
|
|
@@ -5128,7 +6114,7 @@ class Connection {
|
|
|
5128
6114
|
const res = superstruct.create(unsafeRes, jsonRpcResultAndContext(superstruct.nullable(superstruct.number())));
|
|
5129
6115
|
|
|
5130
6116
|
if ('error' in res) {
|
|
5131
|
-
throw new SolanaJSONRPCError(res.error, 'failed to get
|
|
6117
|
+
throw new SolanaJSONRPCError(res.error, 'failed to get fee for message');
|
|
5132
6118
|
}
|
|
5133
6119
|
|
|
5134
6120
|
if (res.result === null) {
|
|
@@ -5224,9 +6210,16 @@ class Connection {
|
|
|
5224
6210
|
}
|
|
5225
6211
|
/**
|
|
5226
6212
|
* Fetch a processed block from the cluster.
|
|
6213
|
+
*
|
|
6214
|
+
* @deprecated Instead, call `getBlock` using a `GetVersionedBlockConfig` by
|
|
6215
|
+
* setting the `maxSupportedTransactionVersion` property.
|
|
5227
6216
|
*/
|
|
5228
6217
|
|
|
5229
6218
|
|
|
6219
|
+
/**
|
|
6220
|
+
* Fetch a processed block from the cluster.
|
|
6221
|
+
*/
|
|
6222
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
5230
6223
|
async getBlock(slot, rawConfig) {
|
|
5231
6224
|
const {
|
|
5232
6225
|
commitment,
|
|
@@ -5238,28 +6231,115 @@ class Connection {
|
|
|
5238
6231
|
, config);
|
|
5239
6232
|
|
|
5240
6233
|
const unsafeRes = await this._rpcRequest('getBlock', args);
|
|
5241
|
-
const res = superstruct.create(unsafeRes, GetBlockRpcResult);
|
|
5242
6234
|
|
|
5243
|
-
|
|
5244
|
-
|
|
6235
|
+
try {
|
|
6236
|
+
switch (config === null || config === void 0 ? void 0 : config.transactionDetails) {
|
|
6237
|
+
case 'accounts':
|
|
6238
|
+
{
|
|
6239
|
+
const res = superstruct.create(unsafeRes, GetAccountsModeBlockRpcResult);
|
|
6240
|
+
|
|
6241
|
+
if ('error' in res) {
|
|
6242
|
+
throw res.error;
|
|
6243
|
+
}
|
|
6244
|
+
|
|
6245
|
+
return res.result;
|
|
6246
|
+
}
|
|
6247
|
+
|
|
6248
|
+
case 'none':
|
|
6249
|
+
{
|
|
6250
|
+
const res = superstruct.create(unsafeRes, GetNoneModeBlockRpcResult);
|
|
6251
|
+
|
|
6252
|
+
if ('error' in res) {
|
|
6253
|
+
throw res.error;
|
|
6254
|
+
}
|
|
6255
|
+
|
|
6256
|
+
return res.result;
|
|
6257
|
+
}
|
|
6258
|
+
|
|
6259
|
+
default:
|
|
6260
|
+
{
|
|
6261
|
+
const res = superstruct.create(unsafeRes, GetBlockRpcResult);
|
|
6262
|
+
|
|
6263
|
+
if ('error' in res) {
|
|
6264
|
+
throw res.error;
|
|
6265
|
+
}
|
|
6266
|
+
|
|
6267
|
+
const {
|
|
6268
|
+
result
|
|
6269
|
+
} = res;
|
|
6270
|
+
return result ? { ...result,
|
|
6271
|
+
transactions: result.transactions.map(({
|
|
6272
|
+
transaction,
|
|
6273
|
+
meta,
|
|
6274
|
+
version
|
|
6275
|
+
}) => ({
|
|
6276
|
+
meta,
|
|
6277
|
+
transaction: { ...transaction,
|
|
6278
|
+
message: versionedMessageFromResponse(version, transaction.message)
|
|
6279
|
+
},
|
|
6280
|
+
version
|
|
6281
|
+
}))
|
|
6282
|
+
} : null;
|
|
6283
|
+
}
|
|
6284
|
+
}
|
|
6285
|
+
} catch (e) {
|
|
6286
|
+
throw new SolanaJSONRPCError(e, 'failed to get confirmed block');
|
|
5245
6287
|
}
|
|
6288
|
+
}
|
|
6289
|
+
/**
|
|
6290
|
+
* Fetch parsed transaction details for a confirmed or finalized block
|
|
6291
|
+
*/
|
|
5246
6292
|
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
6293
|
+
|
|
6294
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6295
|
+
async getParsedBlock(slot, rawConfig) {
|
|
6296
|
+
const {
|
|
6297
|
+
commitment,
|
|
6298
|
+
config
|
|
6299
|
+
} = extractCommitmentFromConfig(rawConfig);
|
|
6300
|
+
|
|
6301
|
+
const args = this._buildArgsAtLeastConfirmed([slot], commitment, 'jsonParsed', config);
|
|
6302
|
+
|
|
6303
|
+
const unsafeRes = await this._rpcRequest('getBlock', args);
|
|
6304
|
+
|
|
6305
|
+
try {
|
|
6306
|
+
switch (config === null || config === void 0 ? void 0 : config.transactionDetails) {
|
|
6307
|
+
case 'accounts':
|
|
6308
|
+
{
|
|
6309
|
+
const res = superstruct.create(unsafeRes, GetParsedAccountsModeBlockRpcResult);
|
|
6310
|
+
|
|
6311
|
+
if ('error' in res) {
|
|
6312
|
+
throw res.error;
|
|
6313
|
+
}
|
|
6314
|
+
|
|
6315
|
+
return res.result;
|
|
5259
6316
|
}
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
6317
|
+
|
|
6318
|
+
case 'none':
|
|
6319
|
+
{
|
|
6320
|
+
const res = superstruct.create(unsafeRes, GetParsedNoneModeBlockRpcResult);
|
|
6321
|
+
|
|
6322
|
+
if ('error' in res) {
|
|
6323
|
+
throw res.error;
|
|
6324
|
+
}
|
|
6325
|
+
|
|
6326
|
+
return res.result;
|
|
6327
|
+
}
|
|
6328
|
+
|
|
6329
|
+
default:
|
|
6330
|
+
{
|
|
6331
|
+
const res = superstruct.create(unsafeRes, GetParsedBlockRpcResult);
|
|
6332
|
+
|
|
6333
|
+
if ('error' in res) {
|
|
6334
|
+
throw res.error;
|
|
6335
|
+
}
|
|
6336
|
+
|
|
6337
|
+
return res.result;
|
|
6338
|
+
}
|
|
6339
|
+
}
|
|
6340
|
+
} catch (e) {
|
|
6341
|
+
throw new SolanaJSONRPCError(e, 'failed to get block');
|
|
6342
|
+
}
|
|
5263
6343
|
}
|
|
5264
6344
|
/*
|
|
5265
6345
|
* Returns the current block height of the node
|
|
@@ -5318,9 +6398,17 @@ class Connection {
|
|
|
5318
6398
|
}
|
|
5319
6399
|
/**
|
|
5320
6400
|
* Fetch a confirmed or finalized transaction from the cluster.
|
|
6401
|
+
*
|
|
6402
|
+
* @deprecated Instead, call `getTransaction` using a
|
|
6403
|
+
* `GetVersionedTransactionConfig` by setting the
|
|
6404
|
+
* `maxSupportedTransactionVersion` property.
|
|
5321
6405
|
*/
|
|
5322
6406
|
|
|
5323
6407
|
|
|
6408
|
+
/**
|
|
6409
|
+
* Fetch a confirmed or finalized transaction from the cluster.
|
|
6410
|
+
*/
|
|
6411
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
5324
6412
|
async getTransaction(signature, rawConfig) {
|
|
5325
6413
|
const {
|
|
5326
6414
|
commitment,
|
|
@@ -5342,7 +6430,7 @@ class Connection {
|
|
|
5342
6430
|
if (!result) return result;
|
|
5343
6431
|
return { ...result,
|
|
5344
6432
|
transaction: { ...result.transaction,
|
|
5345
|
-
message:
|
|
6433
|
+
message: versionedMessageFromResponse(result.version, result.transaction.message)
|
|
5346
6434
|
}
|
|
5347
6435
|
};
|
|
5348
6436
|
}
|
|
@@ -5401,9 +6489,19 @@ class Connection {
|
|
|
5401
6489
|
/**
|
|
5402
6490
|
* Fetch transaction details for a batch of confirmed transactions.
|
|
5403
6491
|
* Similar to {@link getParsedTransactions} but returns a {@link TransactionResponse}.
|
|
6492
|
+
*
|
|
6493
|
+
* @deprecated Instead, call `getTransactions` using a
|
|
6494
|
+
* `GetVersionedTransactionConfig` by setting the
|
|
6495
|
+
* `maxSupportedTransactionVersion` property.
|
|
5404
6496
|
*/
|
|
5405
6497
|
|
|
5406
6498
|
|
|
6499
|
+
/**
|
|
6500
|
+
* Fetch transaction details for a batch of confirmed transactions.
|
|
6501
|
+
* Similar to {@link getParsedTransactions} but returns a {@link
|
|
6502
|
+
* VersionedTransactionResponse}.
|
|
6503
|
+
*/
|
|
6504
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
5407
6505
|
async getTransactions(signatures, commitmentOrConfig) {
|
|
5408
6506
|
const {
|
|
5409
6507
|
commitment,
|
|
@@ -5431,7 +6529,7 @@ class Connection {
|
|
|
5431
6529
|
if (!result) return result;
|
|
5432
6530
|
return { ...result,
|
|
5433
6531
|
transaction: { ...result.transaction,
|
|
5434
|
-
message:
|
|
6532
|
+
message: versionedMessageFromResponse(result.version, result.transaction.message)
|
|
5435
6533
|
}
|
|
5436
6534
|
};
|
|
5437
6535
|
});
|
|
@@ -5764,11 +6862,11 @@ class Connection {
|
|
|
5764
6862
|
*/
|
|
5765
6863
|
|
|
5766
6864
|
|
|
5767
|
-
async getNonceAndContext(nonceAccount,
|
|
6865
|
+
async getNonceAndContext(nonceAccount, commitmentOrConfig) {
|
|
5768
6866
|
const {
|
|
5769
6867
|
context,
|
|
5770
6868
|
value: accountInfo
|
|
5771
|
-
} = await this.getAccountInfoAndContext(nonceAccount,
|
|
6869
|
+
} = await this.getAccountInfoAndContext(nonceAccount, commitmentOrConfig);
|
|
5772
6870
|
let value = null;
|
|
5773
6871
|
|
|
5774
6872
|
if (accountInfo !== null) {
|
|
@@ -5785,8 +6883,8 @@ class Connection {
|
|
|
5785
6883
|
*/
|
|
5786
6884
|
|
|
5787
6885
|
|
|
5788
|
-
async getNonce(nonceAccount,
|
|
5789
|
-
return await this.getNonceAndContext(nonceAccount,
|
|
6886
|
+
async getNonce(nonceAccount, commitmentOrConfig) {
|
|
6887
|
+
return await this.getNonceAndContext(nonceAccount, commitmentOrConfig).then(x => x.value).catch(e => {
|
|
5790
6888
|
throw new Error('failed to get nonce for account ' + nonceAccount.toBase58() + ': ' + e);
|
|
5791
6889
|
});
|
|
5792
6890
|
}
|
|
@@ -5894,14 +6992,48 @@ class Connection {
|
|
|
5894
6992
|
throw new SolanaJSONRPCError(res.error, `failed to get stake minimum delegation`);
|
|
5895
6993
|
}
|
|
5896
6994
|
|
|
5897
|
-
return res.result;
|
|
5898
|
-
}
|
|
6995
|
+
return res.result;
|
|
6996
|
+
}
|
|
6997
|
+
/**
|
|
6998
|
+
* Simulate a transaction
|
|
6999
|
+
*
|
|
7000
|
+
* @deprecated Instead, call {@link simulateTransaction} with {@link
|
|
7001
|
+
* VersionedTransaction} and {@link SimulateTransactionConfig} parameters
|
|
7002
|
+
*/
|
|
7003
|
+
|
|
7004
|
+
|
|
5899
7005
|
/**
|
|
5900
7006
|
* Simulate a transaction
|
|
5901
7007
|
*/
|
|
7008
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
7009
|
+
async simulateTransaction(transactionOrMessage, configOrSigners, includeAccounts) {
|
|
7010
|
+
if ('message' in transactionOrMessage) {
|
|
7011
|
+
const versionedTx = transactionOrMessage;
|
|
7012
|
+
const wireTransaction = versionedTx.serialize();
|
|
7013
|
+
const encodedTransaction = buffer.Buffer.from(wireTransaction).toString('base64');
|
|
7014
|
+
|
|
7015
|
+
if (Array.isArray(configOrSigners) || includeAccounts !== undefined) {
|
|
7016
|
+
throw new Error('Invalid arguments');
|
|
7017
|
+
}
|
|
7018
|
+
|
|
7019
|
+
const config = configOrSigners || {};
|
|
7020
|
+
config.encoding = 'base64';
|
|
7021
|
+
|
|
7022
|
+
if (!('commitment' in config)) {
|
|
7023
|
+
config.commitment = this.commitment;
|
|
7024
|
+
}
|
|
7025
|
+
|
|
7026
|
+
const args = [encodedTransaction, config];
|
|
7027
|
+
const unsafeRes = await this._rpcRequest('simulateTransaction', args);
|
|
7028
|
+
const res = superstruct.create(unsafeRes, SimulatedTransactionResponseStruct);
|
|
5902
7029
|
|
|
7030
|
+
if ('error' in res) {
|
|
7031
|
+
throw new Error('failed to simulate transaction: ' + res.error.message);
|
|
7032
|
+
}
|
|
7033
|
+
|
|
7034
|
+
return res.result;
|
|
7035
|
+
}
|
|
5903
7036
|
|
|
5904
|
-
async simulateTransaction(transactionOrMessage, signers, includeAccounts) {
|
|
5905
7037
|
let transaction;
|
|
5906
7038
|
|
|
5907
7039
|
if (transactionOrMessage instanceof Transaction) {
|
|
@@ -5917,6 +7049,12 @@ class Connection {
|
|
|
5917
7049
|
transaction._message = transaction._json = undefined;
|
|
5918
7050
|
}
|
|
5919
7051
|
|
|
7052
|
+
if (configOrSigners !== undefined && !Array.isArray(configOrSigners)) {
|
|
7053
|
+
throw new Error('Invalid arguments');
|
|
7054
|
+
}
|
|
7055
|
+
|
|
7056
|
+
const signers = configOrSigners;
|
|
7057
|
+
|
|
5920
7058
|
if (transaction.nonceInfo && signers) {
|
|
5921
7059
|
transaction.sign(...signers);
|
|
5922
7060
|
} else {
|
|
@@ -5997,12 +7135,34 @@ class Connection {
|
|
|
5997
7135
|
|
|
5998
7136
|
return res.result;
|
|
5999
7137
|
}
|
|
7138
|
+
/**
|
|
7139
|
+
* Sign and send a transaction
|
|
7140
|
+
*
|
|
7141
|
+
* @deprecated Instead, call {@link sendTransaction} with a {@link
|
|
7142
|
+
* VersionedTransaction}
|
|
7143
|
+
*/
|
|
7144
|
+
|
|
7145
|
+
|
|
6000
7146
|
/**
|
|
6001
7147
|
* Sign and send a transaction
|
|
6002
7148
|
*/
|
|
7149
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
7150
|
+
async sendTransaction(transaction, signersOrOptions, options) {
|
|
7151
|
+
if ('version' in transaction) {
|
|
7152
|
+
if (signersOrOptions && Array.isArray(signersOrOptions)) {
|
|
7153
|
+
throw new Error('Invalid arguments');
|
|
7154
|
+
}
|
|
6003
7155
|
|
|
7156
|
+
const wireTransaction = transaction.serialize();
|
|
7157
|
+
return await this.sendRawTransaction(wireTransaction, options);
|
|
7158
|
+
}
|
|
7159
|
+
|
|
7160
|
+
if (signersOrOptions === undefined || !Array.isArray(signersOrOptions)) {
|
|
7161
|
+
throw new Error('Invalid arguments');
|
|
7162
|
+
}
|
|
7163
|
+
|
|
7164
|
+
const signers = signersOrOptions;
|
|
6004
7165
|
|
|
6005
|
-
async sendTransaction(transaction, signers, options) {
|
|
6006
7166
|
if (transaction.nonceInfo) {
|
|
6007
7167
|
transaction.sign(...signers);
|
|
6008
7168
|
} else {
|
|
@@ -6125,7 +7285,7 @@ class Connection {
|
|
|
6125
7285
|
|
|
6126
7286
|
_wsOnClose(code) {
|
|
6127
7287
|
this._rpcWebSocketConnected = false;
|
|
6128
|
-
this._rpcWebSocketGeneration
|
|
7288
|
+
this._rpcWebSocketGeneration = (this._rpcWebSocketGeneration + 1) % Number.MAX_SAFE_INTEGER;
|
|
6129
7289
|
|
|
6130
7290
|
if (this._rpcWebSocketIdleTimeout) {
|
|
6131
7291
|
clearTimeout(this._rpcWebSocketIdleTimeout);
|
|
@@ -6147,9 +7307,9 @@ class Connection {
|
|
|
6147
7307
|
|
|
6148
7308
|
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
6149
7309
|
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
6150
|
-
this.
|
|
7310
|
+
this._setSubscription(hash, { ...subscription,
|
|
6151
7311
|
state: 'pending'
|
|
6152
|
-
};
|
|
7312
|
+
});
|
|
6153
7313
|
});
|
|
6154
7314
|
}
|
|
6155
7315
|
/**
|
|
@@ -6157,6 +7317,53 @@ class Connection {
|
|
|
6157
7317
|
*/
|
|
6158
7318
|
|
|
6159
7319
|
|
|
7320
|
+
_setSubscription(hash, nextSubscription) {
|
|
7321
|
+
var _this$_subscriptionsB;
|
|
7322
|
+
|
|
7323
|
+
const prevState = (_this$_subscriptionsB = this._subscriptionsByHash[hash]) === null || _this$_subscriptionsB === void 0 ? void 0 : _this$_subscriptionsB.state;
|
|
7324
|
+
this._subscriptionsByHash[hash] = nextSubscription;
|
|
7325
|
+
|
|
7326
|
+
if (prevState !== nextSubscription.state) {
|
|
7327
|
+
const stateChangeCallbacks = this._subscriptionStateChangeCallbacksByHash[hash];
|
|
7328
|
+
|
|
7329
|
+
if (stateChangeCallbacks) {
|
|
7330
|
+
stateChangeCallbacks.forEach(cb => {
|
|
7331
|
+
try {
|
|
7332
|
+
cb(nextSubscription.state); // eslint-disable-next-line no-empty
|
|
7333
|
+
} catch {}
|
|
7334
|
+
});
|
|
7335
|
+
}
|
|
7336
|
+
}
|
|
7337
|
+
}
|
|
7338
|
+
/**
|
|
7339
|
+
* @internal
|
|
7340
|
+
*/
|
|
7341
|
+
|
|
7342
|
+
|
|
7343
|
+
_onSubscriptionStateChange(clientSubscriptionId, callback) {
|
|
7344
|
+
var _this$_subscriptionSt;
|
|
7345
|
+
|
|
7346
|
+
const hash = this._subscriptionHashByClientSubscriptionId[clientSubscriptionId];
|
|
7347
|
+
|
|
7348
|
+
if (hash == null) {
|
|
7349
|
+
return () => {};
|
|
7350
|
+
}
|
|
7351
|
+
|
|
7352
|
+
const stateChangeCallbacks = (_this$_subscriptionSt = this._subscriptionStateChangeCallbacksByHash)[hash] || (_this$_subscriptionSt[hash] = new Set());
|
|
7353
|
+
stateChangeCallbacks.add(callback);
|
|
7354
|
+
return () => {
|
|
7355
|
+
stateChangeCallbacks.delete(callback);
|
|
7356
|
+
|
|
7357
|
+
if (stateChangeCallbacks.size === 0) {
|
|
7358
|
+
delete this._subscriptionStateChangeCallbacksByHash[hash];
|
|
7359
|
+
}
|
|
7360
|
+
};
|
|
7361
|
+
}
|
|
7362
|
+
/**
|
|
7363
|
+
* @internal
|
|
7364
|
+
*/
|
|
7365
|
+
|
|
7366
|
+
|
|
6160
7367
|
async _updateSubscriptions() {
|
|
6161
7368
|
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
6162
7369
|
if (this._rpcWebSocketConnected) {
|
|
@@ -6242,14 +7449,17 @@ class Connection {
|
|
|
6242
7449
|
} = subscription;
|
|
6243
7450
|
|
|
6244
7451
|
try {
|
|
6245
|
-
this.
|
|
7452
|
+
this._setSubscription(hash, { ...subscription,
|
|
6246
7453
|
state: 'subscribing'
|
|
6247
|
-
};
|
|
7454
|
+
});
|
|
7455
|
+
|
|
6248
7456
|
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
6249
|
-
|
|
7457
|
+
|
|
7458
|
+
this._setSubscription(hash, { ...subscription,
|
|
6250
7459
|
serverSubscriptionId,
|
|
6251
7460
|
state: 'subscribed'
|
|
6252
|
-
};
|
|
7461
|
+
});
|
|
7462
|
+
|
|
6253
7463
|
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
6254
7464
|
await this._updateSubscriptions();
|
|
6255
7465
|
} catch (e) {
|
|
@@ -6262,9 +7472,10 @@ class Connection {
|
|
|
6262
7472
|
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
6263
7473
|
|
|
6264
7474
|
|
|
6265
|
-
this.
|
|
7475
|
+
this._setSubscription(hash, { ...subscription,
|
|
6266
7476
|
state: 'pending'
|
|
6267
|
-
};
|
|
7477
|
+
});
|
|
7478
|
+
|
|
6268
7479
|
await this._updateSubscriptions();
|
|
6269
7480
|
}
|
|
6270
7481
|
})();
|
|
@@ -6293,9 +7504,13 @@ class Connection {
|
|
|
6293
7504
|
*/
|
|
6294
7505
|
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
6295
7506
|
} else {
|
|
6296
|
-
this.
|
|
7507
|
+
this._setSubscription(hash, { ...subscription,
|
|
6297
7508
|
state: 'unsubscribing'
|
|
6298
|
-
};
|
|
7509
|
+
});
|
|
7510
|
+
|
|
7511
|
+
this._setSubscription(hash, { ...subscription,
|
|
7512
|
+
state: 'unsubscribing'
|
|
7513
|
+
});
|
|
6299
7514
|
|
|
6300
7515
|
try {
|
|
6301
7516
|
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
@@ -6309,17 +7524,19 @@ class Connection {
|
|
|
6309
7524
|
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
6310
7525
|
|
|
6311
7526
|
|
|
6312
|
-
this.
|
|
7527
|
+
this._setSubscription(hash, { ...subscription,
|
|
6313
7528
|
state: 'subscribed'
|
|
6314
|
-
};
|
|
7529
|
+
});
|
|
7530
|
+
|
|
6315
7531
|
await this._updateSubscriptions();
|
|
6316
7532
|
return;
|
|
6317
7533
|
}
|
|
6318
7534
|
}
|
|
6319
7535
|
|
|
6320
|
-
this.
|
|
7536
|
+
this._setSubscription(hash, { ...subscription,
|
|
6321
7537
|
state: 'unsubscribed'
|
|
6322
|
-
};
|
|
7538
|
+
});
|
|
7539
|
+
|
|
6323
7540
|
await this._updateSubscriptions();
|
|
6324
7541
|
})();
|
|
6325
7542
|
}
|
|
@@ -6412,8 +7629,11 @@ class Connection {
|
|
|
6412
7629
|
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
6413
7630
|
}
|
|
6414
7631
|
|
|
7632
|
+
this._subscriptionHashByClientSubscriptionId[clientSubscriptionId] = hash;
|
|
7633
|
+
|
|
6415
7634
|
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
6416
7635
|
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7636
|
+
delete this._subscriptionHashByClientSubscriptionId[clientSubscriptionId];
|
|
6417
7637
|
const subscription = this._subscriptionsByHash[hash];
|
|
6418
7638
|
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
6419
7639
|
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
@@ -6858,12 +8078,7 @@ class Keypair {
|
|
|
6858
8078
|
*/
|
|
6859
8079
|
constructor(keypair) {
|
|
6860
8080
|
this._keypair = void 0;
|
|
6861
|
-
|
|
6862
|
-
if (keypair) {
|
|
6863
|
-
this._keypair = keypair;
|
|
6864
|
-
} else {
|
|
6865
|
-
this._keypair = nacl__default["default"].sign.keyPair();
|
|
6866
|
-
}
|
|
8081
|
+
this._keypair = keypair !== null && keypair !== void 0 ? keypair : generateKeypair();
|
|
6867
8082
|
}
|
|
6868
8083
|
/**
|
|
6869
8084
|
* Generate a new random keypair
|
|
@@ -6871,7 +8086,7 @@ class Keypair {
|
|
|
6871
8086
|
|
|
6872
8087
|
|
|
6873
8088
|
static generate() {
|
|
6874
|
-
return new Keypair(
|
|
8089
|
+
return new Keypair(generateKeypair());
|
|
6875
8090
|
}
|
|
6876
8091
|
/**
|
|
6877
8092
|
* Create a keypair from a raw secret key byte array.
|
|
@@ -6888,19 +8103,27 @@ class Keypair {
|
|
|
6888
8103
|
|
|
6889
8104
|
|
|
6890
8105
|
static fromSecretKey(secretKey, options) {
|
|
6891
|
-
|
|
8106
|
+
if (secretKey.byteLength !== 64) {
|
|
8107
|
+
throw new Error('bad secret key size');
|
|
8108
|
+
}
|
|
8109
|
+
|
|
8110
|
+
const publicKey = secretKey.slice(32, 64);
|
|
6892
8111
|
|
|
6893
8112
|
if (!options || !options.skipValidation) {
|
|
6894
|
-
const
|
|
6895
|
-
const
|
|
6896
|
-
const signature = nacl__default["default"].sign.detached(signData, keypair.secretKey);
|
|
8113
|
+
const privateScalar = secretKey.slice(0, 32);
|
|
8114
|
+
const computedPublicKey = getPublicKey(privateScalar);
|
|
6897
8115
|
|
|
6898
|
-
|
|
6899
|
-
|
|
8116
|
+
for (let ii = 0; ii < 32; ii++) {
|
|
8117
|
+
if (publicKey[ii] !== computedPublicKey[ii]) {
|
|
8118
|
+
throw new Error('provided secretKey is invalid');
|
|
8119
|
+
}
|
|
6900
8120
|
}
|
|
6901
8121
|
}
|
|
6902
8122
|
|
|
6903
|
-
return new Keypair(
|
|
8123
|
+
return new Keypair({
|
|
8124
|
+
publicKey,
|
|
8125
|
+
secretKey
|
|
8126
|
+
});
|
|
6904
8127
|
}
|
|
6905
8128
|
/**
|
|
6906
8129
|
* Generate a keypair from a 32 byte seed.
|
|
@@ -6910,7 +8133,14 @@ class Keypair {
|
|
|
6910
8133
|
|
|
6911
8134
|
|
|
6912
8135
|
static fromSeed(seed) {
|
|
6913
|
-
|
|
8136
|
+
const publicKey = getPublicKey(seed);
|
|
8137
|
+
const secretKey = new Uint8Array(64);
|
|
8138
|
+
secretKey.set(seed);
|
|
8139
|
+
secretKey.set(publicKey, 32);
|
|
8140
|
+
return new Keypair({
|
|
8141
|
+
publicKey,
|
|
8142
|
+
secretKey
|
|
8143
|
+
});
|
|
6914
8144
|
}
|
|
6915
8145
|
/**
|
|
6916
8146
|
* The public key for this keypair
|
|
@@ -6926,7 +8156,7 @@ class Keypair {
|
|
|
6926
8156
|
|
|
6927
8157
|
|
|
6928
8158
|
get secretKey() {
|
|
6929
|
-
return this._keypair.secretKey;
|
|
8159
|
+
return new Uint8Array(this._keypair.secretKey);
|
|
6930
8160
|
}
|
|
6931
8161
|
|
|
6932
8162
|
}
|
|
@@ -7341,6 +8571,9 @@ class ComputeBudgetProgram {
|
|
|
7341
8571
|
*/
|
|
7342
8572
|
|
|
7343
8573
|
|
|
8574
|
+
/**
|
|
8575
|
+
* @deprecated Instead, call {@link setComputeUnitLimit} and/or {@link setComputeUnitPrice}
|
|
8576
|
+
*/
|
|
7344
8577
|
static requestUnits(params) {
|
|
7345
8578
|
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits;
|
|
7346
8579
|
const data = encodeData(type, params);
|
|
@@ -7462,7 +8695,7 @@ class Ed25519Program {
|
|
|
7462
8695
|
try {
|
|
7463
8696
|
const keypair = Keypair.fromSecretKey(privateKey);
|
|
7464
8697
|
const publicKey = keypair.publicKey.toBytes();
|
|
7465
|
-
const signature =
|
|
8698
|
+
const signature = sign(message, keypair.secretKey);
|
|
7466
8699
|
return this.createInstructionWithPublicKey({
|
|
7467
8700
|
publicKey,
|
|
7468
8701
|
message,
|
|
@@ -7477,1042 +8710,20 @@ class Ed25519Program {
|
|
|
7477
8710
|
}
|
|
7478
8711
|
Ed25519Program.programId = new PublicKey('Ed25519SigVerify111111111111111111111111111');
|
|
7479
8712
|
|
|
7480
|
-
// HMAC (RFC 2104)
|
|
7481
|
-
class HMAC extends Hash {
|
|
7482
|
-
constructor(hash, _key) {
|
|
7483
|
-
super();
|
|
7484
|
-
this.finished = false;
|
|
7485
|
-
this.destroyed = false;
|
|
7486
|
-
assert$2.hash(hash);
|
|
7487
|
-
const key = toBytes(_key);
|
|
7488
|
-
this.iHash = hash.create();
|
|
7489
|
-
if (!(this.iHash instanceof Hash))
|
|
7490
|
-
throw new TypeError('Expected instance of class which extends utils.Hash');
|
|
7491
|
-
const blockLen = (this.blockLen = this.iHash.blockLen);
|
|
7492
|
-
this.outputLen = this.iHash.outputLen;
|
|
7493
|
-
const pad = new Uint8Array(blockLen);
|
|
7494
|
-
// blockLen can be bigger than outputLen
|
|
7495
|
-
pad.set(key.length > this.iHash.blockLen ? hash.create().update(key).digest() : key);
|
|
7496
|
-
for (let i = 0; i < pad.length; i++)
|
|
7497
|
-
pad[i] ^= 0x36;
|
|
7498
|
-
this.iHash.update(pad);
|
|
7499
|
-
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
|
7500
|
-
this.oHash = hash.create();
|
|
7501
|
-
// Undo internal XOR && apply outer XOR
|
|
7502
|
-
for (let i = 0; i < pad.length; i++)
|
|
7503
|
-
pad[i] ^= 0x36 ^ 0x5c;
|
|
7504
|
-
this.oHash.update(pad);
|
|
7505
|
-
pad.fill(0);
|
|
7506
|
-
}
|
|
7507
|
-
update(buf) {
|
|
7508
|
-
assert$2.exists(this);
|
|
7509
|
-
this.iHash.update(buf);
|
|
7510
|
-
return this;
|
|
7511
|
-
}
|
|
7512
|
-
digestInto(out) {
|
|
7513
|
-
assert$2.exists(this);
|
|
7514
|
-
assert$2.bytes(out, this.outputLen);
|
|
7515
|
-
this.finished = true;
|
|
7516
|
-
this.iHash.digestInto(out);
|
|
7517
|
-
this.oHash.update(out);
|
|
7518
|
-
this.oHash.digestInto(out);
|
|
7519
|
-
this.destroy();
|
|
7520
|
-
}
|
|
7521
|
-
digest() {
|
|
7522
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
|
7523
|
-
this.digestInto(out);
|
|
7524
|
-
return out;
|
|
7525
|
-
}
|
|
7526
|
-
_cloneInto(to) {
|
|
7527
|
-
// Create new instance without calling constructor since key already in state and we don't know it.
|
|
7528
|
-
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
|
7529
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
7530
|
-
to = to;
|
|
7531
|
-
to.finished = finished;
|
|
7532
|
-
to.destroyed = destroyed;
|
|
7533
|
-
to.blockLen = blockLen;
|
|
7534
|
-
to.outputLen = outputLen;
|
|
7535
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
|
7536
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
|
7537
|
-
return to;
|
|
7538
|
-
}
|
|
7539
|
-
destroy() {
|
|
7540
|
-
this.destroyed = true;
|
|
7541
|
-
this.oHash.destroy();
|
|
7542
|
-
this.iHash.destroy();
|
|
7543
|
-
}
|
|
7544
|
-
}
|
|
7545
|
-
/**
|
|
7546
|
-
* HMAC: RFC2104 message authentication code.
|
|
7547
|
-
* @param hash - function that would be used e.g. sha256
|
|
7548
|
-
* @param key - message key
|
|
7549
|
-
* @param message - message data
|
|
7550
|
-
*/
|
|
7551
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
|
7552
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
|
7553
|
-
|
|
7554
|
-
var _nodeResolve_empty = {};
|
|
7555
|
-
|
|
7556
|
-
var nodeCrypto = /*#__PURE__*/Object.freeze({
|
|
7557
|
-
__proto__: null,
|
|
7558
|
-
'default': _nodeResolve_empty
|
|
7559
|
-
});
|
|
7560
|
-
|
|
7561
|
-
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
|
7562
|
-
const _0n = BigInt(0);
|
|
7563
|
-
const _1n = BigInt(1);
|
|
7564
|
-
const _2n = BigInt(2);
|
|
7565
|
-
const _3n = BigInt(3);
|
|
7566
|
-
const _8n = BigInt(8);
|
|
7567
|
-
const POW_2_256 = _2n ** BigInt(256);
|
|
7568
|
-
const CURVE = {
|
|
7569
|
-
a: _0n,
|
|
7570
|
-
b: BigInt(7),
|
|
7571
|
-
P: POW_2_256 - _2n ** BigInt(32) - BigInt(977),
|
|
7572
|
-
n: POW_2_256 - BigInt('432420386565659656852420866394968145599'),
|
|
7573
|
-
h: _1n,
|
|
7574
|
-
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
|
7575
|
-
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
|
7576
|
-
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
|
7577
|
-
};
|
|
7578
|
-
function weistrass(x) {
|
|
7579
|
-
const { a, b } = CURVE;
|
|
7580
|
-
const x2 = mod(x * x);
|
|
7581
|
-
const x3 = mod(x2 * x);
|
|
7582
|
-
return mod(x3 + a * x + b);
|
|
7583
|
-
}
|
|
7584
|
-
const USE_ENDOMORPHISM = CURVE.a === _0n;
|
|
7585
|
-
class JacobianPoint {
|
|
7586
|
-
constructor(x, y, z) {
|
|
7587
|
-
this.x = x;
|
|
7588
|
-
this.y = y;
|
|
7589
|
-
this.z = z;
|
|
7590
|
-
}
|
|
7591
|
-
static fromAffine(p) {
|
|
7592
|
-
if (!(p instanceof Point)) {
|
|
7593
|
-
throw new TypeError('JacobianPoint#fromAffine: expected Point');
|
|
7594
|
-
}
|
|
7595
|
-
return new JacobianPoint(p.x, p.y, _1n);
|
|
7596
|
-
}
|
|
7597
|
-
static toAffineBatch(points) {
|
|
7598
|
-
const toInv = invertBatch(points.map((p) => p.z));
|
|
7599
|
-
return points.map((p, i) => p.toAffine(toInv[i]));
|
|
7600
|
-
}
|
|
7601
|
-
static normalizeZ(points) {
|
|
7602
|
-
return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine);
|
|
7603
|
-
}
|
|
7604
|
-
equals(other) {
|
|
7605
|
-
if (!(other instanceof JacobianPoint))
|
|
7606
|
-
throw new TypeError('JacobianPoint expected');
|
|
7607
|
-
const { x: X1, y: Y1, z: Z1 } = this;
|
|
7608
|
-
const { x: X2, y: Y2, z: Z2 } = other;
|
|
7609
|
-
const Z1Z1 = mod(Z1 ** _2n);
|
|
7610
|
-
const Z2Z2 = mod(Z2 ** _2n);
|
|
7611
|
-
const U1 = mod(X1 * Z2Z2);
|
|
7612
|
-
const U2 = mod(X2 * Z1Z1);
|
|
7613
|
-
const S1 = mod(mod(Y1 * Z2) * Z2Z2);
|
|
7614
|
-
const S2 = mod(mod(Y2 * Z1) * Z1Z1);
|
|
7615
|
-
return U1 === U2 && S1 === S2;
|
|
7616
|
-
}
|
|
7617
|
-
negate() {
|
|
7618
|
-
return new JacobianPoint(this.x, mod(-this.y), this.z);
|
|
7619
|
-
}
|
|
7620
|
-
double() {
|
|
7621
|
-
const { x: X1, y: Y1, z: Z1 } = this;
|
|
7622
|
-
const A = mod(X1 ** _2n);
|
|
7623
|
-
const B = mod(Y1 ** _2n);
|
|
7624
|
-
const C = mod(B ** _2n);
|
|
7625
|
-
const D = mod(_2n * (mod((X1 + B) ** _2n) - A - C));
|
|
7626
|
-
const E = mod(_3n * A);
|
|
7627
|
-
const F = mod(E ** _2n);
|
|
7628
|
-
const X3 = mod(F - _2n * D);
|
|
7629
|
-
const Y3 = mod(E * (D - X3) - _8n * C);
|
|
7630
|
-
const Z3 = mod(_2n * Y1 * Z1);
|
|
7631
|
-
return new JacobianPoint(X3, Y3, Z3);
|
|
7632
|
-
}
|
|
7633
|
-
add(other) {
|
|
7634
|
-
if (!(other instanceof JacobianPoint))
|
|
7635
|
-
throw new TypeError('JacobianPoint expected');
|
|
7636
|
-
const { x: X1, y: Y1, z: Z1 } = this;
|
|
7637
|
-
const { x: X2, y: Y2, z: Z2 } = other;
|
|
7638
|
-
if (X2 === _0n || Y2 === _0n)
|
|
7639
|
-
return this;
|
|
7640
|
-
if (X1 === _0n || Y1 === _0n)
|
|
7641
|
-
return other;
|
|
7642
|
-
const Z1Z1 = mod(Z1 ** _2n);
|
|
7643
|
-
const Z2Z2 = mod(Z2 ** _2n);
|
|
7644
|
-
const U1 = mod(X1 * Z2Z2);
|
|
7645
|
-
const U2 = mod(X2 * Z1Z1);
|
|
7646
|
-
const S1 = mod(mod(Y1 * Z2) * Z2Z2);
|
|
7647
|
-
const S2 = mod(mod(Y2 * Z1) * Z1Z1);
|
|
7648
|
-
const H = mod(U2 - U1);
|
|
7649
|
-
const r = mod(S2 - S1);
|
|
7650
|
-
if (H === _0n) {
|
|
7651
|
-
if (r === _0n) {
|
|
7652
|
-
return this.double();
|
|
7653
|
-
}
|
|
7654
|
-
else {
|
|
7655
|
-
return JacobianPoint.ZERO;
|
|
7656
|
-
}
|
|
7657
|
-
}
|
|
7658
|
-
const HH = mod(H ** _2n);
|
|
7659
|
-
const HHH = mod(H * HH);
|
|
7660
|
-
const V = mod(U1 * HH);
|
|
7661
|
-
const X3 = mod(r ** _2n - HHH - _2n * V);
|
|
7662
|
-
const Y3 = mod(r * (V - X3) - S1 * HHH);
|
|
7663
|
-
const Z3 = mod(Z1 * Z2 * H);
|
|
7664
|
-
return new JacobianPoint(X3, Y3, Z3);
|
|
7665
|
-
}
|
|
7666
|
-
subtract(other) {
|
|
7667
|
-
return this.add(other.negate());
|
|
7668
|
-
}
|
|
7669
|
-
multiplyUnsafe(scalar) {
|
|
7670
|
-
const P0 = JacobianPoint.ZERO;
|
|
7671
|
-
if (typeof scalar === 'bigint' && scalar === _0n)
|
|
7672
|
-
return P0;
|
|
7673
|
-
let n = normalizeScalar(scalar);
|
|
7674
|
-
if (n === _1n)
|
|
7675
|
-
return this;
|
|
7676
|
-
if (!USE_ENDOMORPHISM) {
|
|
7677
|
-
let p = P0;
|
|
7678
|
-
let d = this;
|
|
7679
|
-
while (n > _0n) {
|
|
7680
|
-
if (n & _1n)
|
|
7681
|
-
p = p.add(d);
|
|
7682
|
-
d = d.double();
|
|
7683
|
-
n >>= _1n;
|
|
7684
|
-
}
|
|
7685
|
-
return p;
|
|
7686
|
-
}
|
|
7687
|
-
let { k1neg, k1, k2neg, k2 } = splitScalarEndo(n);
|
|
7688
|
-
let k1p = P0;
|
|
7689
|
-
let k2p = P0;
|
|
7690
|
-
let d = this;
|
|
7691
|
-
while (k1 > _0n || k2 > _0n) {
|
|
7692
|
-
if (k1 & _1n)
|
|
7693
|
-
k1p = k1p.add(d);
|
|
7694
|
-
if (k2 & _1n)
|
|
7695
|
-
k2p = k2p.add(d);
|
|
7696
|
-
d = d.double();
|
|
7697
|
-
k1 >>= _1n;
|
|
7698
|
-
k2 >>= _1n;
|
|
7699
|
-
}
|
|
7700
|
-
if (k1neg)
|
|
7701
|
-
k1p = k1p.negate();
|
|
7702
|
-
if (k2neg)
|
|
7703
|
-
k2p = k2p.negate();
|
|
7704
|
-
k2p = new JacobianPoint(mod(k2p.x * CURVE.beta), k2p.y, k2p.z);
|
|
7705
|
-
return k1p.add(k2p);
|
|
7706
|
-
}
|
|
7707
|
-
precomputeWindow(W) {
|
|
7708
|
-
const windows = USE_ENDOMORPHISM ? 128 / W + 1 : 256 / W + 1;
|
|
7709
|
-
const points = [];
|
|
7710
|
-
let p = this;
|
|
7711
|
-
let base = p;
|
|
7712
|
-
for (let window = 0; window < windows; window++) {
|
|
7713
|
-
base = p;
|
|
7714
|
-
points.push(base);
|
|
7715
|
-
for (let i = 1; i < 2 ** (W - 1); i++) {
|
|
7716
|
-
base = base.add(p);
|
|
7717
|
-
points.push(base);
|
|
7718
|
-
}
|
|
7719
|
-
p = base.double();
|
|
7720
|
-
}
|
|
7721
|
-
return points;
|
|
7722
|
-
}
|
|
7723
|
-
wNAF(n, affinePoint) {
|
|
7724
|
-
if (!affinePoint && this.equals(JacobianPoint.BASE))
|
|
7725
|
-
affinePoint = Point.BASE;
|
|
7726
|
-
const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
|
|
7727
|
-
if (256 % W) {
|
|
7728
|
-
throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
|
|
7729
|
-
}
|
|
7730
|
-
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
|
7731
|
-
if (!precomputes) {
|
|
7732
|
-
precomputes = this.precomputeWindow(W);
|
|
7733
|
-
if (affinePoint && W !== 1) {
|
|
7734
|
-
precomputes = JacobianPoint.normalizeZ(precomputes);
|
|
7735
|
-
pointPrecomputes.set(affinePoint, precomputes);
|
|
7736
|
-
}
|
|
7737
|
-
}
|
|
7738
|
-
let p = JacobianPoint.ZERO;
|
|
7739
|
-
let f = JacobianPoint.ZERO;
|
|
7740
|
-
const windows = 1 + (USE_ENDOMORPHISM ? 128 / W : 256 / W);
|
|
7741
|
-
const windowSize = 2 ** (W - 1);
|
|
7742
|
-
const mask = BigInt(2 ** W - 1);
|
|
7743
|
-
const maxNumber = 2 ** W;
|
|
7744
|
-
const shiftBy = BigInt(W);
|
|
7745
|
-
for (let window = 0; window < windows; window++) {
|
|
7746
|
-
const offset = window * windowSize;
|
|
7747
|
-
let wbits = Number(n & mask);
|
|
7748
|
-
n >>= shiftBy;
|
|
7749
|
-
if (wbits > windowSize) {
|
|
7750
|
-
wbits -= maxNumber;
|
|
7751
|
-
n += _1n;
|
|
7752
|
-
}
|
|
7753
|
-
if (wbits === 0) {
|
|
7754
|
-
let pr = precomputes[offset];
|
|
7755
|
-
if (window % 2)
|
|
7756
|
-
pr = pr.negate();
|
|
7757
|
-
f = f.add(pr);
|
|
7758
|
-
}
|
|
7759
|
-
else {
|
|
7760
|
-
let cached = precomputes[offset + Math.abs(wbits) - 1];
|
|
7761
|
-
if (wbits < 0)
|
|
7762
|
-
cached = cached.negate();
|
|
7763
|
-
p = p.add(cached);
|
|
7764
|
-
}
|
|
7765
|
-
}
|
|
7766
|
-
return { p, f };
|
|
7767
|
-
}
|
|
7768
|
-
multiply(scalar, affinePoint) {
|
|
7769
|
-
let n = normalizeScalar(scalar);
|
|
7770
|
-
let point;
|
|
7771
|
-
let fake;
|
|
7772
|
-
if (USE_ENDOMORPHISM) {
|
|
7773
|
-
const { k1neg, k1, k2neg, k2 } = splitScalarEndo(n);
|
|
7774
|
-
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
|
7775
|
-
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
|
7776
|
-
if (k1neg)
|
|
7777
|
-
k1p = k1p.negate();
|
|
7778
|
-
if (k2neg)
|
|
7779
|
-
k2p = k2p.negate();
|
|
7780
|
-
k2p = new JacobianPoint(mod(k2p.x * CURVE.beta), k2p.y, k2p.z);
|
|
7781
|
-
point = k1p.add(k2p);
|
|
7782
|
-
fake = f1p.add(f2p);
|
|
7783
|
-
}
|
|
7784
|
-
else {
|
|
7785
|
-
const { p, f } = this.wNAF(n, affinePoint);
|
|
7786
|
-
point = p;
|
|
7787
|
-
fake = f;
|
|
7788
|
-
}
|
|
7789
|
-
return JacobianPoint.normalizeZ([point, fake])[0];
|
|
7790
|
-
}
|
|
7791
|
-
toAffine(invZ = invert(this.z)) {
|
|
7792
|
-
const { x, y, z } = this;
|
|
7793
|
-
const iz1 = invZ;
|
|
7794
|
-
const iz2 = mod(iz1 * iz1);
|
|
7795
|
-
const iz3 = mod(iz2 * iz1);
|
|
7796
|
-
const ax = mod(x * iz2);
|
|
7797
|
-
const ay = mod(y * iz3);
|
|
7798
|
-
const zz = mod(z * iz1);
|
|
7799
|
-
if (zz !== _1n)
|
|
7800
|
-
throw new Error('invZ was invalid');
|
|
7801
|
-
return new Point(ax, ay);
|
|
7802
|
-
}
|
|
7803
|
-
}
|
|
7804
|
-
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n);
|
|
7805
|
-
JacobianPoint.ZERO = new JacobianPoint(_0n, _1n, _0n);
|
|
7806
|
-
const pointPrecomputes = new WeakMap();
|
|
7807
|
-
class Point {
|
|
7808
|
-
constructor(x, y) {
|
|
7809
|
-
this.x = x;
|
|
7810
|
-
this.y = y;
|
|
7811
|
-
}
|
|
7812
|
-
_setWindowSize(windowSize) {
|
|
7813
|
-
this._WINDOW_SIZE = windowSize;
|
|
7814
|
-
pointPrecomputes.delete(this);
|
|
7815
|
-
}
|
|
7816
|
-
static fromCompressedHex(bytes) {
|
|
7817
|
-
const isShort = bytes.length === 32;
|
|
7818
|
-
const x = bytesToNumber(isShort ? bytes : bytes.subarray(1));
|
|
7819
|
-
if (!isValidFieldElement(x))
|
|
7820
|
-
throw new Error('Point is not on curve');
|
|
7821
|
-
const y2 = weistrass(x);
|
|
7822
|
-
let y = sqrtMod(y2);
|
|
7823
|
-
const isYOdd = (y & _1n) === _1n;
|
|
7824
|
-
if (isShort) {
|
|
7825
|
-
if (isYOdd)
|
|
7826
|
-
y = mod(-y);
|
|
7827
|
-
}
|
|
7828
|
-
else {
|
|
7829
|
-
const isFirstByteOdd = (bytes[0] & 1) === 1;
|
|
7830
|
-
if (isFirstByteOdd !== isYOdd)
|
|
7831
|
-
y = mod(-y);
|
|
7832
|
-
}
|
|
7833
|
-
const point = new Point(x, y);
|
|
7834
|
-
point.assertValidity();
|
|
7835
|
-
return point;
|
|
7836
|
-
}
|
|
7837
|
-
static fromUncompressedHex(bytes) {
|
|
7838
|
-
const x = bytesToNumber(bytes.subarray(1, 33));
|
|
7839
|
-
const y = bytesToNumber(bytes.subarray(33, 65));
|
|
7840
|
-
const point = new Point(x, y);
|
|
7841
|
-
point.assertValidity();
|
|
7842
|
-
return point;
|
|
7843
|
-
}
|
|
7844
|
-
static fromHex(hex) {
|
|
7845
|
-
const bytes = ensureBytes(hex);
|
|
7846
|
-
const len = bytes.length;
|
|
7847
|
-
const header = bytes[0];
|
|
7848
|
-
if (len === 32 || (len === 33 && (header === 0x02 || header === 0x03))) {
|
|
7849
|
-
return this.fromCompressedHex(bytes);
|
|
7850
|
-
}
|
|
7851
|
-
if (len === 65 && header === 0x04)
|
|
7852
|
-
return this.fromUncompressedHex(bytes);
|
|
7853
|
-
throw new Error(`Point.fromHex: received invalid point. Expected 32-33 compressed bytes or 65 uncompressed bytes, not ${len}`);
|
|
7854
|
-
}
|
|
7855
|
-
static fromPrivateKey(privateKey) {
|
|
7856
|
-
return Point.BASE.multiply(normalizePrivateKey(privateKey));
|
|
7857
|
-
}
|
|
7858
|
-
static fromSignature(msgHash, signature, recovery) {
|
|
7859
|
-
msgHash = ensureBytes(msgHash);
|
|
7860
|
-
const h = truncateHash(msgHash);
|
|
7861
|
-
const { r, s } = normalizeSignature(signature);
|
|
7862
|
-
if (recovery !== 0 && recovery !== 1) {
|
|
7863
|
-
throw new Error('Cannot recover signature: invalid recovery bit');
|
|
7864
|
-
}
|
|
7865
|
-
const prefix = recovery & 1 ? '03' : '02';
|
|
7866
|
-
const R = Point.fromHex(prefix + numTo32bStr(r));
|
|
7867
|
-
const { n } = CURVE;
|
|
7868
|
-
const rinv = invert(r, n);
|
|
7869
|
-
const u1 = mod(-h * rinv, n);
|
|
7870
|
-
const u2 = mod(s * rinv, n);
|
|
7871
|
-
const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2);
|
|
7872
|
-
if (!Q)
|
|
7873
|
-
throw new Error('Cannot recover signature: point at infinify');
|
|
7874
|
-
Q.assertValidity();
|
|
7875
|
-
return Q;
|
|
7876
|
-
}
|
|
7877
|
-
toRawBytes(isCompressed = false) {
|
|
7878
|
-
return hexToBytes(this.toHex(isCompressed));
|
|
7879
|
-
}
|
|
7880
|
-
toHex(isCompressed = false) {
|
|
7881
|
-
const x = numTo32bStr(this.x);
|
|
7882
|
-
if (isCompressed) {
|
|
7883
|
-
const prefix = this.y & _1n ? '03' : '02';
|
|
7884
|
-
return `${prefix}${x}`;
|
|
7885
|
-
}
|
|
7886
|
-
else {
|
|
7887
|
-
return `04${x}${numTo32bStr(this.y)}`;
|
|
7888
|
-
}
|
|
7889
|
-
}
|
|
7890
|
-
toHexX() {
|
|
7891
|
-
return this.toHex(true).slice(2);
|
|
7892
|
-
}
|
|
7893
|
-
toRawX() {
|
|
7894
|
-
return this.toRawBytes(true).slice(1);
|
|
7895
|
-
}
|
|
7896
|
-
assertValidity() {
|
|
7897
|
-
const msg = 'Point is not on elliptic curve';
|
|
7898
|
-
const { x, y } = this;
|
|
7899
|
-
if (!isValidFieldElement(x) || !isValidFieldElement(y))
|
|
7900
|
-
throw new Error(msg);
|
|
7901
|
-
const left = mod(y * y);
|
|
7902
|
-
const right = weistrass(x);
|
|
7903
|
-
if (mod(left - right) !== _0n)
|
|
7904
|
-
throw new Error(msg);
|
|
7905
|
-
}
|
|
7906
|
-
equals(other) {
|
|
7907
|
-
return this.x === other.x && this.y === other.y;
|
|
7908
|
-
}
|
|
7909
|
-
negate() {
|
|
7910
|
-
return new Point(this.x, mod(-this.y));
|
|
7911
|
-
}
|
|
7912
|
-
double() {
|
|
7913
|
-
return JacobianPoint.fromAffine(this).double().toAffine();
|
|
7914
|
-
}
|
|
7915
|
-
add(other) {
|
|
7916
|
-
return JacobianPoint.fromAffine(this).add(JacobianPoint.fromAffine(other)).toAffine();
|
|
7917
|
-
}
|
|
7918
|
-
subtract(other) {
|
|
7919
|
-
return this.add(other.negate());
|
|
7920
|
-
}
|
|
7921
|
-
multiply(scalar) {
|
|
7922
|
-
return JacobianPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
|
7923
|
-
}
|
|
7924
|
-
multiplyAndAddUnsafe(Q, a, b) {
|
|
7925
|
-
const P = JacobianPoint.fromAffine(this);
|
|
7926
|
-
const aP = a === _0n || a === _1n || this !== Point.BASE ? P.multiplyUnsafe(a) : P.multiply(a);
|
|
7927
|
-
const bQ = JacobianPoint.fromAffine(Q).multiplyUnsafe(b);
|
|
7928
|
-
const sum = aP.add(bQ);
|
|
7929
|
-
return sum.equals(JacobianPoint.ZERO) ? undefined : sum.toAffine();
|
|
7930
|
-
}
|
|
7931
|
-
}
|
|
7932
|
-
Point.BASE = new Point(CURVE.Gx, CURVE.Gy);
|
|
7933
|
-
Point.ZERO = new Point(_0n, _0n);
|
|
7934
|
-
function sliceDER(s) {
|
|
7935
|
-
return Number.parseInt(s[0], 16) >= 8 ? '00' + s : s;
|
|
7936
|
-
}
|
|
7937
|
-
function parseDERInt(data) {
|
|
7938
|
-
if (data.length < 2 || data[0] !== 0x02) {
|
|
7939
|
-
throw new Error(`Invalid signature integer tag: ${bytesToHex(data)}`);
|
|
7940
|
-
}
|
|
7941
|
-
const len = data[1];
|
|
7942
|
-
const res = data.subarray(2, len + 2);
|
|
7943
|
-
if (!len || res.length !== len) {
|
|
7944
|
-
throw new Error(`Invalid signature integer: wrong length`);
|
|
7945
|
-
}
|
|
7946
|
-
if (res[0] === 0x00 && res[1] <= 0x7f) {
|
|
7947
|
-
throw new Error('Invalid signature integer: trailing length');
|
|
7948
|
-
}
|
|
7949
|
-
return { data: bytesToNumber(res), left: data.subarray(len + 2) };
|
|
7950
|
-
}
|
|
7951
|
-
function parseDERSignature(data) {
|
|
7952
|
-
if (data.length < 2 || data[0] != 0x30) {
|
|
7953
|
-
throw new Error(`Invalid signature tag: ${bytesToHex(data)}`);
|
|
7954
|
-
}
|
|
7955
|
-
if (data[1] !== data.length - 2) {
|
|
7956
|
-
throw new Error('Invalid signature: incorrect length');
|
|
7957
|
-
}
|
|
7958
|
-
const { data: r, left: sBytes } = parseDERInt(data.subarray(2));
|
|
7959
|
-
const { data: s, left: rBytesLeft } = parseDERInt(sBytes);
|
|
7960
|
-
if (rBytesLeft.length) {
|
|
7961
|
-
throw new Error(`Invalid signature: left bytes after parsing: ${bytesToHex(rBytesLeft)}`);
|
|
7962
|
-
}
|
|
7963
|
-
return { r, s };
|
|
7964
|
-
}
|
|
7965
|
-
class Signature {
|
|
7966
|
-
constructor(r, s) {
|
|
7967
|
-
this.r = r;
|
|
7968
|
-
this.s = s;
|
|
7969
|
-
this.assertValidity();
|
|
7970
|
-
}
|
|
7971
|
-
static fromCompact(hex) {
|
|
7972
|
-
const arr = isUint8a(hex);
|
|
7973
|
-
const name = 'Signature.fromCompact';
|
|
7974
|
-
if (typeof hex !== 'string' && !arr)
|
|
7975
|
-
throw new TypeError(`${name}: Expected string or Uint8Array`);
|
|
7976
|
-
const str = arr ? bytesToHex(hex) : hex;
|
|
7977
|
-
if (str.length !== 128)
|
|
7978
|
-
throw new Error(`${name}: Expected 64-byte hex`);
|
|
7979
|
-
return new Signature(hexToNumber(str.slice(0, 64)), hexToNumber(str.slice(64, 128)));
|
|
7980
|
-
}
|
|
7981
|
-
static fromDER(hex) {
|
|
7982
|
-
const arr = isUint8a(hex);
|
|
7983
|
-
if (typeof hex !== 'string' && !arr)
|
|
7984
|
-
throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`);
|
|
7985
|
-
const { r, s } = parseDERSignature(arr ? hex : hexToBytes(hex));
|
|
7986
|
-
return new Signature(r, s);
|
|
7987
|
-
}
|
|
7988
|
-
static fromHex(hex) {
|
|
7989
|
-
return this.fromDER(hex);
|
|
7990
|
-
}
|
|
7991
|
-
assertValidity() {
|
|
7992
|
-
const { r, s } = this;
|
|
7993
|
-
if (!isWithinCurveOrder(r))
|
|
7994
|
-
throw new Error('Invalid Signature: r must be 0 < r < n');
|
|
7995
|
-
if (!isWithinCurveOrder(s))
|
|
7996
|
-
throw new Error('Invalid Signature: s must be 0 < s < n');
|
|
7997
|
-
}
|
|
7998
|
-
hasHighS() {
|
|
7999
|
-
const HALF = CURVE.n >> _1n;
|
|
8000
|
-
return this.s > HALF;
|
|
8001
|
-
}
|
|
8002
|
-
normalizeS() {
|
|
8003
|
-
return this.hasHighS() ? new Signature(this.r, CURVE.n - this.s) : this;
|
|
8004
|
-
}
|
|
8005
|
-
toDERRawBytes(isCompressed = false) {
|
|
8006
|
-
return hexToBytes(this.toDERHex(isCompressed));
|
|
8007
|
-
}
|
|
8008
|
-
toDERHex(isCompressed = false) {
|
|
8009
|
-
const sHex = sliceDER(numberToHexUnpadded(this.s));
|
|
8010
|
-
if (isCompressed)
|
|
8011
|
-
return sHex;
|
|
8012
|
-
const rHex = sliceDER(numberToHexUnpadded(this.r));
|
|
8013
|
-
const rLen = numberToHexUnpadded(rHex.length / 2);
|
|
8014
|
-
const sLen = numberToHexUnpadded(sHex.length / 2);
|
|
8015
|
-
const length = numberToHexUnpadded(rHex.length / 2 + sHex.length / 2 + 4);
|
|
8016
|
-
return `30${length}02${rLen}${rHex}02${sLen}${sHex}`;
|
|
8017
|
-
}
|
|
8018
|
-
toRawBytes() {
|
|
8019
|
-
return this.toDERRawBytes();
|
|
8020
|
-
}
|
|
8021
|
-
toHex() {
|
|
8022
|
-
return this.toDERHex();
|
|
8023
|
-
}
|
|
8024
|
-
toCompactRawBytes() {
|
|
8025
|
-
return hexToBytes(this.toCompactHex());
|
|
8026
|
-
}
|
|
8027
|
-
toCompactHex() {
|
|
8028
|
-
return numTo32bStr(this.r) + numTo32bStr(this.s);
|
|
8029
|
-
}
|
|
8030
|
-
}
|
|
8031
|
-
function concatBytes(...arrays) {
|
|
8032
|
-
if (!arrays.every(isUint8a))
|
|
8033
|
-
throw new Error('Uint8Array list expected');
|
|
8034
|
-
if (arrays.length === 1)
|
|
8035
|
-
return arrays[0];
|
|
8036
|
-
const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
|
8037
|
-
const result = new Uint8Array(length);
|
|
8038
|
-
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
8039
|
-
const arr = arrays[i];
|
|
8040
|
-
result.set(arr, pad);
|
|
8041
|
-
pad += arr.length;
|
|
8042
|
-
}
|
|
8043
|
-
return result;
|
|
8044
|
-
}
|
|
8045
|
-
function isUint8a(bytes) {
|
|
8046
|
-
return bytes instanceof Uint8Array;
|
|
8047
|
-
}
|
|
8048
|
-
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
|
8049
|
-
function bytesToHex(uint8a) {
|
|
8050
|
-
if (!(uint8a instanceof Uint8Array))
|
|
8051
|
-
throw new Error('Expected Uint8Array');
|
|
8052
|
-
let hex = '';
|
|
8053
|
-
for (let i = 0; i < uint8a.length; i++) {
|
|
8054
|
-
hex += hexes[uint8a[i]];
|
|
8055
|
-
}
|
|
8056
|
-
return hex;
|
|
8057
|
-
}
|
|
8058
|
-
function numTo32bStr(num) {
|
|
8059
|
-
if (num > POW_2_256)
|
|
8060
|
-
throw new Error('Expected number < 2^256');
|
|
8061
|
-
return num.toString(16).padStart(64, '0');
|
|
8062
|
-
}
|
|
8063
|
-
function numTo32b(num) {
|
|
8064
|
-
return hexToBytes(numTo32bStr(num));
|
|
8065
|
-
}
|
|
8066
|
-
function numberToHexUnpadded(num) {
|
|
8067
|
-
const hex = num.toString(16);
|
|
8068
|
-
return hex.length & 1 ? `0${hex}` : hex;
|
|
8069
|
-
}
|
|
8070
|
-
function hexToNumber(hex) {
|
|
8071
|
-
if (typeof hex !== 'string') {
|
|
8072
|
-
throw new TypeError('hexToNumber: expected string, got ' + typeof hex);
|
|
8073
|
-
}
|
|
8074
|
-
return BigInt(`0x${hex}`);
|
|
8075
|
-
}
|
|
8076
|
-
function hexToBytes(hex) {
|
|
8077
|
-
if (typeof hex !== 'string') {
|
|
8078
|
-
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
|
8079
|
-
}
|
|
8080
|
-
if (hex.length % 2)
|
|
8081
|
-
throw new Error('hexToBytes: received invalid unpadded hex' + hex.length);
|
|
8082
|
-
const array = new Uint8Array(hex.length / 2);
|
|
8083
|
-
for (let i = 0; i < array.length; i++) {
|
|
8084
|
-
const j = i * 2;
|
|
8085
|
-
const hexByte = hex.slice(j, j + 2);
|
|
8086
|
-
const byte = Number.parseInt(hexByte, 16);
|
|
8087
|
-
if (Number.isNaN(byte) || byte < 0)
|
|
8088
|
-
throw new Error('Invalid byte sequence');
|
|
8089
|
-
array[i] = byte;
|
|
8090
|
-
}
|
|
8091
|
-
return array;
|
|
8092
|
-
}
|
|
8093
|
-
function bytesToNumber(bytes) {
|
|
8094
|
-
return hexToNumber(bytesToHex(bytes));
|
|
8095
|
-
}
|
|
8096
|
-
function ensureBytes(hex) {
|
|
8097
|
-
return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex);
|
|
8098
|
-
}
|
|
8099
|
-
function normalizeScalar(num) {
|
|
8100
|
-
if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)
|
|
8101
|
-
return BigInt(num);
|
|
8102
|
-
if (typeof num === 'bigint' && isWithinCurveOrder(num))
|
|
8103
|
-
return num;
|
|
8104
|
-
throw new TypeError('Expected valid private scalar: 0 < scalar < curve.n');
|
|
8105
|
-
}
|
|
8106
|
-
function mod(a, b = CURVE.P) {
|
|
8107
|
-
const result = a % b;
|
|
8108
|
-
return result >= _0n ? result : b + result;
|
|
8109
|
-
}
|
|
8110
|
-
function pow2(x, power) {
|
|
8111
|
-
const { P } = CURVE;
|
|
8112
|
-
let res = x;
|
|
8113
|
-
while (power-- > _0n) {
|
|
8114
|
-
res *= res;
|
|
8115
|
-
res %= P;
|
|
8116
|
-
}
|
|
8117
|
-
return res;
|
|
8118
|
-
}
|
|
8119
|
-
function sqrtMod(x) {
|
|
8120
|
-
const { P } = CURVE;
|
|
8121
|
-
const _6n = BigInt(6);
|
|
8122
|
-
const _11n = BigInt(11);
|
|
8123
|
-
const _22n = BigInt(22);
|
|
8124
|
-
const _23n = BigInt(23);
|
|
8125
|
-
const _44n = BigInt(44);
|
|
8126
|
-
const _88n = BigInt(88);
|
|
8127
|
-
const b2 = (x * x * x) % P;
|
|
8128
|
-
const b3 = (b2 * b2 * x) % P;
|
|
8129
|
-
const b6 = (pow2(b3, _3n) * b3) % P;
|
|
8130
|
-
const b9 = (pow2(b6, _3n) * b3) % P;
|
|
8131
|
-
const b11 = (pow2(b9, _2n) * b2) % P;
|
|
8132
|
-
const b22 = (pow2(b11, _11n) * b11) % P;
|
|
8133
|
-
const b44 = (pow2(b22, _22n) * b22) % P;
|
|
8134
|
-
const b88 = (pow2(b44, _44n) * b44) % P;
|
|
8135
|
-
const b176 = (pow2(b88, _88n) * b88) % P;
|
|
8136
|
-
const b220 = (pow2(b176, _44n) * b44) % P;
|
|
8137
|
-
const b223 = (pow2(b220, _3n) * b3) % P;
|
|
8138
|
-
const t1 = (pow2(b223, _23n) * b22) % P;
|
|
8139
|
-
const t2 = (pow2(t1, _6n) * b2) % P;
|
|
8140
|
-
return pow2(t2, _2n);
|
|
8141
|
-
}
|
|
8142
|
-
function invert(number, modulo = CURVE.P) {
|
|
8143
|
-
if (number === _0n || modulo <= _0n) {
|
|
8144
|
-
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
8145
|
-
}
|
|
8146
|
-
let a = mod(number, modulo);
|
|
8147
|
-
let b = modulo;
|
|
8148
|
-
let x = _0n, u = _1n;
|
|
8149
|
-
while (a !== _0n) {
|
|
8150
|
-
const q = b / a;
|
|
8151
|
-
const r = b % a;
|
|
8152
|
-
const m = x - u * q;
|
|
8153
|
-
b = a, a = r, x = u, u = m;
|
|
8154
|
-
}
|
|
8155
|
-
const gcd = b;
|
|
8156
|
-
if (gcd !== _1n)
|
|
8157
|
-
throw new Error('invert: does not exist');
|
|
8158
|
-
return mod(x, modulo);
|
|
8159
|
-
}
|
|
8160
|
-
function invertBatch(nums, p = CURVE.P) {
|
|
8161
|
-
const scratch = new Array(nums.length);
|
|
8162
|
-
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
8163
|
-
if (num === _0n)
|
|
8164
|
-
return acc;
|
|
8165
|
-
scratch[i] = acc;
|
|
8166
|
-
return mod(acc * num, p);
|
|
8167
|
-
}, _1n);
|
|
8168
|
-
const inverted = invert(lastMultiplied, p);
|
|
8169
|
-
nums.reduceRight((acc, num, i) => {
|
|
8170
|
-
if (num === _0n)
|
|
8171
|
-
return acc;
|
|
8172
|
-
scratch[i] = mod(acc * scratch[i], p);
|
|
8173
|
-
return mod(acc * num, p);
|
|
8174
|
-
}, inverted);
|
|
8175
|
-
return scratch;
|
|
8176
|
-
}
|
|
8177
|
-
const divNearest = (a, b) => (a + b / _2n) / b;
|
|
8178
|
-
const POW_2_128 = _2n ** BigInt(128);
|
|
8179
|
-
function splitScalarEndo(k) {
|
|
8180
|
-
const { n } = CURVE;
|
|
8181
|
-
const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');
|
|
8182
|
-
const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');
|
|
8183
|
-
const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');
|
|
8184
|
-
const b2 = a1;
|
|
8185
|
-
const c1 = divNearest(b2 * k, n);
|
|
8186
|
-
const c2 = divNearest(-b1 * k, n);
|
|
8187
|
-
let k1 = mod(k - c1 * a1 - c2 * a2, n);
|
|
8188
|
-
let k2 = mod(-c1 * b1 - c2 * b2, n);
|
|
8189
|
-
const k1neg = k1 > POW_2_128;
|
|
8190
|
-
const k2neg = k2 > POW_2_128;
|
|
8191
|
-
if (k1neg)
|
|
8192
|
-
k1 = n - k1;
|
|
8193
|
-
if (k2neg)
|
|
8194
|
-
k2 = n - k2;
|
|
8195
|
-
if (k1 > POW_2_128 || k2 > POW_2_128) {
|
|
8196
|
-
throw new Error('splitScalarEndo: Endomorphism failed, k=' + k);
|
|
8197
|
-
}
|
|
8198
|
-
return { k1neg, k1, k2neg, k2 };
|
|
8199
|
-
}
|
|
8200
|
-
function truncateHash(hash) {
|
|
8201
|
-
const { n } = CURVE;
|
|
8202
|
-
const byteLength = hash.length;
|
|
8203
|
-
const delta = byteLength * 8 - 256;
|
|
8204
|
-
let h = bytesToNumber(hash);
|
|
8205
|
-
if (delta > 0)
|
|
8206
|
-
h = h >> BigInt(delta);
|
|
8207
|
-
if (h >= n)
|
|
8208
|
-
h -= n;
|
|
8209
|
-
return h;
|
|
8210
|
-
}
|
|
8211
|
-
class HmacDrbg {
|
|
8212
|
-
constructor() {
|
|
8213
|
-
this.v = new Uint8Array(32).fill(1);
|
|
8214
|
-
this.k = new Uint8Array(32).fill(0);
|
|
8215
|
-
this.counter = 0;
|
|
8216
|
-
}
|
|
8217
|
-
hmac(...values) {
|
|
8218
|
-
return utils.hmacSha256(this.k, ...values);
|
|
8219
|
-
}
|
|
8220
|
-
hmacSync(...values) {
|
|
8221
|
-
if (typeof utils.hmacSha256Sync !== 'function')
|
|
8222
|
-
throw new Error('utils.hmacSha256Sync is undefined, you need to set it');
|
|
8223
|
-
const res = utils.hmacSha256Sync(this.k, ...values);
|
|
8224
|
-
if (res instanceof Promise)
|
|
8225
|
-
throw new Error('To use sync sign(), ensure utils.hmacSha256 is sync');
|
|
8226
|
-
return res;
|
|
8227
|
-
}
|
|
8228
|
-
incr() {
|
|
8229
|
-
if (this.counter >= 1000) {
|
|
8230
|
-
throw new Error('Tried 1,000 k values for sign(), all were invalid');
|
|
8231
|
-
}
|
|
8232
|
-
this.counter += 1;
|
|
8233
|
-
}
|
|
8234
|
-
async reseed(seed = new Uint8Array()) {
|
|
8235
|
-
this.k = await this.hmac(this.v, Uint8Array.from([0x00]), seed);
|
|
8236
|
-
this.v = await this.hmac(this.v);
|
|
8237
|
-
if (seed.length === 0)
|
|
8238
|
-
return;
|
|
8239
|
-
this.k = await this.hmac(this.v, Uint8Array.from([0x01]), seed);
|
|
8240
|
-
this.v = await this.hmac(this.v);
|
|
8241
|
-
}
|
|
8242
|
-
reseedSync(seed = new Uint8Array()) {
|
|
8243
|
-
this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);
|
|
8244
|
-
this.v = this.hmacSync(this.v);
|
|
8245
|
-
if (seed.length === 0)
|
|
8246
|
-
return;
|
|
8247
|
-
this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);
|
|
8248
|
-
this.v = this.hmacSync(this.v);
|
|
8249
|
-
}
|
|
8250
|
-
async generate() {
|
|
8251
|
-
this.incr();
|
|
8252
|
-
this.v = await this.hmac(this.v);
|
|
8253
|
-
return this.v;
|
|
8254
|
-
}
|
|
8255
|
-
generateSync() {
|
|
8256
|
-
this.incr();
|
|
8257
|
-
this.v = this.hmacSync(this.v);
|
|
8258
|
-
return this.v;
|
|
8259
|
-
}
|
|
8260
|
-
}
|
|
8261
|
-
function isWithinCurveOrder(num) {
|
|
8262
|
-
return _0n < num && num < CURVE.n;
|
|
8263
|
-
}
|
|
8264
|
-
function isValidFieldElement(num) {
|
|
8265
|
-
return _0n < num && num < CURVE.P;
|
|
8266
|
-
}
|
|
8267
|
-
function kmdToSig(kBytes, m, d) {
|
|
8268
|
-
const k = bytesToNumber(kBytes);
|
|
8269
|
-
if (!isWithinCurveOrder(k))
|
|
8270
|
-
return;
|
|
8271
|
-
const { n } = CURVE;
|
|
8272
|
-
const q = Point.BASE.multiply(k);
|
|
8273
|
-
const r = mod(q.x, n);
|
|
8274
|
-
if (r === _0n)
|
|
8275
|
-
return;
|
|
8276
|
-
const s = mod(invert(k, n) * mod(m + d * r, n), n);
|
|
8277
|
-
if (s === _0n)
|
|
8278
|
-
return;
|
|
8279
|
-
const sig = new Signature(r, s);
|
|
8280
|
-
const recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n);
|
|
8281
|
-
return { sig, recovery };
|
|
8282
|
-
}
|
|
8283
|
-
function normalizePrivateKey(key) {
|
|
8284
|
-
let num;
|
|
8285
|
-
if (typeof key === 'bigint') {
|
|
8286
|
-
num = key;
|
|
8287
|
-
}
|
|
8288
|
-
else if (typeof key === 'number' && Number.isSafeInteger(key) && key > 0) {
|
|
8289
|
-
num = BigInt(key);
|
|
8290
|
-
}
|
|
8291
|
-
else if (typeof key === 'string') {
|
|
8292
|
-
if (key.length !== 64)
|
|
8293
|
-
throw new Error('Expected 32 bytes of private key');
|
|
8294
|
-
num = hexToNumber(key);
|
|
8295
|
-
}
|
|
8296
|
-
else if (isUint8a(key)) {
|
|
8297
|
-
if (key.length !== 32)
|
|
8298
|
-
throw new Error('Expected 32 bytes of private key');
|
|
8299
|
-
num = bytesToNumber(key);
|
|
8300
|
-
}
|
|
8301
|
-
else {
|
|
8302
|
-
throw new TypeError('Expected valid private key');
|
|
8303
|
-
}
|
|
8304
|
-
if (!isWithinCurveOrder(num))
|
|
8305
|
-
throw new Error('Expected private key: 0 < key < n');
|
|
8306
|
-
return num;
|
|
8307
|
-
}
|
|
8308
|
-
function normalizeSignature(signature) {
|
|
8309
|
-
if (signature instanceof Signature) {
|
|
8310
|
-
signature.assertValidity();
|
|
8311
|
-
return signature;
|
|
8312
|
-
}
|
|
8313
|
-
try {
|
|
8314
|
-
return Signature.fromDER(signature);
|
|
8315
|
-
}
|
|
8316
|
-
catch (error) {
|
|
8317
|
-
return Signature.fromCompact(signature);
|
|
8318
|
-
}
|
|
8319
|
-
}
|
|
8320
|
-
function getPublicKey(privateKey, isCompressed = false) {
|
|
8321
|
-
return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);
|
|
8322
|
-
}
|
|
8323
|
-
function bits2int(bytes) {
|
|
8324
|
-
const slice = bytes.length > 32 ? bytes.slice(0, 32) : bytes;
|
|
8325
|
-
return bytesToNumber(slice);
|
|
8326
|
-
}
|
|
8327
|
-
function bits2octets(bytes) {
|
|
8328
|
-
const z1 = bits2int(bytes);
|
|
8329
|
-
const z2 = mod(z1, CURVE.n);
|
|
8330
|
-
return int2octets(z2 < _0n ? z1 : z2);
|
|
8331
|
-
}
|
|
8332
|
-
function int2octets(num) {
|
|
8333
|
-
if (typeof num !== 'bigint')
|
|
8334
|
-
throw new Error('Expected bigint');
|
|
8335
|
-
const hex = numTo32bStr(num);
|
|
8336
|
-
return hexToBytes(hex);
|
|
8337
|
-
}
|
|
8338
|
-
function initSigArgs(msgHash, privateKey, extraEntropy) {
|
|
8339
|
-
if (msgHash == null)
|
|
8340
|
-
throw new Error(`sign: expected valid message hash, not "${msgHash}"`);
|
|
8341
|
-
const h1 = ensureBytes(msgHash);
|
|
8342
|
-
const d = normalizePrivateKey(privateKey);
|
|
8343
|
-
const seedArgs = [int2octets(d), bits2octets(h1)];
|
|
8344
|
-
if (extraEntropy != null) {
|
|
8345
|
-
if (extraEntropy === true)
|
|
8346
|
-
extraEntropy = utils.randomBytes(32);
|
|
8347
|
-
const e = ensureBytes(extraEntropy);
|
|
8348
|
-
if (e.length !== 32)
|
|
8349
|
-
throw new Error('sign: Expected 32 bytes of extra data');
|
|
8350
|
-
seedArgs.push(e);
|
|
8351
|
-
}
|
|
8352
|
-
const seed = concatBytes(...seedArgs);
|
|
8353
|
-
const m = bits2int(h1);
|
|
8354
|
-
return { seed, m, d };
|
|
8355
|
-
}
|
|
8356
|
-
function finalizeSig(recSig, opts) {
|
|
8357
|
-
let { sig, recovery } = recSig;
|
|
8358
|
-
const { canonical, der, recovered } = Object.assign({ canonical: true, der: true }, opts);
|
|
8359
|
-
if (canonical && sig.hasHighS()) {
|
|
8360
|
-
sig = sig.normalizeS();
|
|
8361
|
-
recovery ^= 1;
|
|
8362
|
-
}
|
|
8363
|
-
const hashed = der ? sig.toDERRawBytes() : sig.toCompactRawBytes();
|
|
8364
|
-
return recovered ? [hashed, recovery] : hashed;
|
|
8365
|
-
}
|
|
8366
|
-
function signSync(msgHash, privKey, opts = {}) {
|
|
8367
|
-
const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
|
|
8368
|
-
let sig;
|
|
8369
|
-
const drbg = new HmacDrbg();
|
|
8370
|
-
drbg.reseedSync(seed);
|
|
8371
|
-
while (!(sig = kmdToSig(drbg.generateSync(), m, d)))
|
|
8372
|
-
drbg.reseedSync();
|
|
8373
|
-
return finalizeSig(sig, opts);
|
|
8374
|
-
}
|
|
8375
|
-
Point.BASE._setWindowSize(8);
|
|
8376
|
-
const crypto = {
|
|
8377
|
-
node: nodeCrypto,
|
|
8378
|
-
web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
|
|
8379
|
-
};
|
|
8380
|
-
const TAGGED_HASH_PREFIXES = {};
|
|
8381
|
-
const utils = {
|
|
8382
|
-
isValidPrivateKey(privateKey) {
|
|
8383
|
-
try {
|
|
8384
|
-
normalizePrivateKey(privateKey);
|
|
8385
|
-
return true;
|
|
8386
|
-
}
|
|
8387
|
-
catch (error) {
|
|
8388
|
-
return false;
|
|
8389
|
-
}
|
|
8390
|
-
},
|
|
8391
|
-
privateAdd: (privateKey, tweak) => {
|
|
8392
|
-
const p = normalizePrivateKey(privateKey);
|
|
8393
|
-
const t = normalizePrivateKey(tweak);
|
|
8394
|
-
return numTo32b(mod(p + t, CURVE.n));
|
|
8395
|
-
},
|
|
8396
|
-
privateNegate: (privateKey) => {
|
|
8397
|
-
const p = normalizePrivateKey(privateKey);
|
|
8398
|
-
return numTo32b(CURVE.n - p);
|
|
8399
|
-
},
|
|
8400
|
-
pointAddScalar: (p, tweak, isCompressed) => {
|
|
8401
|
-
const P = Point.fromHex(p);
|
|
8402
|
-
const t = normalizePrivateKey(tweak);
|
|
8403
|
-
const Q = Point.BASE.multiplyAndAddUnsafe(P, t, _1n);
|
|
8404
|
-
if (!Q)
|
|
8405
|
-
throw new Error('Tweaked point at infinity');
|
|
8406
|
-
return Q.toRawBytes(isCompressed);
|
|
8407
|
-
},
|
|
8408
|
-
pointMultiply: (p, tweak, isCompressed) => {
|
|
8409
|
-
const P = Point.fromHex(p);
|
|
8410
|
-
const t = bytesToNumber(ensureBytes(tweak));
|
|
8411
|
-
return P.multiply(t).toRawBytes(isCompressed);
|
|
8412
|
-
},
|
|
8413
|
-
hashToPrivateKey: (hash) => {
|
|
8414
|
-
hash = ensureBytes(hash);
|
|
8415
|
-
if (hash.length < 40 || hash.length > 1024)
|
|
8416
|
-
throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
|
|
8417
|
-
const num = mod(bytesToNumber(hash), CURVE.n - _1n) + _1n;
|
|
8418
|
-
return numTo32b(num);
|
|
8419
|
-
},
|
|
8420
|
-
randomBytes: (bytesLength = 32) => {
|
|
8421
|
-
if (crypto.web) {
|
|
8422
|
-
return crypto.web.getRandomValues(new Uint8Array(bytesLength));
|
|
8423
|
-
}
|
|
8424
|
-
else if (crypto.node) {
|
|
8425
|
-
const { randomBytes } = crypto.node;
|
|
8426
|
-
return Uint8Array.from(randomBytes(bytesLength));
|
|
8427
|
-
}
|
|
8428
|
-
else {
|
|
8429
|
-
throw new Error("The environment doesn't have randomBytes function");
|
|
8430
|
-
}
|
|
8431
|
-
},
|
|
8432
|
-
randomPrivateKey: () => {
|
|
8433
|
-
return utils.hashToPrivateKey(utils.randomBytes(40));
|
|
8434
|
-
},
|
|
8435
|
-
bytesToHex,
|
|
8436
|
-
hexToBytes,
|
|
8437
|
-
concatBytes,
|
|
8438
|
-
mod,
|
|
8439
|
-
invert,
|
|
8440
|
-
sha256: async (...messages) => {
|
|
8441
|
-
if (crypto.web) {
|
|
8442
|
-
const buffer = await crypto.web.subtle.digest('SHA-256', concatBytes(...messages));
|
|
8443
|
-
return new Uint8Array(buffer);
|
|
8444
|
-
}
|
|
8445
|
-
else if (crypto.node) {
|
|
8446
|
-
const { createHash } = crypto.node;
|
|
8447
|
-
const hash = createHash('sha256');
|
|
8448
|
-
messages.forEach((m) => hash.update(m));
|
|
8449
|
-
return Uint8Array.from(hash.digest());
|
|
8450
|
-
}
|
|
8451
|
-
else {
|
|
8452
|
-
throw new Error("The environment doesn't have sha256 function");
|
|
8453
|
-
}
|
|
8454
|
-
},
|
|
8455
|
-
hmacSha256: async (key, ...messages) => {
|
|
8456
|
-
if (crypto.web) {
|
|
8457
|
-
const ckey = await crypto.web.subtle.importKey('raw', key, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']);
|
|
8458
|
-
const message = concatBytes(...messages);
|
|
8459
|
-
const buffer = await crypto.web.subtle.sign('HMAC', ckey, message);
|
|
8460
|
-
return new Uint8Array(buffer);
|
|
8461
|
-
}
|
|
8462
|
-
else if (crypto.node) {
|
|
8463
|
-
const { createHmac } = crypto.node;
|
|
8464
|
-
const hash = createHmac('sha256', key);
|
|
8465
|
-
messages.forEach((m) => hash.update(m));
|
|
8466
|
-
return Uint8Array.from(hash.digest());
|
|
8467
|
-
}
|
|
8468
|
-
else {
|
|
8469
|
-
throw new Error("The environment doesn't have hmac-sha256 function");
|
|
8470
|
-
}
|
|
8471
|
-
},
|
|
8472
|
-
sha256Sync: undefined,
|
|
8473
|
-
hmacSha256Sync: undefined,
|
|
8474
|
-
taggedHash: async (tag, ...messages) => {
|
|
8475
|
-
let tagP = TAGGED_HASH_PREFIXES[tag];
|
|
8476
|
-
if (tagP === undefined) {
|
|
8477
|
-
const tagH = await utils.sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
|
|
8478
|
-
tagP = concatBytes(tagH, tagH);
|
|
8479
|
-
TAGGED_HASH_PREFIXES[tag] = tagP;
|
|
8480
|
-
}
|
|
8481
|
-
return utils.sha256(tagP, ...messages);
|
|
8482
|
-
},
|
|
8483
|
-
taggedHashSync: (tag, ...messages) => {
|
|
8484
|
-
if (typeof utils.sha256Sync !== 'function')
|
|
8485
|
-
throw new Error('utils.sha256Sync is undefined, you need to set it');
|
|
8486
|
-
let tagP = TAGGED_HASH_PREFIXES[tag];
|
|
8487
|
-
if (tagP === undefined) {
|
|
8488
|
-
const tagH = utils.sha256Sync(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
|
|
8489
|
-
tagP = concatBytes(tagH, tagH);
|
|
8490
|
-
TAGGED_HASH_PREFIXES[tag] = tagP;
|
|
8491
|
-
}
|
|
8492
|
-
return utils.sha256Sync(tagP, ...messages);
|
|
8493
|
-
},
|
|
8494
|
-
precompute(windowSize = 8, point = Point.BASE) {
|
|
8495
|
-
const cached = point === Point.BASE ? point : new Point(point.x, point.y);
|
|
8496
|
-
cached._setWindowSize(windowSize);
|
|
8497
|
-
cached.multiply(_3n);
|
|
8498
|
-
return cached;
|
|
8499
|
-
},
|
|
8500
|
-
};
|
|
8501
|
-
|
|
8502
8713
|
// library interoperable with the synchronous APIs in web3.js.
|
|
8503
8714
|
|
|
8504
|
-
utils.hmacSha256Sync = (key, ...msgs) => {
|
|
8505
|
-
const h = hmac.create(sha256, key);
|
|
8715
|
+
secp256k1__namespace.utils.hmacSha256Sync = (key, ...msgs) => {
|
|
8716
|
+
const h = hmac.hmac.create(sha256.sha256, key);
|
|
8506
8717
|
msgs.forEach(msg => h.update(msg));
|
|
8507
8718
|
return h.digest();
|
|
8508
8719
|
};
|
|
8509
8720
|
|
|
8510
|
-
const ecdsaSign = (msgHash, privKey) => signSync(msgHash, privKey, {
|
|
8721
|
+
const ecdsaSign = (msgHash, privKey) => secp256k1__namespace.signSync(msgHash, privKey, {
|
|
8511
8722
|
der: false,
|
|
8512
8723
|
recovered: true
|
|
8513
8724
|
});
|
|
8514
|
-
utils.isValidPrivateKey;
|
|
8515
|
-
const publicKeyCreate = getPublicKey;
|
|
8725
|
+
secp256k1__namespace.utils.isValidPrivateKey;
|
|
8726
|
+
const publicKeyCreate = secp256k1__namespace.getPublicKey;
|
|
8516
8727
|
|
|
8517
8728
|
const PRIVATE_KEY_BYTES = 32;
|
|
8518
8729
|
const ETHEREUM_ADDRESS_BYTES = 20;
|
|
@@ -8541,7 +8752,7 @@ class Secp256k1Program {
|
|
|
8541
8752
|
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
8542
8753
|
|
|
8543
8754
|
try {
|
|
8544
|
-
return buffer.Buffer.from(
|
|
8755
|
+
return buffer.Buffer.from(sha3.keccak_256(toBuffer(publicKey))).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
8545
8756
|
} catch (error) {
|
|
8546
8757
|
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
8547
8758
|
}
|
|
@@ -8641,7 +8852,7 @@ class Secp256k1Program {
|
|
|
8641
8852
|
/* isCompressed */
|
|
8642
8853
|
).slice(1); // throw away leading byte
|
|
8643
8854
|
|
|
8644
|
-
const messageHash = buffer.Buffer.from(
|
|
8855
|
+
const messageHash = buffer.Buffer.from(sha3.keccak_256(toBuffer(message)));
|
|
8645
8856
|
const [signature, recoveryId] = ecdsaSign(messageHash, privateKey);
|
|
8646
8857
|
return this.createInstructionWithPublicKey({
|
|
8647
8858
|
publicKey,
|
|
@@ -9535,6 +9746,33 @@ class VoteInstruction {
|
|
|
9535
9746
|
}
|
|
9536
9747
|
};
|
|
9537
9748
|
}
|
|
9749
|
+
/**
|
|
9750
|
+
* Decode an authorize instruction and retrieve the instruction params.
|
|
9751
|
+
*/
|
|
9752
|
+
|
|
9753
|
+
|
|
9754
|
+
static decodeAuthorizeWithSeed(instruction) {
|
|
9755
|
+
this.checkProgramId(instruction.programId);
|
|
9756
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
9757
|
+
const {
|
|
9758
|
+
voteAuthorizeWithSeedArgs: {
|
|
9759
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9760
|
+
currentAuthorityDerivedKeySeed,
|
|
9761
|
+
newAuthorized,
|
|
9762
|
+
voteAuthorizationType
|
|
9763
|
+
}
|
|
9764
|
+
} = decodeData$1(VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed, instruction.data);
|
|
9765
|
+
return {
|
|
9766
|
+
currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
|
|
9767
|
+
currentAuthorityDerivedKeyOwnerPubkey: new PublicKey(currentAuthorityDerivedKeyOwnerPubkey),
|
|
9768
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9769
|
+
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
|
9770
|
+
voteAuthorizationType: {
|
|
9771
|
+
index: voteAuthorizationType
|
|
9772
|
+
},
|
|
9773
|
+
votePubkey: instruction.keys[0].pubkey
|
|
9774
|
+
};
|
|
9775
|
+
}
|
|
9538
9776
|
/**
|
|
9539
9777
|
* Decode a withdraw instruction and retrieve the instruction params.
|
|
9540
9778
|
*/
|
|
@@ -9591,6 +9829,10 @@ const VOTE_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
9591
9829
|
Withdraw: {
|
|
9592
9830
|
index: 3,
|
|
9593
9831
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), BufferLayout__namespace.ns64('lamports')])
|
|
9832
|
+
},
|
|
9833
|
+
AuthorizeWithSeed: {
|
|
9834
|
+
index: 10,
|
|
9835
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), voteAuthorizeWithSeedArgs()])
|
|
9594
9836
|
}
|
|
9595
9837
|
});
|
|
9596
9838
|
/**
|
|
@@ -9719,6 +9961,49 @@ class VoteProgram {
|
|
|
9719
9961
|
data
|
|
9720
9962
|
});
|
|
9721
9963
|
}
|
|
9964
|
+
/**
|
|
9965
|
+
* Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account
|
|
9966
|
+
* where the current Voter or Withdrawer authority is a derived key.
|
|
9967
|
+
*/
|
|
9968
|
+
|
|
9969
|
+
|
|
9970
|
+
static authorizeWithSeed(params) {
|
|
9971
|
+
const {
|
|
9972
|
+
currentAuthorityDerivedKeyBasePubkey,
|
|
9973
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9974
|
+
currentAuthorityDerivedKeySeed,
|
|
9975
|
+
newAuthorizedPubkey,
|
|
9976
|
+
voteAuthorizationType,
|
|
9977
|
+
votePubkey
|
|
9978
|
+
} = params;
|
|
9979
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
|
|
9980
|
+
const data = encodeData(type, {
|
|
9981
|
+
voteAuthorizeWithSeedArgs: {
|
|
9982
|
+
currentAuthorityDerivedKeyOwnerPubkey: toBuffer(currentAuthorityDerivedKeyOwnerPubkey.toBuffer()),
|
|
9983
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9984
|
+
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
|
|
9985
|
+
voteAuthorizationType: voteAuthorizationType.index
|
|
9986
|
+
}
|
|
9987
|
+
});
|
|
9988
|
+
const keys = [{
|
|
9989
|
+
pubkey: votePubkey,
|
|
9990
|
+
isSigner: false,
|
|
9991
|
+
isWritable: true
|
|
9992
|
+
}, {
|
|
9993
|
+
pubkey: SYSVAR_CLOCK_PUBKEY,
|
|
9994
|
+
isSigner: false,
|
|
9995
|
+
isWritable: false
|
|
9996
|
+
}, {
|
|
9997
|
+
pubkey: currentAuthorityDerivedKeyBasePubkey,
|
|
9998
|
+
isSigner: true,
|
|
9999
|
+
isWritable: false
|
|
10000
|
+
}];
|
|
10001
|
+
return new Transaction().add({
|
|
10002
|
+
keys,
|
|
10003
|
+
programId: this.programId,
|
|
10004
|
+
data
|
|
10005
|
+
});
|
|
10006
|
+
}
|
|
9722
10007
|
/**
|
|
9723
10008
|
* Generate a transaction to withdraw from a Vote account.
|
|
9724
10009
|
*/
|
|
@@ -10014,6 +10299,9 @@ async function sendAndConfirmRawTransaction(connection, rawTransaction, confirma
|
|
|
10014
10299
|
if (confirmationStrategyOrConfirmOptions && Object.prototype.hasOwnProperty.call(confirmationStrategyOrConfirmOptions, 'lastValidBlockHeight')) {
|
|
10015
10300
|
confirmationStrategy = confirmationStrategyOrConfirmOptions;
|
|
10016
10301
|
options = maybeConfirmOptions;
|
|
10302
|
+
} else if (confirmationStrategyOrConfirmOptions && Object.prototype.hasOwnProperty.call(confirmationStrategyOrConfirmOptions, 'nonceValue')) {
|
|
10303
|
+
confirmationStrategy = confirmationStrategyOrConfirmOptions;
|
|
10304
|
+
options = maybeConfirmOptions;
|
|
10017
10305
|
} else {
|
|
10018
10306
|
options = confirmationStrategyOrConfirmOptions;
|
|
10019
10307
|
}
|
|
@@ -10065,6 +10353,8 @@ exports.Loader = Loader;
|
|
|
10065
10353
|
exports.Lockup = Lockup;
|
|
10066
10354
|
exports.MAX_SEED_LENGTH = MAX_SEED_LENGTH;
|
|
10067
10355
|
exports.Message = Message;
|
|
10356
|
+
exports.MessageAccountKeys = MessageAccountKeys;
|
|
10357
|
+
exports.MessageV0 = MessageV0;
|
|
10068
10358
|
exports.NONCE_ACCOUNT_LENGTH = NONCE_ACCOUNT_LENGTH;
|
|
10069
10359
|
exports.NonceAccount = NonceAccount;
|
|
10070
10360
|
exports.PACKET_DATA_SIZE = PACKET_DATA_SIZE;
|
|
@@ -10096,11 +10386,16 @@ exports.SystemInstruction = SystemInstruction;
|
|
|
10096
10386
|
exports.SystemProgram = SystemProgram;
|
|
10097
10387
|
exports.Transaction = Transaction;
|
|
10098
10388
|
exports.TransactionExpiredBlockheightExceededError = TransactionExpiredBlockheightExceededError;
|
|
10389
|
+
exports.TransactionExpiredNonceInvalidError = TransactionExpiredNonceInvalidError;
|
|
10099
10390
|
exports.TransactionExpiredTimeoutError = TransactionExpiredTimeoutError;
|
|
10100
10391
|
exports.TransactionInstruction = TransactionInstruction;
|
|
10392
|
+
exports.TransactionMessage = TransactionMessage;
|
|
10101
10393
|
exports.VALIDATOR_INFO_KEY = VALIDATOR_INFO_KEY;
|
|
10394
|
+
exports.VERSION_PREFIX_MASK = VERSION_PREFIX_MASK;
|
|
10102
10395
|
exports.VOTE_PROGRAM_ID = VOTE_PROGRAM_ID;
|
|
10103
10396
|
exports.ValidatorInfo = ValidatorInfo;
|
|
10397
|
+
exports.VersionedMessage = VersionedMessage;
|
|
10398
|
+
exports.VersionedTransaction = VersionedTransaction;
|
|
10104
10399
|
exports.VoteAccount = VoteAccount;
|
|
10105
10400
|
exports.VoteAuthorizationLayout = VoteAuthorizationLayout;
|
|
10106
10401
|
exports.VoteInit = VoteInit;
|