zkcloudworker 0.7.15 → 0.8.1
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/ts/src/cloud/config.js +1 -1
- package/lib/ts/src/cloud/utils/hash.d.ts +7 -0
- package/lib/ts/src/cloud/utils/hash.js +101 -0
- package/lib/ts/src/cloud/utils/index.d.ts +1 -0
- package/lib/ts/src/cloud/utils/index.js +1 -0
- package/lib/ts/src/cloud/worker/cloud.d.ts +2 -1
- package/lib/ts/src/mina/api/api.d.ts +1 -1
- package/lib/ts/src/mina/api/api.js +9 -3
- package/lib/ts/src/mina/local/local.d.ts +3 -6
- package/lib/ts/src/mina/local/local.js +17 -14
- package/lib/ts/src/mina/utils/base64.d.ts +0 -6
- package/lib/ts/src/mina/utils/base64.js +6 -91
- package/lib/ts/tsconfig.tsbuildinfo +1 -1
- package/lib/web/src/cloud/config.js +1 -1
- package/lib/web/src/cloud/config.js.map +1 -1
- package/lib/web/src/cloud/utils/hash.d.ts +7 -0
- package/lib/web/src/cloud/utils/hash.js +89 -0
- package/lib/web/src/cloud/utils/hash.js.map +1 -0
- package/lib/web/src/cloud/utils/index.d.ts +1 -0
- package/lib/web/src/cloud/utils/index.js +1 -0
- package/lib/web/src/cloud/utils/index.js.map +1 -1
- package/lib/web/src/cloud/worker/cloud.d.ts +2 -1
- package/lib/web/src/cloud/worker/cloud.js.map +1 -1
- package/lib/web/src/mina/api/api.d.ts +1 -1
- package/lib/web/src/mina/api/api.js +9 -3
- package/lib/web/src/mina/api/api.js.map +1 -1
- package/lib/web/src/mina/local/local.d.ts +3 -6
- package/lib/web/src/mina/local/local.js +17 -14
- package/lib/web/src/mina/local/local.js.map +1 -1
- package/lib/web/src/mina/utils/base64.d.ts +0 -6
- package/lib/web/src/mina/utils/base64.js +1 -80
- package/lib/web/src/mina/utils/base64.js.map +1 -1
- package/lib/web/tsconfig.web.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const config = {
|
4
4
|
MINAFEE: "200000000",
|
5
5
|
ZKCLOUDWORKER_AUTH: "M6t4jtbBAFFXhLERHQWyEB9JA9xi4cWqmYduaCXtbrFjb7yaY7TyaXDunKDJNiUTBEcyUomNXJgC",
|
6
|
-
ZKCLOUDWORKER_API: "https://cuq99yahhi.execute-api.eu-west-1.amazonaws.com/dev/
|
6
|
+
ZKCLOUDWORKER_API: "https://cuq99yahhi.execute-api.eu-west-1.amazonaws.com/dev/",
|
7
7
|
};
|
8
8
|
exports.default = config;
|
@@ -0,0 +1,7 @@
|
|
1
|
+
export declare function stringHash(jsonString: string): string;
|
2
|
+
export declare function bigintToBase56(value: bigint): string;
|
3
|
+
export declare function bigintFromBase56(str: string): bigint;
|
4
|
+
export declare function bigintToBase64(value: bigint): string;
|
5
|
+
export declare function bigintFromBase64(str: string): bigint;
|
6
|
+
export declare function fromBase(digits: bigint[], base: bigint): bigint;
|
7
|
+
export declare function toBase(x: bigint, base: bigint): bigint[];
|
@@ -0,0 +1,101 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.toBase = exports.fromBase = exports.bigintFromBase64 = exports.bigintToBase64 = exports.bigintFromBase56 = exports.bigintToBase56 = exports.stringHash = void 0;
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
8
|
+
function stringHash(jsonString) {
|
9
|
+
if (typeof jsonString !== "string")
|
10
|
+
throw new Error("stringHash: input must be a string");
|
11
|
+
return bigintToBase56(BigInt("0x" + crypto_1.default.createHash("sha256").update(jsonString).digest("hex")));
|
12
|
+
}
|
13
|
+
exports.stringHash = stringHash;
|
14
|
+
// URL friendly base64 encoding
|
15
|
+
const TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
16
|
+
function bigintToBase56(value) {
|
17
|
+
const digits = toBase(value, 56n);
|
18
|
+
//console.log("digits:", digits);
|
19
|
+
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
20
|
+
//console.log("str:", str);
|
21
|
+
return str;
|
22
|
+
}
|
23
|
+
exports.bigintToBase56 = bigintToBase56;
|
24
|
+
function bigintFromBase56(str) {
|
25
|
+
const base56Digits = str.split("").map((x) => BigInt(TABLE.indexOf(x)));
|
26
|
+
const x = fromBase(base56Digits, 56n);
|
27
|
+
return x;
|
28
|
+
}
|
29
|
+
exports.bigintFromBase56 = bigintFromBase56;
|
30
|
+
function bigintToBase64(value) {
|
31
|
+
const digits = toBase(value, 64n);
|
32
|
+
//console.log("digits:", digits);
|
33
|
+
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
34
|
+
//console.log("str:", str);
|
35
|
+
return str;
|
36
|
+
}
|
37
|
+
exports.bigintToBase64 = bigintToBase64;
|
38
|
+
function bigintFromBase64(str) {
|
39
|
+
const base64Digits = str.split("").map((x) => BigInt(TABLE.indexOf(x)));
|
40
|
+
const x = fromBase(base64Digits, 64n);
|
41
|
+
return x;
|
42
|
+
}
|
43
|
+
exports.bigintFromBase64 = bigintFromBase64;
|
44
|
+
function fromBase(digits, base) {
|
45
|
+
if (base <= 0n)
|
46
|
+
throw Error("fromBase: base must be positive");
|
47
|
+
// compute powers base, base^2, base^4, ..., base^(2^k)
|
48
|
+
// with largest k s.t. n = 2^k < digits.length
|
49
|
+
let basePowers = [];
|
50
|
+
for (let power = base, n = 1; n < digits.length; power **= 2n, n *= 2) {
|
51
|
+
basePowers.push(power);
|
52
|
+
}
|
53
|
+
let k = basePowers.length;
|
54
|
+
// pad digits array with zeros s.t. digits.length === 2^k
|
55
|
+
digits = digits.concat(Array(2 ** k - digits.length).fill(0n));
|
56
|
+
// accumulate [x0, x1, x2, x3, ...] -> [x0 + base*x1, x2 + base*x3, ...] -> [x0 + base*x1 + base^2*(x2 + base*x3), ...] -> ...
|
57
|
+
// until we end up with a single element
|
58
|
+
for (let i = 0; i < k; i++) {
|
59
|
+
let newDigits = Array(digits.length >> 1);
|
60
|
+
let basePower = basePowers[i];
|
61
|
+
for (let j = 0; j < newDigits.length; j++) {
|
62
|
+
newDigits[j] = digits[2 * j] + basePower * digits[2 * j + 1];
|
63
|
+
}
|
64
|
+
digits = newDigits;
|
65
|
+
}
|
66
|
+
console.assert(digits.length === 1);
|
67
|
+
let [digit] = digits;
|
68
|
+
return digit;
|
69
|
+
}
|
70
|
+
exports.fromBase = fromBase;
|
71
|
+
function toBase(x, base) {
|
72
|
+
if (base <= 0n)
|
73
|
+
throw Error("toBase: base must be positive");
|
74
|
+
// compute powers base, base^2, base^4, ..., base^(2^k)
|
75
|
+
// with largest k s.t. base^(2^k) < x
|
76
|
+
let basePowers = [];
|
77
|
+
for (let power = base; power <= x; power **= 2n) {
|
78
|
+
basePowers.push(power);
|
79
|
+
}
|
80
|
+
let digits = [x]; // single digit w.r.t base^(2^(k+1))
|
81
|
+
// successively split digits w.r.t. base^(2^j) into digits w.r.t. base^(2^(j-1))
|
82
|
+
// until we arrive at digits w.r.t. base
|
83
|
+
let k = basePowers.length;
|
84
|
+
for (let i = 0; i < k; i++) {
|
85
|
+
let newDigits = Array(2 * digits.length);
|
86
|
+
let basePower = basePowers[k - 1 - i];
|
87
|
+
for (let j = 0; j < digits.length; j++) {
|
88
|
+
let x = digits[j];
|
89
|
+
let high = x / basePower;
|
90
|
+
newDigits[2 * j + 1] = high;
|
91
|
+
newDigits[2 * j] = x - high * basePower;
|
92
|
+
}
|
93
|
+
digits = newDigits;
|
94
|
+
}
|
95
|
+
// pop "leading" zero digits
|
96
|
+
while (digits[digits.length - 1] === 0n) {
|
97
|
+
digits.pop();
|
98
|
+
}
|
99
|
+
return digits;
|
100
|
+
}
|
101
|
+
exports.toBase = toBase;
|
@@ -43,6 +43,7 @@ export interface CloudTransaction {
|
|
43
43
|
txId: string;
|
44
44
|
transaction: string;
|
45
45
|
timeReceived: number;
|
46
|
+
status: string;
|
46
47
|
}
|
47
48
|
export declare abstract class Cloud {
|
48
49
|
readonly id: string;
|
@@ -202,7 +203,7 @@ export declare abstract class Cloud {
|
|
202
203
|
* Abstract method to send the transactions
|
203
204
|
* @param transactions
|
204
205
|
*/
|
205
|
-
abstract sendTransactions(transactions: string[] | CloudTransaction[]): Promise<
|
206
|
+
abstract sendTransactions(transactions: string[] | CloudTransaction[]): Promise<CloudTransaction[]>;
|
206
207
|
/**
|
207
208
|
* Abstract method to delete the transaction
|
208
209
|
* Used to delete the transaction
|
@@ -22,7 +22,7 @@ export type ApiCommand = "recursiveProof" | "execute" | "sendTransactions" | "jo
|
|
22
22
|
*/
|
23
23
|
export declare class zkCloudWorkerClient {
|
24
24
|
readonly jwt: string;
|
25
|
-
readonly endpoint
|
25
|
+
readonly endpoint?: string;
|
26
26
|
readonly chain: blockchain;
|
27
27
|
readonly webhook?: string;
|
28
28
|
readonly localWorker?: (cloud: Cloud) => Promise<zkCloudWorker>;
|
@@ -28,10 +28,14 @@ class zkCloudWorkerClient {
|
|
28
28
|
* @param params.webhook The webhook for the serverless api to get the results
|
29
29
|
*/
|
30
30
|
constructor(params) {
|
31
|
-
const { jwt, zkcloudworker,
|
31
|
+
const { jwt, zkcloudworker, webhook } = params;
|
32
32
|
this.jwt = jwt;
|
33
|
-
|
34
|
-
this.chain = chain
|
33
|
+
const chain = params.chain ?? "devnet";
|
34
|
+
this.chain = chain;
|
35
|
+
this.endpoint =
|
36
|
+
chain === "devnet" || chain === "zeko"
|
37
|
+
? ZKCLOUDWORKER_API + chain
|
38
|
+
: undefined;
|
35
39
|
this.webhook = webhook;
|
36
40
|
if (jwt === "local") {
|
37
41
|
if (zkcloudworker === undefined)
|
@@ -423,6 +427,8 @@ class zkCloudWorkerClient {
|
|
423
427
|
}
|
424
428
|
}
|
425
429
|
else {
|
430
|
+
if (this.endpoint === undefined)
|
431
|
+
throw new Error("zkCloudWorker supports only devnet and zeko chains in the cloud.");
|
426
432
|
const apiData = {
|
427
433
|
auth: ZKCLOUDWORKER_AUTH,
|
428
434
|
command: command,
|
@@ -81,13 +81,13 @@ export declare class LocalCloud extends Cloud {
|
|
81
81
|
* @param transactions the transactions to add
|
82
82
|
* @returns the transaction ids
|
83
83
|
*/
|
84
|
-
sendTransactions(transactions: string[]): Promise<
|
84
|
+
sendTransactions(transactions: string[]): Promise<CloudTransaction[]>;
|
85
85
|
/**
|
86
86
|
* Adds transactions to the local cloud
|
87
87
|
* @param transactions the transactions to add
|
88
88
|
* @returns the transaction ids
|
89
89
|
*/
|
90
|
-
static addTransactions(transactions: string[] | CloudTransaction[]): Promise<
|
90
|
+
static addTransactions(transactions: string[] | CloudTransaction[]): Promise<CloudTransaction[]>;
|
91
91
|
/**
|
92
92
|
* Deletes a transaction from the local cloud
|
93
93
|
* @param txId the transaction id to delete
|
@@ -238,10 +238,7 @@ export declare class LocalStorage {
|
|
238
238
|
[key: string]: string;
|
239
239
|
};
|
240
240
|
static transactions: {
|
241
|
-
[key: string]:
|
242
|
-
transaction: string;
|
243
|
-
timeReceived: number;
|
244
|
-
};
|
241
|
+
[key: string]: CloudTransaction;
|
245
242
|
};
|
246
243
|
static tasks: {
|
247
244
|
[key: string]: TaskData;
|
@@ -4,6 +4,7 @@ exports.LocalStorage = exports.LocalCloud = void 0;
|
|
4
4
|
const cloud_1 = require("../../cloud");
|
5
5
|
const cloud_2 = require("../../cloud");
|
6
6
|
const cloud_3 = require("../../cloud");
|
7
|
+
const cloud_4 = require("../../cloud");
|
7
8
|
/**
|
8
9
|
* LocalCloud is a cloud that runs on the local machine for testing and development
|
9
10
|
* It uses LocalStorage to store jobs, tasks, transactions, and data
|
@@ -115,8 +116,9 @@ class LocalCloud extends cloud_1.Cloud {
|
|
115
116
|
* Generates an id for local cloud
|
116
117
|
* @returns generated unique id
|
117
118
|
*/
|
118
|
-
static generateId() {
|
119
|
-
|
119
|
+
static generateId(tx = undefined) {
|
120
|
+
const data = tx ?? JSON.stringify({ time: Date.now(), data: (0, cloud_2.makeString)(32) });
|
121
|
+
return (0, cloud_4.stringHash)(data);
|
120
122
|
}
|
121
123
|
/**
|
122
124
|
* Send transactions to the local cloud
|
@@ -133,19 +135,25 @@ class LocalCloud extends cloud_1.Cloud {
|
|
133
135
|
*/
|
134
136
|
static async addTransactions(transactions) {
|
135
137
|
const timeReceived = Date.now();
|
136
|
-
const
|
138
|
+
const txs = [];
|
137
139
|
transactions.forEach((tx) => {
|
138
140
|
if (typeof tx === "string") {
|
139
|
-
const
|
140
|
-
|
141
|
-
|
141
|
+
const txId = LocalCloud.generateId(JSON.stringify({ tx, time: timeReceived }));
|
142
|
+
const transaction = {
|
143
|
+
txId,
|
144
|
+
transaction: tx,
|
145
|
+
timeReceived,
|
146
|
+
status: "accepted",
|
147
|
+
};
|
148
|
+
LocalStorage.transactions[txId] = transaction;
|
149
|
+
txs.push(transaction);
|
142
150
|
}
|
143
151
|
else {
|
144
152
|
LocalStorage.transactions[tx.txId] = tx;
|
145
|
-
|
153
|
+
txs.push(tx);
|
146
154
|
}
|
147
155
|
});
|
148
|
-
return
|
156
|
+
return txs;
|
149
157
|
}
|
150
158
|
/**
|
151
159
|
* Deletes a transaction from the local cloud
|
@@ -158,12 +166,7 @@ class LocalCloud extends cloud_1.Cloud {
|
|
158
166
|
}
|
159
167
|
async getTransactions() {
|
160
168
|
const txs = Object.keys(LocalStorage.transactions).map((txId) => {
|
161
|
-
|
162
|
-
return {
|
163
|
-
txId,
|
164
|
-
transaction,
|
165
|
-
timeReceived,
|
166
|
-
};
|
169
|
+
return LocalStorage.transactions[txId];
|
167
170
|
});
|
168
171
|
return txs;
|
169
172
|
}
|
@@ -1,11 +1,5 @@
|
|
1
1
|
import { Field } from "o1js";
|
2
2
|
export declare function fieldToBase56(field: Field): string;
|
3
|
-
export declare function bigintToBase56(value: bigint): string;
|
4
3
|
export declare function fieldFromBase56(str: string): Field;
|
5
|
-
export declare function bigintFromBase56(str: string): bigint;
|
6
4
|
export declare function fieldToBase64(field: Field): string;
|
7
|
-
export declare function bigintToBase64(value: bigint): string;
|
8
5
|
export declare function fieldFromBase64(str: string): Field;
|
9
|
-
export declare function bigintFromBase64(str: string): bigint;
|
10
|
-
export declare function fromBase(digits: bigint[], base: bigint): bigint;
|
11
|
-
export declare function toBase(x: bigint, base: bigint): bigint[];
|
@@ -1,120 +1,35 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.fieldFromBase64 = exports.fieldToBase64 = exports.fieldFromBase56 = exports.fieldToBase56 = void 0;
|
4
4
|
const o1js_1 = require("o1js");
|
5
|
+
const hash_1 = require("../../cloud/utils/hash");
|
5
6
|
// URL friendly base64 encoding
|
6
7
|
const TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
7
8
|
function fieldToBase56(field) {
|
8
|
-
const digits = toBase(field.toBigInt(), 56n);
|
9
|
+
const digits = (0, hash_1.toBase)(field.toBigInt(), 56n);
|
9
10
|
//console.log("digits:", digits);
|
10
11
|
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
11
12
|
//console.log("str:", str);
|
12
13
|
return str;
|
13
14
|
}
|
14
15
|
exports.fieldToBase56 = fieldToBase56;
|
15
|
-
function bigintToBase56(value) {
|
16
|
-
const digits = toBase(value, 56n);
|
17
|
-
//console.log("digits:", digits);
|
18
|
-
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
19
|
-
//console.log("str:", str);
|
20
|
-
return str;
|
21
|
-
}
|
22
|
-
exports.bigintToBase56 = bigintToBase56;
|
23
16
|
function fieldFromBase56(str) {
|
24
17
|
const base56Digits = str.split("").map((x) => BigInt(TABLE.indexOf(x)));
|
25
|
-
const x = fromBase(base56Digits, 56n);
|
18
|
+
const x = (0, hash_1.fromBase)(base56Digits, 56n);
|
26
19
|
return (0, o1js_1.Field)(x);
|
27
20
|
}
|
28
21
|
exports.fieldFromBase56 = fieldFromBase56;
|
29
|
-
function bigintFromBase56(str) {
|
30
|
-
const base56Digits = str.split("").map((x) => BigInt(TABLE.indexOf(x)));
|
31
|
-
const x = fromBase(base56Digits, 56n);
|
32
|
-
return x;
|
33
|
-
}
|
34
|
-
exports.bigintFromBase56 = bigintFromBase56;
|
35
22
|
function fieldToBase64(field) {
|
36
|
-
const digits = toBase(field.toBigInt(), 64n);
|
23
|
+
const digits = (0, hash_1.toBase)(field.toBigInt(), 64n);
|
37
24
|
//console.log("digits:", digits);
|
38
25
|
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
39
26
|
//console.log("str:", str);
|
40
27
|
return str;
|
41
28
|
}
|
42
29
|
exports.fieldToBase64 = fieldToBase64;
|
43
|
-
function bigintToBase64(value) {
|
44
|
-
const digits = toBase(value, 64n);
|
45
|
-
//console.log("digits:", digits);
|
46
|
-
const str = digits.map((x) => TABLE[Number(x)]).join("");
|
47
|
-
//console.log("str:", str);
|
48
|
-
return str;
|
49
|
-
}
|
50
|
-
exports.bigintToBase64 = bigintToBase64;
|
51
30
|
function fieldFromBase64(str) {
|
52
31
|
const base64Digits = str.split("").map((x) => BigInt(TABLE.indexOf(x)));
|
53
|
-
const x = fromBase(base64Digits, 64n);
|
32
|
+
const x = (0, hash_1.fromBase)(base64Digits, 64n);
|
54
33
|
return (0, o1js_1.Field)(x);
|
55
34
|
}
|
56
35
|
exports.fieldFromBase64 = fieldFromBase64;
|
57
|
-
function bigintFromBase64(str) {
|
58
|
-
const base64Digits = str.split("").map((x) => BigInt(TABLE.indexOf(x)));
|
59
|
-
const x = fromBase(base64Digits, 64n);
|
60
|
-
return x;
|
61
|
-
}
|
62
|
-
exports.bigintFromBase64 = bigintFromBase64;
|
63
|
-
function fromBase(digits, base) {
|
64
|
-
if (base <= 0n)
|
65
|
-
throw Error("fromBase: base must be positive");
|
66
|
-
// compute powers base, base^2, base^4, ..., base^(2^k)
|
67
|
-
// with largest k s.t. n = 2^k < digits.length
|
68
|
-
let basePowers = [];
|
69
|
-
for (let power = base, n = 1; n < digits.length; power **= 2n, n *= 2) {
|
70
|
-
basePowers.push(power);
|
71
|
-
}
|
72
|
-
let k = basePowers.length;
|
73
|
-
// pad digits array with zeros s.t. digits.length === 2^k
|
74
|
-
digits = digits.concat(Array(2 ** k - digits.length).fill(0n));
|
75
|
-
// accumulate [x0, x1, x2, x3, ...] -> [x0 + base*x1, x2 + base*x3, ...] -> [x0 + base*x1 + base^2*(x2 + base*x3), ...] -> ...
|
76
|
-
// until we end up with a single element
|
77
|
-
for (let i = 0; i < k; i++) {
|
78
|
-
let newDigits = Array(digits.length >> 1);
|
79
|
-
let basePower = basePowers[i];
|
80
|
-
for (let j = 0; j < newDigits.length; j++) {
|
81
|
-
newDigits[j] = digits[2 * j] + basePower * digits[2 * j + 1];
|
82
|
-
}
|
83
|
-
digits = newDigits;
|
84
|
-
}
|
85
|
-
console.assert(digits.length === 1);
|
86
|
-
let [digit] = digits;
|
87
|
-
return digit;
|
88
|
-
}
|
89
|
-
exports.fromBase = fromBase;
|
90
|
-
function toBase(x, base) {
|
91
|
-
if (base <= 0n)
|
92
|
-
throw Error("toBase: base must be positive");
|
93
|
-
// compute powers base, base^2, base^4, ..., base^(2^k)
|
94
|
-
// with largest k s.t. base^(2^k) < x
|
95
|
-
let basePowers = [];
|
96
|
-
for (let power = base; power <= x; power **= 2n) {
|
97
|
-
basePowers.push(power);
|
98
|
-
}
|
99
|
-
let digits = [x]; // single digit w.r.t base^(2^(k+1))
|
100
|
-
// successively split digits w.r.t. base^(2^j) into digits w.r.t. base^(2^(j-1))
|
101
|
-
// until we arrive at digits w.r.t. base
|
102
|
-
let k = basePowers.length;
|
103
|
-
for (let i = 0; i < k; i++) {
|
104
|
-
let newDigits = Array(2 * digits.length);
|
105
|
-
let basePower = basePowers[k - 1 - i];
|
106
|
-
for (let j = 0; j < digits.length; j++) {
|
107
|
-
let x = digits[j];
|
108
|
-
let high = x / basePower;
|
109
|
-
newDigits[2 * j + 1] = high;
|
110
|
-
newDigits[2 * j] = x - high * basePower;
|
111
|
-
}
|
112
|
-
digits = newDigits;
|
113
|
-
}
|
114
|
-
// pop "leading" zero digits
|
115
|
-
while (digits[digits.length - 1] === 0n) {
|
116
|
-
digits.pop();
|
117
|
-
}
|
118
|
-
return digits;
|
119
|
-
}
|
120
|
-
exports.toBase = toBase;
|