@ardrive/turbo-sdk 1.0.1 → 1.1.0-alpha.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/README.md +45 -3
- package/bundles/web.bundle.min.js +22368 -3347
- package/lib/cjs/common/factory.js +10 -0
- package/lib/cjs/common/http.js +13 -1
- package/lib/cjs/common/logger.js +60 -0
- package/lib/cjs/common/payment.js +6 -3
- package/lib/cjs/common/upload.js +10 -5
- package/lib/cjs/node/factory.js +6 -1
- package/lib/cjs/node/signer.js +4 -1
- package/lib/cjs/utils/axiosClient.js +8 -4
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/web/factory.js +6 -1
- package/lib/cjs/web/signer.js +4 -1
- package/lib/esm/common/factory.js +10 -0
- package/lib/esm/common/http.js +13 -1
- package/lib/esm/common/logger.js +56 -0
- package/lib/esm/common/payment.js +6 -3
- package/lib/esm/common/upload.js +9 -4
- package/lib/esm/node/factory.js +6 -1
- package/lib/esm/node/signer.js +4 -1
- package/lib/esm/utils/axiosClient.js +8 -4
- package/lib/esm/version.js +1 -1
- package/lib/esm/web/factory.js +6 -1
- package/lib/esm/web/signer.js +4 -1
- package/lib/types/common/factory.d.ts +4 -0
- package/lib/types/common/factory.d.ts.map +1 -1
- package/lib/types/common/http.d.ts +4 -2
- package/lib/types/common/http.d.ts.map +1 -1
- package/lib/types/common/logger.d.ts +32 -0
- package/lib/types/common/logger.d.ts.map +1 -0
- package/lib/types/common/payment.d.ts +4 -3
- package/lib/types/common/payment.d.ts.map +1 -1
- package/lib/types/common/upload.d.ts +5 -4
- package/lib/types/common/upload.d.ts.map +1 -1
- package/lib/types/node/factory.d.ts.map +1 -1
- package/lib/types/node/signer.d.ts +4 -2
- package/lib/types/node/signer.d.ts.map +1 -1
- package/lib/types/types.d.ts +9 -2
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/utils/axiosClient.d.ts +3 -1
- package/lib/types/utils/axiosClient.d.ts.map +1 -1
- package/lib/types/version.d.ts +1 -1
- package/lib/types/version.d.ts.map +1 -1
- package/lib/types/web/factory.d.ts.map +1 -1
- package/lib/types/web/signer.d.ts +4 -2
- package/lib/types/web/signer.d.ts.map +1 -1
- package/package.json +1 -1
@@ -1,16 +1,25 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.TurboBaseFactory = void 0;
|
4
|
+
const logger_js_1 = require("./logger.js");
|
4
5
|
const payment_js_1 = require("./payment.js");
|
5
6
|
const turbo_js_1 = require("./turbo.js");
|
6
7
|
const upload_js_1 = require("./upload.js");
|
7
8
|
class TurboBaseFactory {
|
9
|
+
static setLogLevel(level) {
|
10
|
+
this.logger.setLogLevel(level);
|
11
|
+
}
|
12
|
+
static setLogFormat(format) {
|
13
|
+
this.logger.setLogFormat(format);
|
14
|
+
}
|
8
15
|
static unauthenticated({ paymentServiceConfig = {}, uploadServiceConfig = {}, } = {}) {
|
9
16
|
const paymentService = new payment_js_1.TurboUnauthenticatedPaymentService({
|
10
17
|
...paymentServiceConfig,
|
18
|
+
logger: this.logger,
|
11
19
|
});
|
12
20
|
const uploadService = new upload_js_1.TurboUnauthenticatedUploadService({
|
13
21
|
...uploadServiceConfig,
|
22
|
+
logger: this.logger,
|
14
23
|
});
|
15
24
|
return new turbo_js_1.TurboUnauthenticatedClient({
|
16
25
|
uploadService,
|
@@ -19,3 +28,4 @@ class TurboBaseFactory {
|
|
19
28
|
}
|
20
29
|
}
|
21
30
|
exports.TurboBaseFactory = TurboBaseFactory;
|
31
|
+
TurboBaseFactory.logger = new logger_js_1.TurboWinstonLogger();
|
package/lib/cjs/common/http.js
CHANGED
@@ -4,12 +4,24 @@ exports.TurboHTTPService = void 0;
|
|
4
4
|
const axiosClient_js_1 = require("../utils/axiosClient.js");
|
5
5
|
const errors_js_1 = require("../utils/errors.js");
|
6
6
|
class TurboHTTPService {
|
7
|
-
constructor({ url, retryConfig, }) {
|
7
|
+
constructor({ url, retryConfig, logger, }) {
|
8
|
+
this.logger = logger;
|
8
9
|
this.axios = (0, axiosClient_js_1.createAxiosInstance)({
|
9
10
|
axiosConfig: {
|
10
11
|
baseURL: url,
|
12
|
+
onUploadProgress: (progressEvent) => {
|
13
|
+
this.logger.debug(`Uploading...`, {
|
14
|
+
percent: Math.floor((progressEvent.progress ?? 0) * 100),
|
15
|
+
loaded: `${progressEvent.loaded} bytes`,
|
16
|
+
total: `${progressEvent.total} bytes`,
|
17
|
+
});
|
18
|
+
if (progressEvent.progress === 1) {
|
19
|
+
this.logger.debug(`Upload complete!`);
|
20
|
+
}
|
21
|
+
},
|
11
22
|
},
|
12
23
|
retryConfig,
|
24
|
+
logger: this.logger,
|
13
25
|
});
|
14
26
|
}
|
15
27
|
async get({ endpoint, signal, allowedStatuses = [200, 202], headers, }) {
|
@@ -0,0 +1,60 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.TurboWinstonLogger = 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 winston_1 = require("winston");
|
21
|
+
const version_js_1 = require("../version.js");
|
22
|
+
class TurboWinstonLogger {
|
23
|
+
constructor({ level = 'info', logFormat = 'simple', } = {}) {
|
24
|
+
this.logger = (0, winston_1.createLogger)({
|
25
|
+
level,
|
26
|
+
defaultMeta: { client: 'turbo-sdk', version: version_js_1.version },
|
27
|
+
silent: level === 'none',
|
28
|
+
format: getLogFormat(logFormat),
|
29
|
+
transports: [new winston_1.transports.Console()],
|
30
|
+
});
|
31
|
+
}
|
32
|
+
info(message, ...args) {
|
33
|
+
this.logger.info(message, ...args);
|
34
|
+
}
|
35
|
+
warn(message, ...args) {
|
36
|
+
this.logger.warn(message, ...args);
|
37
|
+
}
|
38
|
+
error(message, ...args) {
|
39
|
+
this.logger.error(message, ...args);
|
40
|
+
}
|
41
|
+
debug(message, ...args) {
|
42
|
+
this.logger.debug(message, ...args);
|
43
|
+
}
|
44
|
+
setLogLevel(level) {
|
45
|
+
this.logger.level = level;
|
46
|
+
}
|
47
|
+
setLogFormat(logFormat) {
|
48
|
+
this.logger.format = getLogFormat(logFormat);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
exports.TurboWinstonLogger = TurboWinstonLogger;
|
52
|
+
function getLogFormat(logFormat) {
|
53
|
+
return winston_1.format.combine((0, winston_1.format)((info) => {
|
54
|
+
if (info.stack && info.level !== 'error') {
|
55
|
+
delete info.stack;
|
56
|
+
}
|
57
|
+
return info;
|
58
|
+
})(), winston_1.format.errors({ stack: true }), // Ensure errors show a stack trace
|
59
|
+
winston_1.format.timestamp(), logFormat === 'json' ? winston_1.format.json() : winston_1.format.simple());
|
60
|
+
}
|
@@ -2,13 +2,16 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.TurboAuthenticatedPaymentService = exports.TurboUnauthenticatedPaymentService = exports.defaultPaymentServiceURL = exports.developmentPaymentServiceURL = void 0;
|
4
4
|
const http_js_1 = require("./http.js");
|
5
|
+
const logger_js_1 = require("./logger.js");
|
5
6
|
exports.developmentPaymentServiceURL = 'https://payment.ardrive.dev';
|
6
7
|
exports.defaultPaymentServiceURL = 'https://payment.ardrive.io';
|
7
8
|
class TurboUnauthenticatedPaymentService {
|
8
|
-
constructor({ url = exports.defaultPaymentServiceURL, retryConfig, }) {
|
9
|
+
constructor({ url = exports.defaultPaymentServiceURL, retryConfig, logger = new logger_js_1.TurboWinstonLogger(), }) {
|
10
|
+
this.logger = logger;
|
9
11
|
this.httpService = new http_js_1.TurboHTTPService({
|
10
12
|
url: `${url}/v1`,
|
11
13
|
retryConfig,
|
14
|
+
logger: this.logger,
|
12
15
|
});
|
13
16
|
}
|
14
17
|
getFiatRates() {
|
@@ -70,8 +73,8 @@ class TurboUnauthenticatedPaymentService {
|
|
70
73
|
exports.TurboUnauthenticatedPaymentService = TurboUnauthenticatedPaymentService;
|
71
74
|
// NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
|
72
75
|
class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymentService {
|
73
|
-
constructor({ url = exports.defaultPaymentServiceURL, retryConfig, signer, }) {
|
74
|
-
super({ url, retryConfig });
|
76
|
+
constructor({ url = exports.defaultPaymentServiceURL, retryConfig, signer, logger, }) {
|
77
|
+
super({ url, retryConfig, logger });
|
75
78
|
this.signer = signer;
|
76
79
|
}
|
77
80
|
async getBalance() {
|
package/lib/cjs/common/upload.js
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.TurboAuthenticatedUploadService = exports.TurboUnauthenticatedUploadService = exports.
|
3
|
+
exports.TurboAuthenticatedUploadService = exports.TurboUnauthenticatedUploadService = exports.defaultUploadServiceURL = exports.developmentUploadServiceURL = void 0;
|
4
4
|
const http_js_1 = require("./http.js");
|
5
|
-
|
5
|
+
const logger_js_1 = require("./logger.js");
|
6
6
|
exports.developmentUploadServiceURL = 'https://upload.ardrive.dev';
|
7
|
+
exports.defaultUploadServiceURL = 'https://upload.ardrive.io';
|
7
8
|
class TurboUnauthenticatedUploadService {
|
8
|
-
constructor({ url = exports.defaultUploadServiceURL, retryConfig, }) {
|
9
|
+
constructor({ url = exports.defaultUploadServiceURL, retryConfig, logger = new logger_js_1.TurboWinstonLogger(), }) {
|
10
|
+
this.logger = logger;
|
9
11
|
this.httpService = new http_js_1.TurboHTTPService({
|
10
12
|
url: `${url}/v1`,
|
11
13
|
retryConfig,
|
14
|
+
logger: this.logger,
|
12
15
|
});
|
13
16
|
}
|
14
17
|
async uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, signal, }) {
|
15
18
|
const fileSize = dataItemSizeFactory();
|
19
|
+
this.logger.debug('Uploading signed data item...');
|
16
20
|
// TODO: add p-limit constraint or replace with separate upload class
|
17
21
|
return this.httpService.post({
|
18
22
|
endpoint: `/tx`,
|
@@ -28,8 +32,8 @@ class TurboUnauthenticatedUploadService {
|
|
28
32
|
exports.TurboUnauthenticatedUploadService = TurboUnauthenticatedUploadService;
|
29
33
|
// NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
|
30
34
|
class TurboAuthenticatedUploadService extends TurboUnauthenticatedUploadService {
|
31
|
-
constructor({ url =
|
32
|
-
super({ url, retryConfig });
|
35
|
+
constructor({ url = exports.defaultUploadServiceURL, retryConfig, signer, logger, }) {
|
36
|
+
super({ url, retryConfig, logger });
|
33
37
|
this.signer = signer;
|
34
38
|
}
|
35
39
|
async uploadFile({ fileStreamFactory, fileSizeFactory, signal, }) {
|
@@ -39,6 +43,7 @@ class TurboAuthenticatedUploadService extends TurboUnauthenticatedUploadService
|
|
39
43
|
});
|
40
44
|
const signedDataItem = dataItemStreamFactory();
|
41
45
|
const fileSize = dataItemSizeFactory();
|
46
|
+
this.logger.debug('Uploading signed data item...');
|
42
47
|
// TODO: add p-limit constraint or replace with separate upload class
|
43
48
|
return this.httpService.post({
|
44
49
|
endpoint: `/tx`,
|
package/lib/cjs/node/factory.js
CHANGED
@@ -22,14 +22,19 @@ const index_js_1 = require("../common/index.js");
|
|
22
22
|
const signer_js_1 = require("./signer.js");
|
23
23
|
class TurboFactory extends factory_js_1.TurboBaseFactory {
|
24
24
|
static authenticated({ privateKey, paymentServiceConfig = {}, uploadServiceConfig = {}, }) {
|
25
|
-
const signer = new signer_js_1.TurboNodeArweaveSigner({
|
25
|
+
const signer = new signer_js_1.TurboNodeArweaveSigner({
|
26
|
+
privateKey,
|
27
|
+
logger: this.logger,
|
28
|
+
});
|
26
29
|
const paymentService = new index_js_1.TurboAuthenticatedPaymentService({
|
27
30
|
...paymentServiceConfig,
|
28
31
|
signer,
|
32
|
+
logger: this.logger,
|
29
33
|
});
|
30
34
|
const uploadService = new index_js_1.TurboAuthenticatedUploadService({
|
31
35
|
...uploadServiceConfig,
|
32
36
|
signer,
|
37
|
+
logger: this.logger,
|
33
38
|
});
|
34
39
|
return new index_js_1.TurboAuthenticatedClient({
|
35
40
|
uploadService,
|
package/lib/cjs/node/signer.js
CHANGED
@@ -26,14 +26,17 @@ const node_crypto_1 = require("node:crypto");
|
|
26
26
|
const base64_js_1 = require("../utils/base64.js");
|
27
27
|
class TurboNodeArweaveSigner {
|
28
28
|
// TODO: replace with internal signer class
|
29
|
-
constructor({ privateKey }) {
|
29
|
+
constructor({ privateKey, logger, }) {
|
30
30
|
this.privateKey = privateKey;
|
31
|
+
this.logger = logger;
|
31
32
|
this.signer = new arbundles_1.ArweaveSigner(this.privateKey);
|
32
33
|
}
|
33
34
|
async signDataItem({ fileStreamFactory, fileSizeFactory, }) {
|
34
35
|
// TODO: replace with our own signer implementation
|
36
|
+
this.logger.debug('Signing data item...');
|
35
37
|
const [stream1, stream2] = [fileStreamFactory(), fileStreamFactory()];
|
36
38
|
const signedDataItem = await (0, arbundles_1.streamSigner)(stream1, stream2, this.signer);
|
39
|
+
this.logger.debug('Successfully signed data item...');
|
37
40
|
// TODO: support target, anchor, and tags
|
38
41
|
const signedDataItemSize = this.calculateSignedDataHeadersSize({
|
39
42
|
dataSize: fileSizeFactory(),
|
@@ -45,12 +45,13 @@ exports.createAxiosInstance = exports.defaultRequestHeaders = void 0;
|
|
45
45
|
*/
|
46
46
|
const axios_1 = __importStar(require("axios"));
|
47
47
|
const axios_retry_1 = __importDefault(require("axios-retry"));
|
48
|
+
const logger_js_1 = require("../common/logger.js");
|
48
49
|
const version_js_1 = require("../version.js");
|
49
50
|
exports.defaultRequestHeaders = {
|
50
51
|
'x-turbo-source-version': version_js_1.version,
|
51
52
|
'x-turbo-source-identifier': 'turbo-sdk',
|
52
53
|
};
|
53
|
-
const createAxiosInstance = ({ axiosConfig = {}, retryConfig = {
|
54
|
+
const createAxiosInstance = ({ logger = new logger_js_1.TurboWinstonLogger(), axiosConfig = {}, retryConfig = {
|
54
55
|
retryDelay: axios_retry_1.default.exponentialDelay,
|
55
56
|
retries: 3,
|
56
57
|
retryCondition: (error) => {
|
@@ -58,12 +59,15 @@ const createAxiosInstance = ({ axiosConfig = {}, retryConfig = {
|
|
58
59
|
axios_retry_1.default.isNetworkOrIdempotentRequestError(error));
|
59
60
|
},
|
60
61
|
onRetry: (retryCount, error) => {
|
61
|
-
|
62
|
+
logger.debug(`Request failed, ${error}. Retry attempt #${retryCount}...`);
|
62
63
|
},
|
63
|
-
}, }) => {
|
64
|
+
}, } = {}) => {
|
64
65
|
const axiosInstance = axios_1.default.create({
|
65
66
|
...axiosConfig,
|
66
|
-
headers:
|
67
|
+
headers: {
|
68
|
+
...axiosConfig.headers,
|
69
|
+
...exports.defaultRequestHeaders,
|
70
|
+
},
|
67
71
|
validateStatus: () => true, // don't throw on non-200 status codes
|
68
72
|
});
|
69
73
|
// eslint-disable-next-line
|
package/lib/cjs/version.js
CHANGED
package/lib/cjs/web/factory.js
CHANGED
@@ -22,14 +22,19 @@ const index_js_1 = require("../common/index.js");
|
|
22
22
|
const signer_js_1 = require("./signer.js");
|
23
23
|
class TurboFactory extends factory_js_1.TurboBaseFactory {
|
24
24
|
static authenticated({ privateKey, paymentServiceConfig = {}, uploadServiceConfig = {}, }) {
|
25
|
-
const signer = new signer_js_1.TurboWebArweaveSigner({
|
25
|
+
const signer = new signer_js_1.TurboWebArweaveSigner({
|
26
|
+
privateKey,
|
27
|
+
logger: this.logger,
|
28
|
+
});
|
26
29
|
const paymentService = new index_js_1.TurboAuthenticatedPaymentService({
|
27
30
|
...paymentServiceConfig,
|
28
31
|
signer,
|
32
|
+
logger: this.logger,
|
29
33
|
});
|
30
34
|
const uploadService = new index_js_1.TurboAuthenticatedUploadService({
|
31
35
|
...uploadServiceConfig,
|
32
36
|
signer,
|
37
|
+
logger: this.logger,
|
33
38
|
});
|
34
39
|
return new index_js_1.TurboAuthenticatedClient({
|
35
40
|
uploadService,
|
package/lib/cjs/web/signer.js
CHANGED
@@ -26,8 +26,9 @@ const node_crypto_1 = require("node:crypto");
|
|
26
26
|
const base64_js_1 = require("../utils/base64.js");
|
27
27
|
const readableStream_js_1 = require("../utils/readableStream.js");
|
28
28
|
class TurboWebArweaveSigner {
|
29
|
-
constructor({ privateKey }) {
|
29
|
+
constructor({ privateKey, logger, }) {
|
30
30
|
this.privateKey = privateKey;
|
31
|
+
this.logger = logger;
|
31
32
|
this.signer = new arbundles_1.ArweaveSigner(this.privateKey);
|
32
33
|
}
|
33
34
|
async signDataItem({ fileStreamFactory, fileSizeFactory, }) {
|
@@ -36,9 +37,11 @@ class TurboWebArweaveSigner {
|
|
36
37
|
stream: fileStreamFactory(),
|
37
38
|
size: fileSizeFactory(),
|
38
39
|
});
|
40
|
+
this.logger.debug('Signing data item...');
|
39
41
|
// TODO: support target, anchor and tags for upload
|
40
42
|
const signedDataItem = (0, arbundles_1.createData)(buffer, this.signer, {});
|
41
43
|
await signedDataItem.sign(this.signer);
|
44
|
+
this.logger.debug('Successfully signed data item...');
|
42
45
|
return {
|
43
46
|
// while this returns a Buffer - it needs to match our return type for uploading
|
44
47
|
dataItemStreamFactory: () => signedDataItem.getRaw(),
|
@@ -1,13 +1,22 @@
|
|
1
|
+
import { TurboWinstonLogger } from './logger.js';
|
1
2
|
import { TurboUnauthenticatedPaymentService } from './payment.js';
|
2
3
|
import { TurboUnauthenticatedClient } from './turbo.js';
|
3
4
|
import { TurboUnauthenticatedUploadService } from './upload.js';
|
4
5
|
export class TurboBaseFactory {
|
6
|
+
static setLogLevel(level) {
|
7
|
+
this.logger.setLogLevel(level);
|
8
|
+
}
|
9
|
+
static setLogFormat(format) {
|
10
|
+
this.logger.setLogFormat(format);
|
11
|
+
}
|
5
12
|
static unauthenticated({ paymentServiceConfig = {}, uploadServiceConfig = {}, } = {}) {
|
6
13
|
const paymentService = new TurboUnauthenticatedPaymentService({
|
7
14
|
...paymentServiceConfig,
|
15
|
+
logger: this.logger,
|
8
16
|
});
|
9
17
|
const uploadService = new TurboUnauthenticatedUploadService({
|
10
18
|
...uploadServiceConfig,
|
19
|
+
logger: this.logger,
|
11
20
|
});
|
12
21
|
return new TurboUnauthenticatedClient({
|
13
22
|
uploadService,
|
@@ -15,3 +24,4 @@ export class TurboBaseFactory {
|
|
15
24
|
});
|
16
25
|
}
|
17
26
|
}
|
27
|
+
TurboBaseFactory.logger = new TurboWinstonLogger();
|
package/lib/esm/common/http.js
CHANGED
@@ -1,12 +1,24 @@
|
|
1
1
|
import { createAxiosInstance } from '../utils/axiosClient.js';
|
2
2
|
import { FailedRequestError } from '../utils/errors.js';
|
3
3
|
export class TurboHTTPService {
|
4
|
-
constructor({ url, retryConfig, }) {
|
4
|
+
constructor({ url, retryConfig, logger, }) {
|
5
|
+
this.logger = logger;
|
5
6
|
this.axios = createAxiosInstance({
|
6
7
|
axiosConfig: {
|
7
8
|
baseURL: url,
|
9
|
+
onUploadProgress: (progressEvent) => {
|
10
|
+
this.logger.debug(`Uploading...`, {
|
11
|
+
percent: Math.floor((progressEvent.progress ?? 0) * 100),
|
12
|
+
loaded: `${progressEvent.loaded} bytes`,
|
13
|
+
total: `${progressEvent.total} bytes`,
|
14
|
+
});
|
15
|
+
if (progressEvent.progress === 1) {
|
16
|
+
this.logger.debug(`Upload complete!`);
|
17
|
+
}
|
18
|
+
},
|
8
19
|
},
|
9
20
|
retryConfig,
|
21
|
+
logger: this.logger,
|
10
22
|
});
|
11
23
|
}
|
12
24
|
async get({ endpoint, signal, allowedStatuses = [200, 202], headers, }) {
|
@@ -0,0 +1,56 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (C) 2022-2023 Permanent Data Solutions, Inc. All Rights Reserved.
|
3
|
+
*
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
5
|
+
* it under the terms of the GNU Affero General Public License as published by
|
6
|
+
* the Free Software Foundation, either version 3 of the License, or
|
7
|
+
* (at your option) any later version.
|
8
|
+
*
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
* GNU Affero General Public License for more details.
|
13
|
+
*
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
15
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
*/
|
17
|
+
import { createLogger, format, transports } from 'winston';
|
18
|
+
import { version } from '../version.js';
|
19
|
+
export class TurboWinstonLogger {
|
20
|
+
constructor({ level = 'info', logFormat = 'simple', } = {}) {
|
21
|
+
this.logger = createLogger({
|
22
|
+
level,
|
23
|
+
defaultMeta: { client: 'turbo-sdk', version },
|
24
|
+
silent: level === 'none',
|
25
|
+
format: getLogFormat(logFormat),
|
26
|
+
transports: [new transports.Console()],
|
27
|
+
});
|
28
|
+
}
|
29
|
+
info(message, ...args) {
|
30
|
+
this.logger.info(message, ...args);
|
31
|
+
}
|
32
|
+
warn(message, ...args) {
|
33
|
+
this.logger.warn(message, ...args);
|
34
|
+
}
|
35
|
+
error(message, ...args) {
|
36
|
+
this.logger.error(message, ...args);
|
37
|
+
}
|
38
|
+
debug(message, ...args) {
|
39
|
+
this.logger.debug(message, ...args);
|
40
|
+
}
|
41
|
+
setLogLevel(level) {
|
42
|
+
this.logger.level = level;
|
43
|
+
}
|
44
|
+
setLogFormat(logFormat) {
|
45
|
+
this.logger.format = getLogFormat(logFormat);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
function getLogFormat(logFormat) {
|
49
|
+
return format.combine(format((info) => {
|
50
|
+
if (info.stack && info.level !== 'error') {
|
51
|
+
delete info.stack;
|
52
|
+
}
|
53
|
+
return info;
|
54
|
+
})(), format.errors({ stack: true }), // Ensure errors show a stack trace
|
55
|
+
format.timestamp(), logFormat === 'json' ? format.json() : format.simple());
|
56
|
+
}
|
@@ -1,11 +1,14 @@
|
|
1
1
|
import { TurboHTTPService } from './http.js';
|
2
|
+
import { TurboWinstonLogger } from './logger.js';
|
2
3
|
export const developmentPaymentServiceURL = 'https://payment.ardrive.dev';
|
3
4
|
export const defaultPaymentServiceURL = 'https://payment.ardrive.io';
|
4
5
|
export class TurboUnauthenticatedPaymentService {
|
5
|
-
constructor({ url = defaultPaymentServiceURL, retryConfig, }) {
|
6
|
+
constructor({ url = defaultPaymentServiceURL, retryConfig, logger = new TurboWinstonLogger(), }) {
|
7
|
+
this.logger = logger;
|
6
8
|
this.httpService = new TurboHTTPService({
|
7
9
|
url: `${url}/v1`,
|
8
10
|
retryConfig,
|
11
|
+
logger: this.logger,
|
9
12
|
});
|
10
13
|
}
|
11
14
|
getFiatRates() {
|
@@ -66,8 +69,8 @@ export class TurboUnauthenticatedPaymentService {
|
|
66
69
|
}
|
67
70
|
// NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
|
68
71
|
export class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymentService {
|
69
|
-
constructor({ url = defaultPaymentServiceURL, retryConfig, signer, }) {
|
70
|
-
super({ url, retryConfig });
|
72
|
+
constructor({ url = defaultPaymentServiceURL, retryConfig, signer, logger, }) {
|
73
|
+
super({ url, retryConfig, logger });
|
71
74
|
this.signer = signer;
|
72
75
|
}
|
73
76
|
async getBalance() {
|
package/lib/esm/common/upload.js
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
import { TurboHTTPService } from './http.js';
|
2
|
-
|
2
|
+
import { TurboWinstonLogger } from './logger.js';
|
3
3
|
export const developmentUploadServiceURL = 'https://upload.ardrive.dev';
|
4
|
+
export const defaultUploadServiceURL = 'https://upload.ardrive.io';
|
4
5
|
export class TurboUnauthenticatedUploadService {
|
5
|
-
constructor({ url = defaultUploadServiceURL, retryConfig, }) {
|
6
|
+
constructor({ url = defaultUploadServiceURL, retryConfig, logger = new TurboWinstonLogger(), }) {
|
7
|
+
this.logger = logger;
|
6
8
|
this.httpService = new TurboHTTPService({
|
7
9
|
url: `${url}/v1`,
|
8
10
|
retryConfig,
|
11
|
+
logger: this.logger,
|
9
12
|
});
|
10
13
|
}
|
11
14
|
async uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, signal, }) {
|
12
15
|
const fileSize = dataItemSizeFactory();
|
16
|
+
this.logger.debug('Uploading signed data item...');
|
13
17
|
// TODO: add p-limit constraint or replace with separate upload class
|
14
18
|
return this.httpService.post({
|
15
19
|
endpoint: `/tx`,
|
@@ -24,8 +28,8 @@ export class TurboUnauthenticatedUploadService {
|
|
24
28
|
}
|
25
29
|
// NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
|
26
30
|
export class TurboAuthenticatedUploadService extends TurboUnauthenticatedUploadService {
|
27
|
-
constructor({ url =
|
28
|
-
super({ url, retryConfig });
|
31
|
+
constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, }) {
|
32
|
+
super({ url, retryConfig, logger });
|
29
33
|
this.signer = signer;
|
30
34
|
}
|
31
35
|
async uploadFile({ fileStreamFactory, fileSizeFactory, signal, }) {
|
@@ -35,6 +39,7 @@ export class TurboAuthenticatedUploadService extends TurboUnauthenticatedUploadS
|
|
35
39
|
});
|
36
40
|
const signedDataItem = dataItemStreamFactory();
|
37
41
|
const fileSize = dataItemSizeFactory();
|
42
|
+
this.logger.debug('Uploading signed data item...');
|
38
43
|
// TODO: add p-limit constraint or replace with separate upload class
|
39
44
|
return this.httpService.post({
|
40
45
|
endpoint: `/tx`,
|
package/lib/esm/node/factory.js
CHANGED
@@ -19,14 +19,19 @@ import { TurboAuthenticatedClient, TurboAuthenticatedPaymentService, TurboAuthen
|
|
19
19
|
import { TurboNodeArweaveSigner } from './signer.js';
|
20
20
|
export class TurboFactory extends TurboBaseFactory {
|
21
21
|
static authenticated({ privateKey, paymentServiceConfig = {}, uploadServiceConfig = {}, }) {
|
22
|
-
const signer = new TurboNodeArweaveSigner({
|
22
|
+
const signer = new TurboNodeArweaveSigner({
|
23
|
+
privateKey,
|
24
|
+
logger: this.logger,
|
25
|
+
});
|
23
26
|
const paymentService = new TurboAuthenticatedPaymentService({
|
24
27
|
...paymentServiceConfig,
|
25
28
|
signer,
|
29
|
+
logger: this.logger,
|
26
30
|
});
|
27
31
|
const uploadService = new TurboAuthenticatedUploadService({
|
28
32
|
...uploadServiceConfig,
|
29
33
|
signer,
|
34
|
+
logger: this.logger,
|
30
35
|
});
|
31
36
|
return new TurboAuthenticatedClient({
|
32
37
|
uploadService,
|
package/lib/esm/node/signer.js
CHANGED
@@ -20,14 +20,17 @@ import { randomBytes } from 'node:crypto';
|
|
20
20
|
import { toB64Url } from '../utils/base64.js';
|
21
21
|
export class TurboNodeArweaveSigner {
|
22
22
|
// TODO: replace with internal signer class
|
23
|
-
constructor({ privateKey }) {
|
23
|
+
constructor({ privateKey, logger, }) {
|
24
24
|
this.privateKey = privateKey;
|
25
|
+
this.logger = logger;
|
25
26
|
this.signer = new ArweaveSigner(this.privateKey);
|
26
27
|
}
|
27
28
|
async signDataItem({ fileStreamFactory, fileSizeFactory, }) {
|
28
29
|
// TODO: replace with our own signer implementation
|
30
|
+
this.logger.debug('Signing data item...');
|
29
31
|
const [stream1, stream2] = [fileStreamFactory(), fileStreamFactory()];
|
30
32
|
const signedDataItem = await streamSigner(stream1, stream2, this.signer);
|
33
|
+
this.logger.debug('Successfully signed data item...');
|
31
34
|
// TODO: support target, anchor, and tags
|
32
35
|
const signedDataItemSize = this.calculateSignedDataHeadersSize({
|
33
36
|
dataSize: fileSizeFactory(),
|
@@ -16,12 +16,13 @@
|
|
16
16
|
*/
|
17
17
|
import axios, { CanceledError } from 'axios';
|
18
18
|
import axiosRetry from 'axios-retry';
|
19
|
+
import { TurboWinstonLogger } from '../common/logger.js';
|
19
20
|
import { version } from '../version.js';
|
20
21
|
export const defaultRequestHeaders = {
|
21
22
|
'x-turbo-source-version': version,
|
22
23
|
'x-turbo-source-identifier': 'turbo-sdk',
|
23
24
|
};
|
24
|
-
export const createAxiosInstance = ({ axiosConfig = {}, retryConfig = {
|
25
|
+
export const createAxiosInstance = ({ logger = new TurboWinstonLogger(), axiosConfig = {}, retryConfig = {
|
25
26
|
retryDelay: axiosRetry.exponentialDelay,
|
26
27
|
retries: 3,
|
27
28
|
retryCondition: (error) => {
|
@@ -29,12 +30,15 @@ export const createAxiosInstance = ({ axiosConfig = {}, retryConfig = {
|
|
29
30
|
axiosRetry.isNetworkOrIdempotentRequestError(error));
|
30
31
|
},
|
31
32
|
onRetry: (retryCount, error) => {
|
32
|
-
|
33
|
+
logger.debug(`Request failed, ${error}. Retry attempt #${retryCount}...`);
|
33
34
|
},
|
34
|
-
}, }) => {
|
35
|
+
}, } = {}) => {
|
35
36
|
const axiosInstance = axios.create({
|
36
37
|
...axiosConfig,
|
37
|
-
headers:
|
38
|
+
headers: {
|
39
|
+
...axiosConfig.headers,
|
40
|
+
...defaultRequestHeaders,
|
41
|
+
},
|
38
42
|
validateStatus: () => true, // don't throw on non-200 status codes
|
39
43
|
});
|
40
44
|
// eslint-disable-next-line
|
package/lib/esm/version.js
CHANGED
package/lib/esm/web/factory.js
CHANGED
@@ -19,14 +19,19 @@ import { TurboAuthenticatedClient, TurboAuthenticatedPaymentService, TurboAuthen
|
|
19
19
|
import { TurboWebArweaveSigner } from './signer.js';
|
20
20
|
export class TurboFactory extends TurboBaseFactory {
|
21
21
|
static authenticated({ privateKey, paymentServiceConfig = {}, uploadServiceConfig = {}, }) {
|
22
|
-
const signer = new TurboWebArweaveSigner({
|
22
|
+
const signer = new TurboWebArweaveSigner({
|
23
|
+
privateKey,
|
24
|
+
logger: this.logger,
|
25
|
+
});
|
23
26
|
const paymentService = new TurboAuthenticatedPaymentService({
|
24
27
|
...paymentServiceConfig,
|
25
28
|
signer,
|
29
|
+
logger: this.logger,
|
26
30
|
});
|
27
31
|
const uploadService = new TurboAuthenticatedUploadService({
|
28
32
|
...uploadServiceConfig,
|
29
33
|
signer,
|
34
|
+
logger: this.logger,
|
30
35
|
});
|
31
36
|
return new TurboAuthenticatedClient({
|
32
37
|
uploadService,
|
package/lib/esm/web/signer.js
CHANGED
@@ -20,8 +20,9 @@ import { randomBytes } from 'node:crypto';
|
|
20
20
|
import { toB64Url } from '../utils/base64.js';
|
21
21
|
import { readableStreamToBuffer } from '../utils/readableStream.js';
|
22
22
|
export class TurboWebArweaveSigner {
|
23
|
-
constructor({ privateKey }) {
|
23
|
+
constructor({ privateKey, logger, }) {
|
24
24
|
this.privateKey = privateKey;
|
25
|
+
this.logger = logger;
|
25
26
|
this.signer = new ArweaveSigner(this.privateKey);
|
26
27
|
}
|
27
28
|
async signDataItem({ fileStreamFactory, fileSizeFactory, }) {
|
@@ -30,9 +31,11 @@ export class TurboWebArweaveSigner {
|
|
30
31
|
stream: fileStreamFactory(),
|
31
32
|
size: fileSizeFactory(),
|
32
33
|
});
|
34
|
+
this.logger.debug('Signing data item...');
|
33
35
|
// TODO: support target, anchor and tags for upload
|
34
36
|
const signedDataItem = createData(buffer, this.signer, {});
|
35
37
|
await signedDataItem.sign(this.signer);
|
38
|
+
this.logger.debug('Successfully signed data item...');
|
36
39
|
return {
|
37
40
|
// while this returns a Buffer - it needs to match our return type for uploading
|
38
41
|
dataItemStreamFactory: () => signedDataItem.getRaw(),
|
@@ -15,8 +15,12 @@
|
|
15
15
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
*/
|
17
17
|
import { TurboUnauthenticatedConfiguration } from '../types.js';
|
18
|
+
import { TurboWinstonLogger } from './logger.js';
|
18
19
|
import { TurboUnauthenticatedClient } from './turbo.js';
|
19
20
|
export declare class TurboBaseFactory {
|
21
|
+
protected static logger: TurboWinstonLogger;
|
22
|
+
static setLogLevel(level: string): void;
|
23
|
+
static setLogFormat(format: string): void;
|
20
24
|
static unauthenticated({ paymentServiceConfig, uploadServiceConfig, }?: TurboUnauthenticatedConfiguration): TurboUnauthenticatedClient;
|
21
25
|
}
|
22
26
|
//# sourceMappingURL=factory.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/common/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/common/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAGxD,qBAAa,gBAAgB;IAC3B,SAAS,CAAC,MAAM,CAAC,MAAM,qBAA4B;IAEnD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM;IAIhC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM;IAIlC,MAAM,CAAC,eAAe,CAAC,EACrB,oBAAyB,EACzB,mBAAwB,GACzB,GAAE,iCAAsC;CAc1C"}
|