@solana/web3.js 1.30.1 → 1.30.3
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/lib/index.browser.esm.js +164 -216
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +168 -225
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.esm.js +168 -224
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +28760 -28832
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +30 -30
- package/lib/index.iife.min.js.map +1 -1
- package/package.json +28 -28
- package/src/message.ts +9 -12
- package/src/transaction.ts +2 -2
- package/src/util/guarded-array-utils.ts +37 -0
- package/src/validator-info.ts +5 -4
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
2
1
|
import * as nacl from 'tweetnacl';
|
|
3
2
|
import nacl__default from 'tweetnacl';
|
|
4
3
|
import { Buffer } from 'buffer';
|
|
@@ -1725,8 +1724,7 @@ class Struct {
|
|
|
1725
1724
|
class Enum extends Struct {
|
|
1726
1725
|
constructor(properties) {
|
|
1727
1726
|
super(properties);
|
|
1728
|
-
|
|
1729
|
-
_defineProperty(this, "enum", '');
|
|
1727
|
+
this.enum = '';
|
|
1730
1728
|
|
|
1731
1729
|
if (Object.keys(properties).length !== 1) {
|
|
1732
1730
|
throw new Error('Enum can only take single value');
|
|
@@ -1766,8 +1764,7 @@ class PublicKey extends Struct {
|
|
|
1766
1764
|
*/
|
|
1767
1765
|
constructor(value) {
|
|
1768
1766
|
super({});
|
|
1769
|
-
|
|
1770
|
-
_defineProperty(this, "_bn", void 0);
|
|
1767
|
+
this._bn = void 0;
|
|
1771
1768
|
|
|
1772
1769
|
if (isPublicKeyData(value)) {
|
|
1773
1770
|
this._bn = value._bn;
|
|
@@ -1777,7 +1774,7 @@ class PublicKey extends Struct {
|
|
|
1777
1774
|
const decoded = bs58.decode(value);
|
|
1778
1775
|
|
|
1779
1776
|
if (decoded.length != 32) {
|
|
1780
|
-
throw new Error(
|
|
1777
|
+
throw new Error(`Invalid public key input`);
|
|
1781
1778
|
}
|
|
1782
1779
|
|
|
1783
1780
|
this._bn = new BN(decoded);
|
|
@@ -1786,7 +1783,7 @@ class PublicKey extends Struct {
|
|
|
1786
1783
|
}
|
|
1787
1784
|
|
|
1788
1785
|
if (this._bn.byteLength() > 32) {
|
|
1789
|
-
throw new Error(
|
|
1786
|
+
throw new Error(`Invalid public key input`);
|
|
1790
1787
|
}
|
|
1791
1788
|
}
|
|
1792
1789
|
}
|
|
@@ -1866,7 +1863,7 @@ class PublicKey extends Struct {
|
|
|
1866
1863
|
let buffer = Buffer.alloc(0);
|
|
1867
1864
|
seeds.forEach(function (seed) {
|
|
1868
1865
|
if (seed.length > MAX_SEED_LENGTH) {
|
|
1869
|
-
throw new TypeError(
|
|
1866
|
+
throw new TypeError(`Max seed length exceeded`);
|
|
1870
1867
|
}
|
|
1871
1868
|
|
|
1872
1869
|
buffer = Buffer.concat([buffer, toBuffer(seed)]);
|
|
@@ -1876,7 +1873,7 @@ class PublicKey extends Struct {
|
|
|
1876
1873
|
let publicKeyBytes = new BN(hash, 16).toArray(undefined, 32);
|
|
1877
1874
|
|
|
1878
1875
|
if (is_on_curve(publicKeyBytes)) {
|
|
1879
|
-
throw new Error(
|
|
1876
|
+
throw new Error(`Invalid seeds, address must fall off the curve`);
|
|
1880
1877
|
}
|
|
1881
1878
|
|
|
1882
1879
|
return new PublicKey(publicKeyBytes);
|
|
@@ -1910,7 +1907,7 @@ class PublicKey extends Struct {
|
|
|
1910
1907
|
return [address, nonce];
|
|
1911
1908
|
}
|
|
1912
1909
|
|
|
1913
|
-
throw new Error(
|
|
1910
|
+
throw new Error(`Unable to find a viable program address nonce`);
|
|
1914
1911
|
}
|
|
1915
1912
|
/**
|
|
1916
1913
|
* Check that a pubkey is on the ed25519 curve.
|
|
@@ -1922,9 +1919,7 @@ class PublicKey extends Struct {
|
|
|
1922
1919
|
}
|
|
1923
1920
|
|
|
1924
1921
|
}
|
|
1925
|
-
|
|
1926
|
-
_defineProperty(PublicKey, "default", new PublicKey('11111111111111111111111111111111'));
|
|
1927
|
-
|
|
1922
|
+
PublicKey.default = new PublicKey('11111111111111111111111111111111');
|
|
1928
1923
|
SOLANA_SCHEMA.set(PublicKey, {
|
|
1929
1924
|
kind: 'struct',
|
|
1930
1925
|
fields: [['_bn', 'u256']]
|
|
@@ -1997,7 +1992,7 @@ class Account {
|
|
|
1997
1992
|
* @param secretKey Secret key for the account
|
|
1998
1993
|
*/
|
|
1999
1994
|
constructor(secretKey) {
|
|
2000
|
-
|
|
1995
|
+
this._keypair = void 0;
|
|
2001
1996
|
|
|
2002
1997
|
if (secretKey) {
|
|
2003
1998
|
this._keypair = nacl.sign.keyPair.fromSecretKey(toBuffer(secretKey));
|
|
@@ -2122,27 +2117,52 @@ function encodeLength(bytes, len) {
|
|
|
2122
2117
|
}
|
|
2123
2118
|
}
|
|
2124
2119
|
|
|
2120
|
+
const END_OF_BUFFER_ERROR_MESSAGE = 'Reached end of buffer unexpectedly';
|
|
2125
2121
|
/**
|
|
2126
|
-
*
|
|
2122
|
+
* Delegates to `Array#shift`, but throws if the array is zero-length.
|
|
2127
2123
|
*/
|
|
2128
2124
|
|
|
2129
|
-
|
|
2125
|
+
function guardedShift(byteArray) {
|
|
2126
|
+
if (byteArray.length === 0) {
|
|
2127
|
+
throw new Error(END_OF_BUFFER_ERROR_MESSAGE);
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
return byteArray.shift();
|
|
2131
|
+
}
|
|
2130
2132
|
/**
|
|
2131
|
-
*
|
|
2133
|
+
* Delegates to `Array#splice`, but throws if the section being spliced out extends past the end of
|
|
2134
|
+
* the array.
|
|
2132
2135
|
*/
|
|
2133
2136
|
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
+
function guardedSplice(byteArray, ...args) {
|
|
2138
|
+
var _args$;
|
|
2139
|
+
|
|
2140
|
+
const [start] = args;
|
|
2137
2141
|
|
|
2138
|
-
|
|
2142
|
+
if (args.length === 2 // Implies that `deleteCount` was supplied
|
|
2143
|
+
? start + ((_args$ = args[1]) !== null && _args$ !== void 0 ? _args$ : 0) > byteArray.length : start >= byteArray.length) {
|
|
2144
|
+
throw new Error(END_OF_BUFFER_ERROR_MESSAGE);
|
|
2145
|
+
}
|
|
2139
2146
|
|
|
2140
|
-
|
|
2147
|
+
return byteArray.splice(...args);
|
|
2148
|
+
}
|
|
2141
2149
|
|
|
2142
|
-
|
|
2150
|
+
/**
|
|
2151
|
+
* The message header, identifying signed and read-only account
|
|
2152
|
+
*/
|
|
2143
2153
|
|
|
2144
|
-
|
|
2154
|
+
const PUBKEY_LENGTH = 32;
|
|
2155
|
+
/**
|
|
2156
|
+
* List of instructions to be processed atomically
|
|
2157
|
+
*/
|
|
2145
2158
|
|
|
2159
|
+
class Message {
|
|
2160
|
+
constructor(args) {
|
|
2161
|
+
this.header = void 0;
|
|
2162
|
+
this.accountKeys = void 0;
|
|
2163
|
+
this.recentBlockhash = void 0;
|
|
2164
|
+
this.instructions = void 0;
|
|
2165
|
+
this.indexToProgramIds = new Map();
|
|
2146
2166
|
this.header = args.header;
|
|
2147
2167
|
this.accountKeys = args.accountKeys.map(account => new PublicKey(account));
|
|
2148
2168
|
this.recentBlockhash = args.recentBlockhash;
|
|
@@ -2225,32 +2245,28 @@ class Message {
|
|
|
2225
2245
|
static from(buffer) {
|
|
2226
2246
|
// Slice up wire data
|
|
2227
2247
|
let byteArray = [...buffer];
|
|
2228
|
-
const numRequiredSignatures = byteArray
|
|
2229
|
-
const numReadonlySignedAccounts = byteArray
|
|
2230
|
-
const numReadonlyUnsignedAccounts = byteArray
|
|
2248
|
+
const numRequiredSignatures = guardedShift(byteArray);
|
|
2249
|
+
const numReadonlySignedAccounts = guardedShift(byteArray);
|
|
2250
|
+
const numReadonlyUnsignedAccounts = guardedShift(byteArray);
|
|
2231
2251
|
const accountCount = decodeLength(byteArray);
|
|
2232
2252
|
let accountKeys = [];
|
|
2233
2253
|
|
|
2234
2254
|
for (let i = 0; i < accountCount; i++) {
|
|
2235
|
-
const account = byteArray
|
|
2236
|
-
byteArray = byteArray.slice(PUBKEY_LENGTH);
|
|
2255
|
+
const account = guardedSplice(byteArray, 0, PUBKEY_LENGTH);
|
|
2237
2256
|
accountKeys.push(bs58.encode(Buffer.from(account)));
|
|
2238
2257
|
}
|
|
2239
2258
|
|
|
2240
|
-
const recentBlockhash = byteArray
|
|
2241
|
-
byteArray = byteArray.slice(PUBKEY_LENGTH);
|
|
2259
|
+
const recentBlockhash = guardedSplice(byteArray, 0, PUBKEY_LENGTH);
|
|
2242
2260
|
const instructionCount = decodeLength(byteArray);
|
|
2243
2261
|
let instructions = [];
|
|
2244
2262
|
|
|
2245
2263
|
for (let i = 0; i < instructionCount; i++) {
|
|
2246
|
-
const programIdIndex = byteArray
|
|
2264
|
+
const programIdIndex = guardedShift(byteArray);
|
|
2247
2265
|
const accountCount = decodeLength(byteArray);
|
|
2248
|
-
const accounts = byteArray
|
|
2249
|
-
byteArray = byteArray.slice(accountCount);
|
|
2266
|
+
const accounts = guardedSplice(byteArray, 0, accountCount);
|
|
2250
2267
|
const dataLength = decodeLength(byteArray);
|
|
2251
|
-
const dataSlice = byteArray
|
|
2268
|
+
const dataSlice = guardedSplice(byteArray, 0, dataLength);
|
|
2252
2269
|
const data = bs58.encode(Buffer.from(dataSlice));
|
|
2253
|
-
byteArray = byteArray.slice(dataLength);
|
|
2254
2270
|
instructions.push({
|
|
2255
2271
|
programIdIndex,
|
|
2256
2272
|
accounts,
|
|
@@ -2279,6 +2295,10 @@ function assert (condition, message) {
|
|
|
2279
2295
|
}
|
|
2280
2296
|
}
|
|
2281
2297
|
|
|
2298
|
+
/**
|
|
2299
|
+
* Transaction signature as base-58 encoded string
|
|
2300
|
+
*/
|
|
2301
|
+
|
|
2282
2302
|
/**
|
|
2283
2303
|
* Default (empty) signature
|
|
2284
2304
|
*
|
|
@@ -2316,12 +2336,9 @@ class TransactionInstruction {
|
|
|
2316
2336
|
* Program input
|
|
2317
2337
|
*/
|
|
2318
2338
|
constructor(opts) {
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
_defineProperty(this, "data", Buffer.alloc(0));
|
|
2324
|
-
|
|
2339
|
+
this.keys = void 0;
|
|
2340
|
+
this.programId = void 0;
|
|
2341
|
+
this.data = Buffer.alloc(0);
|
|
2325
2342
|
this.programId = opts.programId;
|
|
2326
2343
|
this.keys = opts.keys;
|
|
2327
2344
|
|
|
@@ -2363,16 +2380,11 @@ class Transaction {
|
|
|
2363
2380
|
* Construct an empty Transaction
|
|
2364
2381
|
*/
|
|
2365
2382
|
constructor(opts) {
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
_defineProperty(this, "recentBlockhash", void 0);
|
|
2373
|
-
|
|
2374
|
-
_defineProperty(this, "nonceInfo", void 0);
|
|
2375
|
-
|
|
2383
|
+
this.signatures = [];
|
|
2384
|
+
this.feePayer = void 0;
|
|
2385
|
+
this.instructions = [];
|
|
2386
|
+
this.recentBlockhash = void 0;
|
|
2387
|
+
this.nonceInfo = void 0;
|
|
2376
2388
|
opts && Object.assign(this, opts);
|
|
2377
2389
|
}
|
|
2378
2390
|
/**
|
|
@@ -2436,7 +2448,7 @@ class Transaction {
|
|
|
2436
2448
|
|
|
2437
2449
|
for (let i = 0; i < this.instructions.length; i++) {
|
|
2438
2450
|
if (this.instructions[i].programId === undefined) {
|
|
2439
|
-
throw new Error(
|
|
2451
|
+
throw new Error(`Transaction instruction index ${i} has undefined program id`);
|
|
2440
2452
|
}
|
|
2441
2453
|
}
|
|
2442
2454
|
|
|
@@ -2511,7 +2523,7 @@ class Transaction {
|
|
|
2511
2523
|
console.warn('Transaction references a signature that is unnecessary, ' + 'only the fee payer and instruction signer accounts should sign a transaction. ' + 'This behavior is deprecated and will throw an error in the next major version release.');
|
|
2512
2524
|
}
|
|
2513
2525
|
} else {
|
|
2514
|
-
throw new Error(
|
|
2526
|
+
throw new Error(`unknown signer: ${signature.publicKey.toString()}`);
|
|
2515
2527
|
}
|
|
2516
2528
|
}
|
|
2517
2529
|
|
|
@@ -2746,7 +2758,7 @@ class Transaction {
|
|
|
2746
2758
|
const index = this.signatures.findIndex(sigpair => pubkey.equals(sigpair.publicKey));
|
|
2747
2759
|
|
|
2748
2760
|
if (index < 0) {
|
|
2749
|
-
throw new Error(
|
|
2761
|
+
throw new Error(`unknown signer: ${pubkey.toString()}`);
|
|
2750
2762
|
}
|
|
2751
2763
|
|
|
2752
2764
|
this.signatures[index].signature = Buffer.from(signature);
|
|
@@ -2822,12 +2834,12 @@ class Transaction {
|
|
|
2822
2834
|
signature
|
|
2823
2835
|
}, index) => {
|
|
2824
2836
|
if (signature !== null) {
|
|
2825
|
-
assert(signature.length === 64,
|
|
2837
|
+
assert(signature.length === 64, `signature has invalid length`);
|
|
2826
2838
|
Buffer.from(signature).copy(wireTransaction, signatureCount.length + index * 64);
|
|
2827
2839
|
}
|
|
2828
2840
|
});
|
|
2829
2841
|
signData.copy(wireTransaction, signatureCount.length + signatures.length * 64);
|
|
2830
|
-
assert(wireTransaction.length <= PACKET_DATA_SIZE,
|
|
2842
|
+
assert(wireTransaction.length <= PACKET_DATA_SIZE, `Transaction too large: ${wireTransaction.length} > ${PACKET_DATA_SIZE}`);
|
|
2831
2843
|
return wireTransaction;
|
|
2832
2844
|
}
|
|
2833
2845
|
/**
|
|
@@ -2872,8 +2884,7 @@ class Transaction {
|
|
|
2872
2884
|
let signatures = [];
|
|
2873
2885
|
|
|
2874
2886
|
for (let i = 0; i < signatureCount; i++) {
|
|
2875
|
-
const signature = byteArray
|
|
2876
|
-
byteArray = byteArray.slice(SIGNATURE_LENGTH);
|
|
2887
|
+
const signature = guardedSplice(byteArray, 0, SIGNATURE_LENGTH);
|
|
2877
2888
|
signatures.push(bs58.encode(Buffer.from(signature)));
|
|
2878
2889
|
}
|
|
2879
2890
|
|
|
@@ -2946,7 +2957,7 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
|
|
|
2946
2957
|
const status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
|
|
2947
2958
|
|
|
2948
2959
|
if (status.err) {
|
|
2949
|
-
throw new Error(
|
|
2960
|
+
throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
|
|
2950
2961
|
}
|
|
2951
2962
|
|
|
2952
2963
|
return signature;
|
|
@@ -2989,7 +3000,7 @@ function decodeData(type, buffer) {
|
|
|
2989
3000
|
}
|
|
2990
3001
|
|
|
2991
3002
|
if (data.instruction !== type.index) {
|
|
2992
|
-
throw new Error(
|
|
3003
|
+
throw new Error(`invalid instruction; instruction index mismatch ${data.instruction} != ${type.index}`);
|
|
2993
3004
|
}
|
|
2994
3005
|
|
|
2995
3006
|
return data;
|
|
@@ -3023,12 +3034,9 @@ class NonceAccount {
|
|
|
3023
3034
|
* @internal
|
|
3024
3035
|
*/
|
|
3025
3036
|
constructor(args) {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
_defineProperty(this, "feeCalculator", void 0);
|
|
3031
|
-
|
|
3037
|
+
this.authorizedPubkey = void 0;
|
|
3038
|
+
this.nonce = void 0;
|
|
3039
|
+
this.feeCalculator = void 0;
|
|
3032
3040
|
this.authorizedPubkey = args.authorizedPubkey;
|
|
3033
3041
|
this.nonce = args.nonce;
|
|
3034
3042
|
this.feeCalculator = args.feeCalculator;
|
|
@@ -3329,7 +3337,7 @@ class SystemInstruction {
|
|
|
3329
3337
|
|
|
3330
3338
|
static checkKeyLength(keys, expectedLength) {
|
|
3331
3339
|
if (keys.length < expectedLength) {
|
|
3332
|
-
throw new Error(
|
|
3340
|
+
throw new Error(`invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`);
|
|
3333
3341
|
}
|
|
3334
3342
|
}
|
|
3335
3343
|
|
|
@@ -3761,8 +3769,7 @@ class SystemProgram {
|
|
|
3761
3769
|
}
|
|
3762
3770
|
|
|
3763
3771
|
}
|
|
3764
|
-
|
|
3765
|
-
_defineProperty(SystemProgram, "programId", new PublicKey('11111111111111111111111111111111'));
|
|
3772
|
+
SystemProgram.programId = new PublicKey('11111111111111111111111111111111');
|
|
3766
3773
|
|
|
3767
3774
|
// rest of the Transaction fields
|
|
3768
3775
|
//
|
|
@@ -3931,8 +3938,7 @@ class Loader {
|
|
|
3931
3938
|
}
|
|
3932
3939
|
|
|
3933
3940
|
}
|
|
3934
|
-
|
|
3935
|
-
_defineProperty(Loader, "chunkSize", CHUNK_SIZE);
|
|
3941
|
+
Loader.chunkSize = CHUNK_SIZE;
|
|
3936
3942
|
|
|
3937
3943
|
const BPF_LOADER_PROGRAM_ID = new PublicKey('BPFLoader2111111111111111111111111111111111');
|
|
3938
3944
|
/**
|
|
@@ -3983,14 +3989,10 @@ class AgentManager {
|
|
|
3983
3989
|
}
|
|
3984
3990
|
|
|
3985
3991
|
constructor(useHttps) {
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
_defineProperty(this, "_destroyTimeout", null);
|
|
3991
|
-
|
|
3992
|
-
_defineProperty(this, "_useHttps", void 0);
|
|
3993
|
-
|
|
3992
|
+
this._agent = void 0;
|
|
3993
|
+
this._activeRequests = 0;
|
|
3994
|
+
this._destroyTimeout = null;
|
|
3995
|
+
this._useHttps = void 0;
|
|
3994
3996
|
this._useHttps = useHttps === true;
|
|
3995
3997
|
this._agent = AgentManager._newAgent(this._useHttps);
|
|
3996
3998
|
}
|
|
@@ -4063,16 +4065,11 @@ class EpochSchedule {
|
|
|
4063
4065
|
|
|
4064
4066
|
/** The first slot of `firstNormalEpoch` */
|
|
4065
4067
|
constructor(slotsPerEpoch, leaderScheduleSlotOffset, warmup, firstNormalEpoch, firstNormalSlot) {
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
_defineProperty(this, "firstNormalEpoch", void 0);
|
|
4073
|
-
|
|
4074
|
-
_defineProperty(this, "firstNormalSlot", void 0);
|
|
4075
|
-
|
|
4068
|
+
this.slotsPerEpoch = void 0;
|
|
4069
|
+
this.leaderScheduleSlotOffset = void 0;
|
|
4070
|
+
this.warmup = void 0;
|
|
4071
|
+
this.firstNormalEpoch = void 0;
|
|
4072
|
+
this.firstNormalSlot = void 0;
|
|
4076
4073
|
this.slotsPerEpoch = slotsPerEpoch;
|
|
4077
4074
|
this.leaderScheduleSlotOffset = leaderScheduleSlotOffset;
|
|
4078
4075
|
this.warmup = warmup;
|
|
@@ -4124,9 +4121,7 @@ class EpochSchedule {
|
|
|
4124
4121
|
class SendTransactionError extends Error {
|
|
4125
4122
|
constructor(message, logs) {
|
|
4126
4123
|
super(message);
|
|
4127
|
-
|
|
4128
|
-
_defineProperty(this, "logs", void 0);
|
|
4129
|
-
|
|
4124
|
+
this.logs = void 0;
|
|
4130
4125
|
this.logs = logs;
|
|
4131
4126
|
}
|
|
4132
4127
|
|
|
@@ -4410,7 +4405,7 @@ function createRpcClient(url, useHttps, httpHeaders, fetchMiddleware, disableRet
|
|
|
4410
4405
|
break;
|
|
4411
4406
|
}
|
|
4412
4407
|
|
|
4413
|
-
console.log(
|
|
4408
|
+
console.log(`Server responded with ${res.status} ${res.statusText}. Retrying after ${waitTime}ms delay...`);
|
|
4414
4409
|
await sleep(waitTime);
|
|
4415
4410
|
waitTime *= 2;
|
|
4416
4411
|
}
|
|
@@ -4420,7 +4415,7 @@ function createRpcClient(url, useHttps, httpHeaders, fetchMiddleware, disableRet
|
|
|
4420
4415
|
if (res.ok) {
|
|
4421
4416
|
callback(null, text);
|
|
4422
4417
|
} else {
|
|
4423
|
-
callback(new Error(
|
|
4418
|
+
callback(new Error(`${res.status} ${res.statusText}: ${text}`));
|
|
4424
4419
|
}
|
|
4425
4420
|
} catch (err) {
|
|
4426
4421
|
if (err instanceof Error) callback(err);
|
|
@@ -5086,67 +5081,39 @@ class Connection {
|
|
|
5086
5081
|
* @param commitmentOrConfig optional default commitment level or optional ConnectionConfig configuration object
|
|
5087
5082
|
*/
|
|
5088
5083
|
constructor(endpoint, commitmentOrConfig) {
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
_defineProperty(this, "_rpcWebSocket", void 0);
|
|
5104
|
-
|
|
5105
|
-
_defineProperty(this, "_rpcWebSocketConnected", false);
|
|
5106
|
-
|
|
5107
|
-
_defineProperty(this, "_rpcWebSocketHeartbeat", null);
|
|
5108
|
-
|
|
5109
|
-
_defineProperty(this, "_rpcWebSocketIdleTimeout", null);
|
|
5110
|
-
|
|
5111
|
-
_defineProperty(this, "_disableBlockhashCaching", false);
|
|
5112
|
-
|
|
5113
|
-
_defineProperty(this, "_pollingBlockhash", false);
|
|
5114
|
-
|
|
5115
|
-
_defineProperty(this, "_blockhashInfo", {
|
|
5084
|
+
this._commitment = void 0;
|
|
5085
|
+
this._confirmTransactionInitialTimeout = void 0;
|
|
5086
|
+
this._rpcEndpoint = void 0;
|
|
5087
|
+
this._rpcWsEndpoint = void 0;
|
|
5088
|
+
this._rpcClient = void 0;
|
|
5089
|
+
this._rpcRequest = void 0;
|
|
5090
|
+
this._rpcBatchRequest = void 0;
|
|
5091
|
+
this._rpcWebSocket = void 0;
|
|
5092
|
+
this._rpcWebSocketConnected = false;
|
|
5093
|
+
this._rpcWebSocketHeartbeat = null;
|
|
5094
|
+
this._rpcWebSocketIdleTimeout = null;
|
|
5095
|
+
this._disableBlockhashCaching = false;
|
|
5096
|
+
this._pollingBlockhash = false;
|
|
5097
|
+
this._blockhashInfo = {
|
|
5116
5098
|
recentBlockhash: null,
|
|
5117
5099
|
lastFetch: 0,
|
|
5118
5100
|
transactionSignatures: [],
|
|
5119
5101
|
simulatedSignatures: []
|
|
5120
|
-
}
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
_defineProperty(this, "_signatureSubscriptions", {});
|
|
5137
|
-
|
|
5138
|
-
_defineProperty(this, "_slotSubscriptionCounter", 0);
|
|
5139
|
-
|
|
5140
|
-
_defineProperty(this, "_slotSubscriptions", {});
|
|
5141
|
-
|
|
5142
|
-
_defineProperty(this, "_logsSubscriptionCounter", 0);
|
|
5143
|
-
|
|
5144
|
-
_defineProperty(this, "_logsSubscriptions", {});
|
|
5145
|
-
|
|
5146
|
-
_defineProperty(this, "_slotUpdateSubscriptionCounter", 0);
|
|
5147
|
-
|
|
5148
|
-
_defineProperty(this, "_slotUpdateSubscriptions", {});
|
|
5149
|
-
|
|
5102
|
+
};
|
|
5103
|
+
this._accountChangeSubscriptionCounter = 0;
|
|
5104
|
+
this._accountChangeSubscriptions = {};
|
|
5105
|
+
this._programAccountChangeSubscriptionCounter = 0;
|
|
5106
|
+
this._programAccountChangeSubscriptions = {};
|
|
5107
|
+
this._rootSubscriptionCounter = 0;
|
|
5108
|
+
this._rootSubscriptions = {};
|
|
5109
|
+
this._signatureSubscriptionCounter = 0;
|
|
5110
|
+
this._signatureSubscriptions = {};
|
|
5111
|
+
this._slotSubscriptionCounter = 0;
|
|
5112
|
+
this._slotSubscriptions = {};
|
|
5113
|
+
this._logsSubscriptionCounter = 0;
|
|
5114
|
+
this._logsSubscriptions = {};
|
|
5115
|
+
this._slotUpdateSubscriptionCounter = 0;
|
|
5116
|
+
this._slotUpdateSubscriptions = {};
|
|
5150
5117
|
let url = new URL(endpoint);
|
|
5151
5118
|
const useHttps = url.protocol === 'https:';
|
|
5152
5119
|
let wsEndpoint;
|
|
@@ -5520,7 +5487,7 @@ class Connection {
|
|
|
5520
5487
|
const res = create(unsafeRes, jsonRpcResult(StakeActivationResult));
|
|
5521
5488
|
|
|
5522
5489
|
if ('error' in res) {
|
|
5523
|
-
throw new Error(
|
|
5490
|
+
throw new Error(`failed to get Stake Activation ${publicKey.toBase58()}: ${res.error.message}`);
|
|
5524
5491
|
}
|
|
5525
5492
|
|
|
5526
5493
|
return res.result;
|
|
@@ -5656,7 +5623,7 @@ class Connection {
|
|
|
5656
5623
|
|
|
5657
5624
|
if (response === null) {
|
|
5658
5625
|
const duration = (Date.now() - start) / 1000;
|
|
5659
|
-
throw new Error(
|
|
5626
|
+
throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
|
|
5660
5627
|
}
|
|
5661
5628
|
|
|
5662
5629
|
return response;
|
|
@@ -6430,7 +6397,7 @@ class Connection {
|
|
|
6430
6397
|
await sleep(MS_PER_SLOT / 2);
|
|
6431
6398
|
}
|
|
6432
6399
|
|
|
6433
|
-
throw new Error(
|
|
6400
|
+
throw new Error(`Unable to obtain a new blockhash after ${Date.now() - startTime}ms`);
|
|
6434
6401
|
} finally {
|
|
6435
6402
|
this._pollingBlockhash = false;
|
|
6436
6403
|
}
|
|
@@ -6687,7 +6654,7 @@ class Connection {
|
|
|
6687
6654
|
}
|
|
6688
6655
|
|
|
6689
6656
|
if (err instanceof Error) {
|
|
6690
|
-
console.error(
|
|
6657
|
+
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
6691
6658
|
}
|
|
6692
6659
|
}
|
|
6693
6660
|
}
|
|
@@ -6707,7 +6674,7 @@ class Connection {
|
|
|
6707
6674
|
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
6708
6675
|
} catch (err) {
|
|
6709
6676
|
if (err instanceof Error) {
|
|
6710
|
-
console.error(
|
|
6677
|
+
console.error(`${rpcMethod} error:`, err.message);
|
|
6711
6678
|
}
|
|
6712
6679
|
}
|
|
6713
6680
|
}
|
|
@@ -6872,7 +6839,7 @@ class Connection {
|
|
|
6872
6839
|
|
|
6873
6840
|
this._updateSubscriptions();
|
|
6874
6841
|
} else {
|
|
6875
|
-
throw new Error(
|
|
6842
|
+
throw new Error(`Unknown account change id: ${id}`);
|
|
6876
6843
|
}
|
|
6877
6844
|
}
|
|
6878
6845
|
/**
|
|
@@ -6938,7 +6905,7 @@ class Connection {
|
|
|
6938
6905
|
|
|
6939
6906
|
this._updateSubscriptions();
|
|
6940
6907
|
} else {
|
|
6941
|
-
throw new Error(
|
|
6908
|
+
throw new Error(`Unknown program account change id: ${id}`);
|
|
6942
6909
|
}
|
|
6943
6910
|
}
|
|
6944
6911
|
/**
|
|
@@ -6968,7 +6935,7 @@ class Connection {
|
|
|
6968
6935
|
|
|
6969
6936
|
async removeOnLogsListener(id) {
|
|
6970
6937
|
if (!this._logsSubscriptions[id]) {
|
|
6971
|
-
throw new Error(
|
|
6938
|
+
throw new Error(`Unknown logs id: ${id}`);
|
|
6972
6939
|
}
|
|
6973
6940
|
|
|
6974
6941
|
const subInfo = this._logsSubscriptions[id];
|
|
@@ -7044,7 +7011,7 @@ class Connection {
|
|
|
7044
7011
|
|
|
7045
7012
|
this._updateSubscriptions();
|
|
7046
7013
|
} else {
|
|
7047
|
-
throw new Error(
|
|
7014
|
+
throw new Error(`Unknown slot change id: ${id}`);
|
|
7048
7015
|
}
|
|
7049
7016
|
}
|
|
7050
7017
|
/**
|
|
@@ -7097,7 +7064,7 @@ class Connection {
|
|
|
7097
7064
|
|
|
7098
7065
|
this._updateSubscriptions();
|
|
7099
7066
|
} else {
|
|
7100
|
-
throw new Error(
|
|
7067
|
+
throw new Error(`Unknown slot update id: ${id}`);
|
|
7101
7068
|
}
|
|
7102
7069
|
}
|
|
7103
7070
|
|
|
@@ -7238,7 +7205,7 @@ class Connection {
|
|
|
7238
7205
|
|
|
7239
7206
|
this._updateSubscriptions();
|
|
7240
7207
|
} else {
|
|
7241
|
-
throw new Error(
|
|
7208
|
+
throw new Error(`Unknown signature result id: ${id}`);
|
|
7242
7209
|
}
|
|
7243
7210
|
}
|
|
7244
7211
|
/**
|
|
@@ -7290,7 +7257,7 @@ class Connection {
|
|
|
7290
7257
|
|
|
7291
7258
|
this._updateSubscriptions();
|
|
7292
7259
|
} else {
|
|
7293
|
-
throw new Error(
|
|
7260
|
+
throw new Error(`Unknown root change id: ${id}`);
|
|
7294
7261
|
}
|
|
7295
7262
|
}
|
|
7296
7263
|
|
|
@@ -7311,7 +7278,7 @@ class Keypair {
|
|
|
7311
7278
|
* @param keypair ed25519 keypair
|
|
7312
7279
|
*/
|
|
7313
7280
|
constructor(keypair) {
|
|
7314
|
-
|
|
7281
|
+
this._keypair = void 0;
|
|
7315
7282
|
|
|
7316
7283
|
if (keypair) {
|
|
7317
7284
|
this._keypair = keypair;
|
|
@@ -7415,8 +7382,8 @@ class Ed25519Program {
|
|
|
7415
7382
|
signature,
|
|
7416
7383
|
instructionIndex
|
|
7417
7384
|
} = params;
|
|
7418
|
-
assert(publicKey.length === PUBLIC_KEY_BYTES$1,
|
|
7419
|
-
assert(signature.length === SIGNATURE_BYTES,
|
|
7385
|
+
assert(publicKey.length === PUBLIC_KEY_BYTES$1, `Public Key must be ${PUBLIC_KEY_BYTES$1} bytes but received ${publicKey.length} bytes`);
|
|
7386
|
+
assert(signature.length === SIGNATURE_BYTES, `Signature must be ${SIGNATURE_BYTES} bytes but received ${signature.length} bytes`);
|
|
7420
7387
|
const publicKeyOffset = ED25519_INSTRUCTION_LAYOUT.span;
|
|
7421
7388
|
const signatureOffset = publicKeyOffset + publicKey.length;
|
|
7422
7389
|
const messageDataOffset = signatureOffset + signature.length;
|
|
@@ -7454,7 +7421,7 @@ class Ed25519Program {
|
|
|
7454
7421
|
message,
|
|
7455
7422
|
instructionIndex
|
|
7456
7423
|
} = params;
|
|
7457
|
-
assert(privateKey.length === PRIVATE_KEY_BYTES$1,
|
|
7424
|
+
assert(privateKey.length === PRIVATE_KEY_BYTES$1, `Private key must be ${PRIVATE_KEY_BYTES$1} bytes but received ${privateKey.length} bytes`);
|
|
7458
7425
|
|
|
7459
7426
|
try {
|
|
7460
7427
|
const keypair = Keypair.fromSecretKey(privateKey);
|
|
@@ -7467,13 +7434,12 @@ class Ed25519Program {
|
|
|
7467
7434
|
instructionIndex
|
|
7468
7435
|
});
|
|
7469
7436
|
} catch (error) {
|
|
7470
|
-
throw new Error(
|
|
7437
|
+
throw new Error(`Error creating instruction; ${error}`);
|
|
7471
7438
|
}
|
|
7472
7439
|
}
|
|
7473
7440
|
|
|
7474
7441
|
}
|
|
7475
|
-
|
|
7476
|
-
_defineProperty(Ed25519Program, "programId", new PublicKey('Ed25519SigVerify111111111111111111111111111'));
|
|
7442
|
+
Ed25519Program.programId = new PublicKey('Ed25519SigVerify111111111111111111111111111');
|
|
7477
7443
|
|
|
7478
7444
|
/**
|
|
7479
7445
|
* Address of the stake config account which configures the rate
|
|
@@ -7496,10 +7462,8 @@ class Authorized {
|
|
|
7496
7462
|
* @param withdrawer the withdraw authority
|
|
7497
7463
|
*/
|
|
7498
7464
|
constructor(staker, withdrawer) {
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
_defineProperty(this, "withdrawer", void 0);
|
|
7502
|
-
|
|
7465
|
+
this.staker = void 0;
|
|
7466
|
+
this.withdrawer = void 0;
|
|
7503
7467
|
this.staker = staker;
|
|
7504
7468
|
this.withdrawer = withdrawer;
|
|
7505
7469
|
}
|
|
@@ -7520,12 +7484,9 @@ class Lockup {
|
|
|
7520
7484
|
* Create a new Lockup object
|
|
7521
7485
|
*/
|
|
7522
7486
|
constructor(unixTimestamp, epoch, custodian) {
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
_defineProperty(this, "custodian", void 0);
|
|
7528
|
-
|
|
7487
|
+
this.unixTimestamp = void 0;
|
|
7488
|
+
this.epoch = void 0;
|
|
7489
|
+
this.custodian = void 0;
|
|
7529
7490
|
this.unixTimestamp = unixTimestamp;
|
|
7530
7491
|
this.epoch = epoch;
|
|
7531
7492
|
this.custodian = custodian;
|
|
@@ -7540,7 +7501,7 @@ class Lockup {
|
|
|
7540
7501
|
* Create stake account transaction params
|
|
7541
7502
|
*/
|
|
7542
7503
|
|
|
7543
|
-
|
|
7504
|
+
Lockup.default = new Lockup(0, 0, PublicKey.default);
|
|
7544
7505
|
|
|
7545
7506
|
/**
|
|
7546
7507
|
* Stake Instruction class
|
|
@@ -7753,7 +7714,7 @@ class StakeInstruction {
|
|
|
7753
7714
|
|
|
7754
7715
|
static checkKeyLength(keys, expectedLength) {
|
|
7755
7716
|
if (keys.length < expectedLength) {
|
|
7756
|
-
throw new Error(
|
|
7717
|
+
throw new Error(`invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`);
|
|
7757
7718
|
}
|
|
7758
7719
|
}
|
|
7759
7720
|
|
|
@@ -8228,10 +8189,8 @@ class StakeProgram {
|
|
|
8228
8189
|
}
|
|
8229
8190
|
|
|
8230
8191
|
}
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
_defineProperty(StakeProgram, "space", 200);
|
|
8192
|
+
StakeProgram.programId = new PublicKey('Stake11111111111111111111111111111111111111');
|
|
8193
|
+
StakeProgram.space = 200;
|
|
8235
8194
|
|
|
8236
8195
|
const {
|
|
8237
8196
|
publicKeyCreate,
|
|
@@ -8261,12 +8220,12 @@ class Secp256k1Program {
|
|
|
8261
8220
|
* @param {Buffer} publicKey a 64 byte secp256k1 public key buffer
|
|
8262
8221
|
*/
|
|
8263
8222
|
static publicKeyToEthAddress(publicKey) {
|
|
8264
|
-
assert(publicKey.length === PUBLIC_KEY_BYTES,
|
|
8223
|
+
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
8265
8224
|
|
|
8266
8225
|
try {
|
|
8267
8226
|
return Buffer.from(keccak_256.update(toBuffer(publicKey)).digest()).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
8268
8227
|
} catch (error) {
|
|
8269
|
-
throw new Error(
|
|
8228
|
+
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
8270
8229
|
}
|
|
8271
8230
|
}
|
|
8272
8231
|
/**
|
|
@@ -8317,7 +8276,7 @@ class Secp256k1Program {
|
|
|
8317
8276
|
ethAddress = rawAddress;
|
|
8318
8277
|
}
|
|
8319
8278
|
|
|
8320
|
-
assert(ethAddress.length === ETHEREUM_ADDRESS_BYTES,
|
|
8279
|
+
assert(ethAddress.length === ETHEREUM_ADDRESS_BYTES, `Address must be ${ETHEREUM_ADDRESS_BYTES} bytes but received ${ethAddress.length} bytes`);
|
|
8321
8280
|
const dataStart = 1 + SIGNATURE_OFFSETS_SERIALIZED_SIZE;
|
|
8322
8281
|
const ethAddressOffset = dataStart;
|
|
8323
8282
|
const signatureOffset = dataStart + ethAddress.length;
|
|
@@ -8356,7 +8315,7 @@ class Secp256k1Program {
|
|
|
8356
8315
|
message,
|
|
8357
8316
|
instructionIndex
|
|
8358
8317
|
} = params;
|
|
8359
|
-
assert(pkey.length === PRIVATE_KEY_BYTES,
|
|
8318
|
+
assert(pkey.length === PRIVATE_KEY_BYTES, `Private key must be ${PRIVATE_KEY_BYTES} bytes but received ${pkey.length} bytes`);
|
|
8360
8319
|
|
|
8361
8320
|
try {
|
|
8362
8321
|
const privateKey = toBuffer(pkey);
|
|
@@ -8375,13 +8334,12 @@ class Secp256k1Program {
|
|
|
8375
8334
|
instructionIndex
|
|
8376
8335
|
});
|
|
8377
8336
|
} catch (error) {
|
|
8378
|
-
throw new Error(
|
|
8337
|
+
throw new Error(`Error creating instruction; ${error}`);
|
|
8379
8338
|
}
|
|
8380
8339
|
}
|
|
8381
8340
|
|
|
8382
8341
|
}
|
|
8383
|
-
|
|
8384
|
-
_defineProperty(Secp256k1Program, "programId", new PublicKey('KeccakSecp256k11111111111111111111111111111'));
|
|
8342
|
+
Secp256k1Program.programId = new PublicKey('KeccakSecp256k11111111111111111111111111111');
|
|
8385
8343
|
|
|
8386
8344
|
const VALIDATOR_INFO_KEY = new PublicKey('Va1idator1nfo111111111111111111111111111111');
|
|
8387
8345
|
/**
|
|
@@ -8414,10 +8372,8 @@ class ValidatorInfo {
|
|
|
8414
8372
|
* @param info validator information
|
|
8415
8373
|
*/
|
|
8416
8374
|
constructor(key, info) {
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
_defineProperty(this, "info", void 0);
|
|
8420
|
-
|
|
8375
|
+
this.key = void 0;
|
|
8376
|
+
this.info = void 0;
|
|
8421
8377
|
this.key = key;
|
|
8422
8378
|
this.info = info;
|
|
8423
8379
|
}
|
|
@@ -8438,10 +8394,8 @@ class ValidatorInfo {
|
|
|
8438
8394
|
const configKeys = [];
|
|
8439
8395
|
|
|
8440
8396
|
for (let i = 0; i < 2; i++) {
|
|
8441
|
-
const publicKey = new PublicKey(byteArray
|
|
8442
|
-
|
|
8443
|
-
const isSigner = byteArray.slice(0, 1)[0] === 1;
|
|
8444
|
-
byteArray = byteArray.slice(1);
|
|
8397
|
+
const publicKey = new PublicKey(guardedSplice(byteArray, 0, PUBKEY_LENGTH));
|
|
8398
|
+
const isSigner = guardedShift(byteArray) === 1;
|
|
8445
8399
|
configKeys.push({
|
|
8446
8400
|
publicKey,
|
|
8447
8401
|
isSigner
|
|
@@ -8481,26 +8435,16 @@ class VoteAccount {
|
|
|
8481
8435
|
* @internal
|
|
8482
8436
|
*/
|
|
8483
8437
|
constructor(args) {
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
_defineProperty(this, "rootSlot", void 0);
|
|
8495
|
-
|
|
8496
|
-
_defineProperty(this, "epoch", void 0);
|
|
8497
|
-
|
|
8498
|
-
_defineProperty(this, "credits", void 0);
|
|
8499
|
-
|
|
8500
|
-
_defineProperty(this, "lastEpochCredits", void 0);
|
|
8501
|
-
|
|
8502
|
-
_defineProperty(this, "epochCredits", void 0);
|
|
8503
|
-
|
|
8438
|
+
this.nodePubkey = void 0;
|
|
8439
|
+
this.authorizedVoterPubkey = void 0;
|
|
8440
|
+
this.authorizedWithdrawerPubkey = void 0;
|
|
8441
|
+
this.commission = void 0;
|
|
8442
|
+
this.votes = void 0;
|
|
8443
|
+
this.rootSlot = void 0;
|
|
8444
|
+
this.epoch = void 0;
|
|
8445
|
+
this.credits = void 0;
|
|
8446
|
+
this.lastEpochCredits = void 0;
|
|
8447
|
+
this.epochCredits = void 0;
|
|
8504
8448
|
this.nodePubkey = args.nodePubkey;
|
|
8505
8449
|
this.authorizedVoterPubkey = args.authorizedVoterPubkey;
|
|
8506
8450
|
this.authorizedWithdrawerPubkey = args.authorizedWithdrawerPubkey;
|
|
@@ -8563,7 +8507,7 @@ async function sendAndConfirmRawTransaction(connection, rawTransaction, options)
|
|
|
8563
8507
|
const status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
|
|
8564
8508
|
|
|
8565
8509
|
if (status.err) {
|
|
8566
|
-
throw new Error(
|
|
8510
|
+
throw new Error(`Raw transaction ${signature} failed (${JSON.stringify(status)})`);
|
|
8567
8511
|
}
|
|
8568
8512
|
|
|
8569
8513
|
return signature;
|
|
@@ -8595,7 +8539,7 @@ function clusterApiUrl(cluster, tls) {
|
|
|
8595
8539
|
const url = endpoint[key][cluster];
|
|
8596
8540
|
|
|
8597
8541
|
if (!url) {
|
|
8598
|
-
throw new Error(
|
|
8542
|
+
throw new Error(`Unknown ${key} cluster: ${cluster}`);
|
|
8599
8543
|
}
|
|
8600
8544
|
|
|
8601
8545
|
return url;
|