@ardrive/turbo-sdk 1.0.0-alpha.2 → 1.0.0-alpha.21

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.
Files changed (86) hide show
  1. package/bundles/web.bundle.min.js +277 -38
  2. package/lib/cjs/common/factory.js +21 -0
  3. package/lib/cjs/common/http.js +36 -0
  4. package/lib/cjs/common/index.js +35 -0
  5. package/lib/cjs/common/jwk.js +2 -0
  6. package/lib/cjs/common/payment.js +63 -0
  7. package/lib/cjs/common/turbo.js +78 -0
  8. package/lib/cjs/common/upload.js +46 -0
  9. package/lib/cjs/node/factory.js +40 -0
  10. package/lib/cjs/node/index.js +36 -0
  11. package/lib/cjs/node/signer.js +50 -0
  12. package/lib/cjs/package.json +1 -0
  13. package/lib/cjs/types.js +2 -0
  14. package/lib/cjs/utils/axiosClient.js +69 -0
  15. package/lib/cjs/utils/base64.js +47 -0
  16. package/lib/cjs/utils/errors.js +33 -0
  17. package/lib/cjs/utils/readableStream.js +17 -0
  18. package/lib/cjs/web/factory.js +40 -0
  19. package/lib/cjs/web/index.js +36 -0
  20. package/lib/cjs/web/signer.js +57 -0
  21. package/lib/{common → esm/common}/factory.js +6 -2
  22. package/lib/esm/common/http.js +32 -0
  23. package/lib/esm/common/payment.js +58 -0
  24. package/lib/esm/common/turbo.js +73 -0
  25. package/lib/esm/common/upload.js +41 -0
  26. package/lib/{node → esm/node}/factory.js +8 -2
  27. package/lib/{web → esm/node}/index.js +1 -0
  28. package/lib/{node → esm/node}/signer.js +9 -20
  29. package/lib/{utils → esm/utils}/axiosClient.js +18 -9
  30. package/lib/esm/utils/readableStream.js +13 -0
  31. package/lib/{web → esm/web}/factory.js +8 -2
  32. package/lib/{node → esm/web}/index.js +1 -0
  33. package/lib/esm/web/signer.js +50 -0
  34. package/lib/{common → types/common}/factory.d.ts +2 -1
  35. package/lib/types/common/factory.d.ts.map +1 -0
  36. package/lib/{common → types/common}/http.d.ts +7 -6
  37. package/lib/types/common/http.d.ts.map +1 -0
  38. package/lib/{common → types/common}/index.d.ts +1 -0
  39. package/lib/types/common/index.d.ts.map +1 -0
  40. package/lib/types/{arweave.d.ts → common/jwk.d.ts} +1 -0
  41. package/lib/types/common/jwk.d.ts.map +1 -0
  42. package/lib/{common → types/common}/payment.d.ts +2 -2
  43. package/lib/types/common/payment.d.ts.map +1 -0
  44. package/lib/{common → types/common}/turbo.d.ts +6 -5
  45. package/lib/types/common/turbo.d.ts.map +1 -0
  46. package/lib/{common → types/common}/upload.d.ts +2 -2
  47. package/lib/types/common/upload.d.ts.map +1 -0
  48. package/lib/{node → types/node}/factory.d.ts +2 -1
  49. package/lib/types/node/factory.d.ts.map +1 -0
  50. package/lib/{web → types/node}/index.d.ts +2 -0
  51. package/lib/types/node/index.d.ts.map +1 -0
  52. package/lib/{node → types/node}/signer.d.ts +4 -3
  53. package/lib/types/node/signer.d.ts.map +1 -0
  54. package/lib/types/{turbo.d.ts → types.d.ts} +7 -6
  55. package/lib/types/types.d.ts.map +1 -0
  56. package/lib/{utils → types/utils}/axiosClient.d.ts +3 -2
  57. package/lib/types/utils/axiosClient.d.ts.map +1 -0
  58. package/lib/{utils → types/utils}/base64.d.ts +4 -3
  59. package/lib/types/utils/base64.d.ts.map +1 -0
  60. package/lib/{utils → types/utils}/errors.d.ts +1 -0
  61. package/lib/types/utils/errors.d.ts.map +1 -0
  62. package/lib/{utils → types/utils}/readableStream.d.ts +3 -2
  63. package/lib/types/utils/readableStream.d.ts.map +1 -0
  64. package/lib/{web → types/web}/factory.d.ts +2 -1
  65. package/lib/types/web/factory.d.ts.map +1 -0
  66. package/lib/{node → types/web}/index.d.ts +2 -0
  67. package/lib/types/web/index.d.ts.map +1 -0
  68. package/lib/{web → types/web}/signer.d.ts +6 -5
  69. package/lib/types/web/signer.d.ts.map +1 -0
  70. package/package.json +19 -16
  71. package/lib/LICENSE.md +0 -661
  72. package/lib/README.md +0 -114
  73. package/lib/common/http.js +0 -45
  74. package/lib/common/payment.js +0 -81
  75. package/lib/common/turbo.js +0 -100
  76. package/lib/common/upload.js +0 -54
  77. package/lib/package.json +0 -105
  78. package/lib/types/index.d.ts +0 -18
  79. package/lib/types/index.js +0 -18
  80. package/lib/utils/readableStream.js +0 -24
  81. package/lib/web/signer.js +0 -61
  82. /package/lib/{common → esm/common}/index.js +0 -0
  83. /package/lib/{types/arweave.js → esm/common/jwk.js} +0 -0
  84. /package/lib/{types/turbo.js → esm/types.js} +0 -0
  85. /package/lib/{utils → esm/utils}/base64.js +0 -0
  86. /package/lib/{utils → esm/utils}/errors.js +0 -0
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TurboAuthenticatedUploadService = exports.TurboUnauthenticatedUploadService = void 0;
4
+ const http_js_1 = require("./http.js");
5
+ class TurboUnauthenticatedUploadService {
6
+ constructor({ url = 'https://upload.ardrive.dev', retryConfig, }) {
7
+ this.httpService = new http_js_1.TurboHTTPService({
8
+ url: `${url}/v1`,
9
+ retryConfig,
10
+ });
11
+ }
12
+ async uploadSignedDataItem({ dataItemStreamFactory, signal, }) {
13
+ // TODO: add p-limit constraint or replace with separate upload class
14
+ return this.httpService.post({
15
+ endpoint: `/tx`,
16
+ signal,
17
+ data: dataItemStreamFactory(),
18
+ headers: {
19
+ 'content-type': 'application/octet-stream',
20
+ },
21
+ });
22
+ }
23
+ }
24
+ exports.TurboUnauthenticatedUploadService = TurboUnauthenticatedUploadService;
25
+ // NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
26
+ class TurboAuthenticatedUploadService extends TurboUnauthenticatedUploadService {
27
+ constructor({ url = 'https://upload.ardrive.dev', retryConfig, signer, }) {
28
+ super({ url, retryConfig });
29
+ this.signer = signer;
30
+ }
31
+ async uploadFile({ fileStreamFactory, signal, }) {
32
+ const signedDataItem = await this.signer.signDataItem({
33
+ fileStreamFactory,
34
+ });
35
+ // TODO: add p-limit constraint or replace with separate upload class
36
+ return this.httpService.post({
37
+ endpoint: `/tx`,
38
+ signal,
39
+ data: signedDataItem,
40
+ headers: {
41
+ 'content-type': 'application/octet-stream',
42
+ },
43
+ });
44
+ }
45
+ }
46
+ exports.TurboAuthenticatedUploadService = TurboAuthenticatedUploadService;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TurboFactory = void 0;
4
+ /**
5
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU Affero General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU Affero General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Affero General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+ const factory_js_1 = require("../common/factory.js");
21
+ const index_js_1 = require("../common/index.js");
22
+ const signer_js_1 = require("./signer.js");
23
+ class TurboFactory extends factory_js_1.TurboBaseFactory {
24
+ static authenticated({ privateKey, paymentServiceConfig = {}, uploadServiceConfig = {}, }) {
25
+ const signer = new signer_js_1.TurboNodeArweaveSigner({ privateKey });
26
+ const paymentService = new index_js_1.TurboAuthenticatedPaymentService({
27
+ ...paymentServiceConfig,
28
+ signer,
29
+ });
30
+ const uploadService = new index_js_1.TurboAuthenticatedUploadService({
31
+ ...uploadServiceConfig,
32
+ signer,
33
+ });
34
+ return new index_js_1.TurboAuthenticatedClient({
35
+ uploadService,
36
+ paymentService,
37
+ });
38
+ }
39
+ }
40
+ exports.TurboFactory = TurboFactory;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
19
+ *
20
+ * This program is free software: you can redistribute it and/or modify
21
+ * it under the terms of the GNU Affero General Public License as published by
22
+ * the Free Software Foundation, either version 3 of the License, or
23
+ * (at your option) any later version.
24
+ *
25
+ * This program is distributed in the hope that it will be useful,
26
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
+ * GNU Affero General Public License for more details.
29
+ *
30
+ * You should have received a copy of the GNU Affero General Public License
31
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
32
+ */
33
+ __exportStar(require("./factory.js"), exports);
34
+ __exportStar(require("./signer.js"), exports);
35
+ __exportStar(require("../types.js"), exports);
36
+ __exportStar(require("../common/index.js"), exports);
@@ -0,0 +1,50 @@
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.TurboNodeArweaveSigner = void 0;
7
+ /**
8
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
9
+ *
10
+ * This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU Affero General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU Affero General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Affero General Public License
21
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+ */
23
+ const arbundles_1 = require("arbundles");
24
+ const index_js_1 = __importDefault(require("arweave/node/index.js"));
25
+ const node_crypto_1 = require("node:crypto");
26
+ const base64_js_1 = require("../utils/base64.js");
27
+ class TurboNodeArweaveSigner {
28
+ // TODO: replace with internal signer class
29
+ constructor({ privateKey }) {
30
+ this.privateKey = privateKey;
31
+ this.signer = new arbundles_1.ArweaveSigner(this.privateKey);
32
+ }
33
+ signDataItem({ fileStreamFactory, }) {
34
+ // TODO: replace with our own signer implementation
35
+ const [stream1, stream2] = [fileStreamFactory(), fileStreamFactory()];
36
+ return (0, arbundles_1.streamSigner)(stream1, stream2, this.signer);
37
+ }
38
+ // NOTE: this might be better in a parent class or elsewhere - easy enough to leave in here now and does require specific environment version of crypto
39
+ async generateSignedRequestHeaders() {
40
+ const nonce = (0, node_crypto_1.randomBytes)(16).toString('hex');
41
+ const buffer = Buffer.from(nonce);
42
+ const signature = await index_js_1.default.crypto.sign(this.privateKey, buffer);
43
+ return {
44
+ 'x-public-key': this.privateKey.n,
45
+ 'x-nonce': nonce,
46
+ 'x-signature': (0, base64_js_1.toB64Url)(Buffer.from(signature)),
47
+ };
48
+ }
49
+ }
50
+ exports.TurboNodeArweaveSigner = TurboNodeArweaveSigner;
@@ -0,0 +1 @@
1
+ {"type": "commonjs"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.createAxiosInstance = void 0;
30
+ /**
31
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
32
+ *
33
+ * This program is free software: you can redistribute it and/or modify
34
+ * it under the terms of the GNU Affero General Public License as published by
35
+ * the Free Software Foundation, either version 3 of the License, or
36
+ * (at your option) any later version.
37
+ *
38
+ * This program is distributed in the hope that it will be useful,
39
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
+ * GNU Affero General Public License for more details.
42
+ *
43
+ * You should have received a copy of the GNU Affero General Public License
44
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
45
+ */
46
+ const axios_1 = __importStar(require("axios"));
47
+ const axios_retry_1 = __importDefault(require("axios-retry"));
48
+ const createAxiosInstance = ({ axiosConfig = {}, retryConfig = {
49
+ retryDelay: axios_retry_1.default.exponentialDelay,
50
+ retries: 3,
51
+ retryCondition: (error) => {
52
+ return (!(error instanceof axios_1.CanceledError) &&
53
+ axios_retry_1.default.isNetworkOrIdempotentRequestError(error));
54
+ },
55
+ onRetry: (retryCount, error) => {
56
+ console.debug(`Request failed, ${error}. Retry attempt #${retryCount}...`);
57
+ },
58
+ }, }) => {
59
+ const axiosInstance = axios_1.default.create({
60
+ ...axiosConfig,
61
+ validateStatus: () => true, // don't throw on non-200 status codes
62
+ });
63
+ // eslint-disable-next-line
64
+ if (retryConfig.retries && retryConfig.retries > 0) {
65
+ (0, axios_retry_1.default)(axiosInstance, retryConfig);
66
+ }
67
+ return axiosInstance;
68
+ };
69
+ exports.createAxiosInstance = createAxiosInstance;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sha256B64Url = exports.toB64Url = exports.fromB64Url = exports.ownerToAddress = exports.jwkToPublicArweaveAddress = exports.base64URLRegex = void 0;
4
+ /**
5
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU Affero General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU Affero General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Affero General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+ const utils_js_1 = require("arweave/node/lib/utils.js");
21
+ const crypto_1 = require("crypto");
22
+ exports.base64URLRegex = /^[a-zA-Z0-9_-]{43}$/;
23
+ function jwkToPublicArweaveAddress(jwk) {
24
+ return ownerToAddress(jwk.n);
25
+ }
26
+ exports.jwkToPublicArweaveAddress = jwkToPublicArweaveAddress;
27
+ function ownerToAddress(owner) {
28
+ return sha256B64Url(fromB64Url(owner));
29
+ }
30
+ exports.ownerToAddress = ownerToAddress;
31
+ function fromB64Url(input) {
32
+ const paddingLength = input.length % 4 === 0 ? 0 : 4 - (input.length % 4);
33
+ const base64 = input
34
+ .replace(/-/g, '+')
35
+ .replace(/_/g, '/')
36
+ .concat('='.repeat(paddingLength));
37
+ return Buffer.from(base64, 'base64');
38
+ }
39
+ exports.fromB64Url = fromB64Url;
40
+ function toB64Url(buffer) {
41
+ return (0, utils_js_1.bufferTob64Url)(buffer);
42
+ }
43
+ exports.toB64Url = toB64Url;
44
+ function sha256B64Url(input) {
45
+ return toB64Url((0, crypto_1.createHash)('sha256').update(input).digest());
46
+ }
47
+ exports.sha256B64Url = sha256B64Url;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FailedRequestError = exports.UnauthenticatedRequestError = void 0;
4
+ /**
5
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU Affero General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU Affero General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Affero General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+ class UnauthenticatedRequestError extends Error {
21
+ constructor() {
22
+ super('Failed authentication. JWK is required.');
23
+ this.name = 'UnauthenticatedRequestError';
24
+ }
25
+ }
26
+ exports.UnauthenticatedRequestError = UnauthenticatedRequestError;
27
+ class FailedRequestError extends Error {
28
+ constructor(status, message) {
29
+ super(`Failed request: ${status}: ${message}`);
30
+ this.name = 'FailedRequestError';
31
+ }
32
+ }
33
+ exports.FailedRequestError = FailedRequestError;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readableStreamToBuffer = void 0;
4
+ async function readableStreamToBuffer({ stream, }) {
5
+ const reader = stream.getReader();
6
+ const chunks = [];
7
+ let done = false;
8
+ while (!done) {
9
+ const { done: streamDone, value } = await reader.read();
10
+ done = streamDone;
11
+ if (!done) {
12
+ chunks.push(value);
13
+ }
14
+ }
15
+ return Buffer.concat(chunks);
16
+ }
17
+ exports.readableStreamToBuffer = readableStreamToBuffer;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TurboFactory = void 0;
4
+ /**
5
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU Affero General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU Affero General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Affero General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+ const factory_js_1 = require("../common/factory.js");
21
+ const index_js_1 = require("../common/index.js");
22
+ const signer_js_1 = require("./signer.js");
23
+ class TurboFactory extends factory_js_1.TurboBaseFactory {
24
+ static authenticated({ privateKey, paymentServiceConfig = {}, uploadServiceConfig = {}, }) {
25
+ const signer = new signer_js_1.TurboWebArweaveSigner({ privateKey });
26
+ const paymentService = new index_js_1.TurboAuthenticatedPaymentService({
27
+ ...paymentServiceConfig,
28
+ signer,
29
+ });
30
+ const uploadService = new index_js_1.TurboAuthenticatedUploadService({
31
+ ...uploadServiceConfig,
32
+ signer,
33
+ });
34
+ return new index_js_1.TurboAuthenticatedClient({
35
+ uploadService,
36
+ paymentService,
37
+ });
38
+ }
39
+ }
40
+ exports.TurboFactory = TurboFactory;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
19
+ *
20
+ * This program is free software: you can redistribute it and/or modify
21
+ * it under the terms of the GNU Affero General Public License as published by
22
+ * the Free Software Foundation, either version 3 of the License, or
23
+ * (at your option) any later version.
24
+ *
25
+ * This program is distributed in the hope that it will be useful,
26
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
+ * GNU Affero General Public License for more details.
29
+ *
30
+ * You should have received a copy of the GNU Affero General Public License
31
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
32
+ */
33
+ __exportStar(require("./factory.js"), exports);
34
+ __exportStar(require("./signer.js"), exports);
35
+ __exportStar(require("../common/index.js"), exports);
36
+ __exportStar(require("../types.js"), exports);
@@ -0,0 +1,57 @@
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.TurboWebArweaveSigner = void 0;
7
+ /**
8
+ * Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
9
+ *
10
+ * This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU Affero General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU Affero General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Affero General Public License
21
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+ */
23
+ const arbundles_1 = require("arbundles");
24
+ const arweave_1 = __importDefault(require("arweave"));
25
+ const node_crypto_1 = require("node:crypto");
26
+ const base64_js_1 = require("../utils/base64.js");
27
+ const readableStream_js_1 = require("../utils/readableStream.js");
28
+ class TurboWebArweaveSigner {
29
+ constructor({ privateKey }) {
30
+ this.privateKey = privateKey;
31
+ this.signer = new arbundles_1.ArweaveSigner(this.privateKey);
32
+ }
33
+ async signDataItem({ fileStreamFactory, }) {
34
+ // TODO: converts the readable stream to a buffer bc incrementally signing ReadableStreams is not trivial
35
+ const buffer = await (0, readableStream_js_1.readableStreamToBuffer)({
36
+ stream: fileStreamFactory(),
37
+ // TODO: add payload size to get performance improvements
38
+ });
39
+ const signedDataItem = (0, arbundles_1.createData)(buffer, this.signer);
40
+ await signedDataItem.sign(this.signer);
41
+ return signedDataItem.getRaw();
42
+ }
43
+ // NOTE: this might be better in a parent class or elsewhere - easy enough to leave in here now and does require specific environment version of crypto
44
+ async generateSignedRequestHeaders() {
45
+ // a bit hacky - but arweave exports cause issues in tests vs. browser
46
+ const arweave = arweave_1.default.default ?? arweave_1.default;
47
+ const nonce = (0, node_crypto_1.randomBytes)(16).toString('hex');
48
+ const buffer = Buffer.from(nonce);
49
+ const signature = await arweave.crypto.sign(this.privateKey, buffer, {});
50
+ return {
51
+ 'x-public-key': this.privateKey.n,
52
+ 'x-nonce': nonce,
53
+ 'x-signature': (0, base64_js_1.toB64Url)(Buffer.from(signature)),
54
+ };
55
+ }
56
+ }
57
+ exports.TurboWebArweaveSigner = TurboWebArweaveSigner;
@@ -3,8 +3,12 @@ import { TurboUnauthenticatedClient } from './turbo.js';
3
3
  import { TurboUnauthenticatedUploadService } from './upload.js';
4
4
  export class TurboBaseFactory {
5
5
  static unauthenticated({ paymentServiceConfig = {}, uploadServiceConfig = {}, } = {}) {
6
- const paymentService = new TurboUnauthenticatedPaymentService(Object.assign({}, paymentServiceConfig));
7
- const uploadService = new TurboUnauthenticatedUploadService(Object.assign({}, uploadServiceConfig));
6
+ const paymentService = new TurboUnauthenticatedPaymentService({
7
+ ...paymentServiceConfig,
8
+ });
9
+ const uploadService = new TurboUnauthenticatedUploadService({
10
+ ...uploadServiceConfig,
11
+ });
8
12
  return new TurboUnauthenticatedClient({
9
13
  uploadService,
10
14
  paymentService,
@@ -0,0 +1,32 @@
1
+ import { createAxiosInstance } from '../utils/axiosClient.js';
2
+ import { FailedRequestError } from '../utils/errors.js';
3
+ export class TurboHTTPService {
4
+ constructor({ url, retryConfig, }) {
5
+ this.axios = createAxiosInstance({
6
+ axiosConfig: {
7
+ baseURL: url,
8
+ },
9
+ retryConfig,
10
+ });
11
+ }
12
+ async get({ endpoint, signal, allowedStatuses = [200, 202], headers, }) {
13
+ const { status, statusText, data } = await this.axios.get(endpoint, {
14
+ headers,
15
+ signal,
16
+ });
17
+ if (!allowedStatuses.includes(status)) {
18
+ throw new FailedRequestError(status, statusText);
19
+ }
20
+ return data;
21
+ }
22
+ async post({ endpoint, signal, allowedStatuses = [200, 202], headers, data, }) {
23
+ const { status, statusText, data: response, } = await this.axios.post(endpoint, data, {
24
+ headers,
25
+ signal,
26
+ });
27
+ if (!allowedStatuses.includes(status)) {
28
+ throw new FailedRequestError(status, statusText);
29
+ }
30
+ return response;
31
+ }
32
+ }
@@ -0,0 +1,58 @@
1
+ import { TurboHTTPService } from './http.js';
2
+ export class TurboUnauthenticatedPaymentService {
3
+ constructor({ url = 'https://payment.ardrive.dev', retryConfig, }) {
4
+ this.httpService = new TurboHTTPService({
5
+ url: `${url}/v1`,
6
+ retryConfig,
7
+ });
8
+ }
9
+ async getFiatRates() {
10
+ return this.httpService.get({
11
+ endpoint: '/rates',
12
+ });
13
+ }
14
+ async getFiatToAR({ currency, }) {
15
+ return this.httpService.get({
16
+ endpoint: `/rates/${currency}`,
17
+ });
18
+ }
19
+ async getSupportedCountries() {
20
+ return this.httpService.get({
21
+ endpoint: '/countries',
22
+ });
23
+ }
24
+ async getSupportedCurrencies() {
25
+ return this.httpService.get({
26
+ endpoint: '/currencies',
27
+ });
28
+ }
29
+ async getUploadCosts({ bytes, }) {
30
+ const fetchPricePromises = bytes.map((byteCount) => this.httpService.get({
31
+ endpoint: `/price/bytes/${byteCount}`,
32
+ }));
33
+ const wincCostsForBytes = await Promise.all(fetchPricePromises);
34
+ return wincCostsForBytes;
35
+ }
36
+ async getWincForFiat({ amount, currency }) {
37
+ return this.httpService.get({
38
+ endpoint: `/price/${currency}/${amount}`,
39
+ });
40
+ }
41
+ }
42
+ // NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
43
+ export class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymentService {
44
+ constructor({ url = 'https://payment.ardrive.dev', retryConfig, signer, }) {
45
+ super({ url, retryConfig });
46
+ this.signer = signer;
47
+ }
48
+ async getBalance() {
49
+ const headers = await this.signer.generateSignedRequestHeaders();
50
+ const balance = await this.httpService.get({
51
+ endpoint: '/balance',
52
+ headers,
53
+ allowedStatuses: [200, 404],
54
+ });
55
+ // 404's don't return a balance, so default to 0
56
+ return balance.winc ? balance : { winc: '0' };
57
+ }
58
+ }
@@ -0,0 +1,73 @@
1
+ import { TurboUnauthenticatedPaymentService } from './payment.js';
2
+ import { TurboUnauthenticatedUploadService } from './upload.js';
3
+ export class TurboUnauthenticatedClient {
4
+ constructor({ uploadService = new TurboUnauthenticatedUploadService({}), paymentService = new TurboUnauthenticatedPaymentService({}), }) {
5
+ this.paymentService = paymentService;
6
+ this.uploadService = uploadService;
7
+ }
8
+ /**
9
+ * Returns the supported fiat currency conversion rate for 1AR based on current market prices.
10
+ */
11
+ async getFiatToAR({ currency, }) {
12
+ return this.paymentService.getFiatToAR({ currency });
13
+ }
14
+ /**
15
+ * Returns the latest conversion rates to purchase 1GiB of data for all supported currencies, including all adjustments and fees.
16
+ *
17
+ * Note: this does not take into account varying adjustments and promotions for different sizes of data. If you want to calculate the total
18
+ * cost in 'winc' for a given number of bytes, use getUploadCosts.
19
+ */
20
+ async getFiatRates() {
21
+ return this.paymentService.getFiatRates();
22
+ }
23
+ /**
24
+ * Returns a comprehensive list of supported countries that can purchase credits through the Turbo Payment Service.
25
+ */
26
+ async getSupportedCountries() {
27
+ return this.paymentService.getSupportedCountries();
28
+ }
29
+ /**
30
+ * Returns a list of all supported fiat currencies.
31
+ */
32
+ async getSupportedCurrencies() {
33
+ return this.paymentService.getSupportedCurrencies();
34
+ }
35
+ /**
36
+ * Determines the price in 'winc' to upload one data item of a specific size in bytes, including all Turbo cost adjustments and fees.
37
+ */
38
+ async getUploadCosts({ bytes, }) {
39
+ return this.paymentService.getUploadCosts({ bytes });
40
+ }
41
+ /**
42
+ * Determines the amount of 'winc' that would be returned for a given currency and amount, including all Turbo cost adjustments and fees.
43
+ */
44
+ async getWincForFiat({ amount, currency, }) {
45
+ return this.paymentService.getWincForFiat({ amount, currency });
46
+ }
47
+ /**
48
+ * Uploads a signed data item to the Turbo Upload Service.
49
+ */
50
+ async uploadSignedDataItem({ dataItemStreamFactory, signal, }) {
51
+ return this.uploadService.uploadSignedDataItem({
52
+ dataItemStreamFactory,
53
+ signal,
54
+ });
55
+ }
56
+ }
57
+ export class TurboAuthenticatedClient extends TurboUnauthenticatedClient {
58
+ constructor({ paymentService, uploadService, }) {
59
+ super({ paymentService, uploadService });
60
+ }
61
+ /**
62
+ * Returns the current balance of the user's wallet in 'winc'.
63
+ */
64
+ async getBalance() {
65
+ return this.paymentService.getBalance();
66
+ }
67
+ /**
68
+ * Signs and uploads raw data to the Turbo Upload Service.
69
+ */
70
+ async uploadFile({ fileStreamFactory, signal, }) {
71
+ return this.uploadService.uploadFile({ fileStreamFactory, signal });
72
+ }
73
+ }