@ardrive/turbo-sdk 1.42.0-alpha.1 → 1.42.0-alpha.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/cjs/cli/cli.js +46 -0
- package/lib/cjs/cli/commands/arns.js +249 -0
- package/lib/cjs/cli/commands/index.js +1 -0
- package/lib/cjs/cli/options.js +97 -1
- package/lib/cjs/common/http.js +4 -3
- package/lib/cjs/common/index.js +3 -0
- package/lib/cjs/common/payment.js +199 -0
- package/lib/cjs/common/signer.js +15 -3
- package/lib/cjs/common/turbo.js +44 -0
- package/lib/cjs/types.js +8 -1
- package/lib/cjs/utils/errors.js +19 -1
- package/lib/cjs/utils/uuid.js +31 -0
- package/lib/cjs/web/signer.js +4 -2
- package/lib/esm/cli/cli.js +47 -1
- package/lib/esm/cli/commands/arns.js +233 -0
- package/lib/esm/cli/commands/index.js +1 -0
- package/lib/esm/cli/options.js +96 -0
- package/lib/esm/common/http.js +4 -3
- package/lib/esm/common/index.js +3 -0
- package/lib/esm/common/payment.js +199 -0
- package/lib/esm/common/signer.js +15 -3
- package/lib/esm/common/turbo.js +44 -0
- package/lib/esm/types.js +7 -0
- package/lib/esm/utils/errors.js +17 -0
- package/lib/esm/utils/uuid.js +28 -0
- package/lib/esm/web/signer.js +4 -2
- package/lib/types/cli/commands/arns.d.ts +88 -0
- package/lib/types/cli/commands/arns.d.ts.map +1 -0
- package/lib/types/cli/commands/index.d.ts +1 -0
- package/lib/types/cli/commands/index.d.ts.map +1 -1
- package/lib/types/cli/options.d.ts +201 -0
- package/lib/types/cli/options.d.ts.map +1 -1
- package/lib/types/cli/types.d.ts +27 -0
- package/lib/types/cli/types.d.ts.map +1 -1
- package/lib/types/common/http.d.ts +2 -1
- package/lib/types/common/http.d.ts.map +1 -1
- package/lib/types/common/index.d.ts +1 -0
- package/lib/types/common/index.d.ts.map +1 -1
- package/lib/types/common/payment.d.ts +64 -1
- package/lib/types/common/payment.d.ts.map +1 -1
- package/lib/types/common/signer.d.ts +2 -6
- package/lib/types/common/signer.d.ts.map +1 -1
- package/lib/types/common/turbo.d.ts +53 -1
- package/lib/types/common/turbo.d.ts.map +1 -1
- package/lib/types/types.d.ts +136 -2
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/utils/errors.d.ts +14 -0
- package/lib/types/utils/errors.d.ts.map +1 -1
- package/lib/types/utils/uuid.d.ts +7 -0
- package/lib/types/utils/uuid.d.ts.map +1 -0
- package/lib/types/web/signer.d.ts +1 -1
- package/lib/types/web/signer.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -17,7 +17,10 @@ exports.TurboAuthenticatedPaymentService = exports.TurboUnauthenticatedPaymentSe
|
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
19
|
const bignumber_js_1 = require("bignumber.js");
|
|
20
|
+
const types_js_1 = require("../types.js");
|
|
20
21
|
const common_js_1 = require("../utils/common.js");
|
|
22
|
+
const errors_js_1 = require("../utils/errors.js");
|
|
23
|
+
const uuid_js_1 = require("../utils/uuid.js");
|
|
21
24
|
const http_js_1 = require("./http.js");
|
|
22
25
|
const http_js_2 = require("./http.js");
|
|
23
26
|
const logger_js_1 = require("./logger.js");
|
|
@@ -94,6 +97,90 @@ class TurboUnauthenticatedPaymentService {
|
|
|
94
97
|
equivalentWincTokenAmount: actualPaymentAmount.toString(),
|
|
95
98
|
};
|
|
96
99
|
}
|
|
100
|
+
async getArNSPriceForName(params) {
|
|
101
|
+
// `async` so a validation failure surfaces as a rejected promise (consistent
|
|
102
|
+
// with `purchaseArNSName`) rather than a synchronous throw.
|
|
103
|
+
this.validateArNSPurchaseParams(params);
|
|
104
|
+
return this.httpService.get({
|
|
105
|
+
endpoint: `/arns/price/${params.intent.toLowerCase()}/${params.name}${this.buildArNSPurchaseQuery(params)}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Fail fast (client-side) on malformed ArNS requests so JS callers that bypass
|
|
110
|
+
* the compile-time intent unions get a clear `ProvidedInputError` instead of an
|
|
111
|
+
* opaque service 4xx. Enforces the required fields per intent:
|
|
112
|
+
* - `Buy-Name`: `type` ('lease' | 'permabuy'); leases also need `years`.
|
|
113
|
+
* `processId` is OPTIONAL — omit it to have the bundler custodially
|
|
114
|
+
* provision the ANT (Turbo owns it), supply it for a user-owned ANT.
|
|
115
|
+
* - `Extend-Lease`: positive `years`
|
|
116
|
+
* - `Increase-Undername-Limit`: positive `increaseQty`
|
|
117
|
+
* - `Upgrade-Name`: just `name`
|
|
118
|
+
*/
|
|
119
|
+
validateArNSPurchaseParams(params) {
|
|
120
|
+
const p = params;
|
|
121
|
+
if (!types_js_1.arNSPurchaseIntents.includes(p.intent)) {
|
|
122
|
+
throw new errors_js_1.ProvidedInputError(`Invalid ArNS intent '${p.intent}'. Expected one of: ${types_js_1.arNSPurchaseIntents.join(', ')}.`);
|
|
123
|
+
}
|
|
124
|
+
if (typeof p.name !== 'string' || p.name.length === 0) {
|
|
125
|
+
throw new errors_js_1.ProvidedInputError('An ArNS `name` is required.');
|
|
126
|
+
}
|
|
127
|
+
const isPositiveNumber = (v) => typeof v === 'number' && Number.isFinite(v) && v > 0;
|
|
128
|
+
switch (p.intent) {
|
|
129
|
+
case 'Buy-Name':
|
|
130
|
+
if (p.type !== 'lease' && p.type !== 'permabuy') {
|
|
131
|
+
throw new errors_js_1.ProvidedInputError("Buy-Name requires a `type` of 'lease' or 'permabuy'.");
|
|
132
|
+
}
|
|
133
|
+
// `processId` is optional for Buy-Name: omitting it drives the
|
|
134
|
+
// bundler's custodial provisioning path (Turbo spawns + owns the ANT).
|
|
135
|
+
// If supplied it must be a non-empty string (user-owned ANT).
|
|
136
|
+
if (p.processId !== undefined &&
|
|
137
|
+
(typeof p.processId !== 'string' || p.processId.length === 0)) {
|
|
138
|
+
throw new errors_js_1.ProvidedInputError('Buy-Name `processId`, when provided, must be a non-empty string (the ANT the name resolves to).');
|
|
139
|
+
}
|
|
140
|
+
if (p.type === 'lease' && !isPositiveNumber(p.years)) {
|
|
141
|
+
throw new errors_js_1.ProvidedInputError('A lease `Buy-Name` requires a positive `years`.');
|
|
142
|
+
}
|
|
143
|
+
break;
|
|
144
|
+
case 'Extend-Lease':
|
|
145
|
+
if (!isPositiveNumber(p.years)) {
|
|
146
|
+
throw new errors_js_1.ProvidedInputError('Extend-Lease requires a positive `years`.');
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
case 'Increase-Undername-Limit':
|
|
150
|
+
if (!isPositiveNumber(p.increaseQty)) {
|
|
151
|
+
throw new errors_js_1.ProvidedInputError('Increase-Undername-Limit requires a positive `increaseQty`.');
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
case 'Upgrade-Name':
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
getArNSPurchaseStatus({ nonce, }) {
|
|
159
|
+
return this.httpService.get({
|
|
160
|
+
endpoint: `/arns/purchase/${nonce}`,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
buildArNSPurchaseQuery(input) {
|
|
164
|
+
// The intent-specific union members each carry only their own fields; read
|
|
165
|
+
// them through a single widened view rather than narrowing per intent.
|
|
166
|
+
const { type, years, increaseQty, processId, paidBy } = input;
|
|
167
|
+
const params = new URLSearchParams();
|
|
168
|
+
if (type !== undefined)
|
|
169
|
+
params.set('type', type);
|
|
170
|
+
if (years !== undefined)
|
|
171
|
+
params.set('years', `${years}`);
|
|
172
|
+
if (increaseQty !== undefined)
|
|
173
|
+
params.set('increaseQty', `${increaseQty}`);
|
|
174
|
+
if (processId !== undefined)
|
|
175
|
+
params.set('processId', processId);
|
|
176
|
+
if (paidBy !== undefined) {
|
|
177
|
+
for (const payer of Array.isArray(paidBy) ? paidBy : [paidBy]) {
|
|
178
|
+
params.append('paidBy', payer);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const query = params.toString();
|
|
182
|
+
return query.length > 0 ? `?${query}` : '';
|
|
183
|
+
}
|
|
97
184
|
appendPromoCodesToQuery(promoCodes) {
|
|
98
185
|
const promoCodesQuery = promoCodes.join(',');
|
|
99
186
|
return promoCodesQuery ? `promoCode=${promoCodesQuery}` : '';
|
|
@@ -259,6 +346,118 @@ class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymentServic
|
|
|
259
346
|
userAddress ??= await this.signer.getNativeAddress();
|
|
260
347
|
return super.getBalance(userAddress);
|
|
261
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Buy / extend / upgrade an ArNS name, paying with the signer's Turbo credit
|
|
351
|
+
* balance. The bundler performs the on-chain ARIO purchase and debits credits;
|
|
352
|
+
* a `402` (FailedRequestError.status === 402) indicates insufficient credits.
|
|
353
|
+
*/
|
|
354
|
+
async purchaseArNSName(params) {
|
|
355
|
+
this.validateArNSPurchaseParams(params);
|
|
356
|
+
// The bundler requires the signed nonce to be a UUID; it also doubles as
|
|
357
|
+
// the idempotency + status-lookup key (`getArNSPurchaseStatus`).
|
|
358
|
+
const nonce = (0, uuid_js_1.uuidV4)();
|
|
359
|
+
const headers = await this.signer.generateSignedRequestHeaders(nonce);
|
|
360
|
+
let response;
|
|
361
|
+
try {
|
|
362
|
+
response = await this.httpService.post({
|
|
363
|
+
endpoint: `/arns/purchase/${params.intent.toLowerCase()}/${params.name}${this.buildArNSPurchaseQuery(params)}`,
|
|
364
|
+
headers,
|
|
365
|
+
// Params travel in the query string + signed headers; the service reads
|
|
366
|
+
// no body, but the HTTP layer requires a `data` field.
|
|
367
|
+
data: Buffer.from([]),
|
|
368
|
+
// Non-idempotent signed write: the nonce is single-use, so a retried
|
|
369
|
+
// (but already-landed) purchase would 4xx as "already exists". Poll
|
|
370
|
+
// status by nonce instead of retrying.
|
|
371
|
+
retry: false,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
// Surface a credit shortfall as a typed, catchable error so callers can
|
|
376
|
+
// prompt a top-up. The `nonce` is the idempotency key: after topping up,
|
|
377
|
+
// retry the same purchase (a fresh nonce is fine — the service dedupes by
|
|
378
|
+
// the on-chain effect, and a captured nonce lets you poll status).
|
|
379
|
+
if (error instanceof errors_js_1.FailedRequestError && error.status === 402) {
|
|
380
|
+
throw new errors_js_1.InsufficientCreditsError(error.message);
|
|
381
|
+
}
|
|
382
|
+
throw error;
|
|
383
|
+
}
|
|
384
|
+
// Normalize both nonce fields to the one we signed so callers can poll with
|
|
385
|
+
// either `response.nonce` or `response.purchaseReceipt.nonce`.
|
|
386
|
+
return {
|
|
387
|
+
...response,
|
|
388
|
+
nonce,
|
|
389
|
+
purchaseReceipt: { ...response.purchaseReceipt, nonce },
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
buyArNSName(params) {
|
|
393
|
+
return this.purchaseArNSName({
|
|
394
|
+
...params,
|
|
395
|
+
intent: 'Buy-Name',
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
extendArNSLease(params) {
|
|
399
|
+
return this.purchaseArNSName({ ...params, intent: 'Extend-Lease' });
|
|
400
|
+
}
|
|
401
|
+
increaseArNSUndernameLimit(params) {
|
|
402
|
+
return this.purchaseArNSName({
|
|
403
|
+
...params,
|
|
404
|
+
intent: 'Increase-Undername-Limit',
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
upgradeArNSName(params) {
|
|
408
|
+
return this.purchaseArNSName({ ...params, intent: 'Upgrade-Name' });
|
|
409
|
+
}
|
|
410
|
+
// ---- ArNS ANT custody: self-custody exit + manage records ----
|
|
411
|
+
// Canonical ACTION-BOUND message. MUST match the bundler's
|
|
412
|
+
// buildArNSCustodyMessage byte-for-byte (newline-delimited) or every signature
|
|
413
|
+
// is rejected. The bundler reconstructs this from the request and verifies the
|
|
414
|
+
// signature over `message + nonce`, so a captured signature can't be replayed
|
|
415
|
+
// against a different operation/params.
|
|
416
|
+
buildArNSCustodyMessage(action, fields) {
|
|
417
|
+
return ['arns', action, ...fields].join('\n');
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Self-custody exit: move a Turbo-custodied ANT to a Solana pubkey you control.
|
|
421
|
+
* Authenticated with an action-bound, single-use signature.
|
|
422
|
+
*/
|
|
423
|
+
async transferArNSAnt({ antId, target, }) {
|
|
424
|
+
const nonce = (0, uuid_js_1.uuidV4)();
|
|
425
|
+
const headers = await this.signer.generateSignedRequestHeaders(nonce, this.buildArNSCustodyMessage('transfer', [antId, target]));
|
|
426
|
+
return this.httpService.post({
|
|
427
|
+
endpoint: `/arns/transfer/${antId}?target=${encodeURIComponent(target)}`,
|
|
428
|
+
headers,
|
|
429
|
+
data: Buffer.from([]),
|
|
430
|
+
retry: false, // single-use action-bound nonce; don't re-POST on 5xx
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
/** Set a resolution record on a custodied ANT (undername defaults to '@'). */
|
|
434
|
+
async setArNSRecord({ antId, undername = '@', transactionId, ttlSeconds, }) {
|
|
435
|
+
const nonce = (0, uuid_js_1.uuidV4)();
|
|
436
|
+
const headers = await this.signer.generateSignedRequestHeaders(nonce, this.buildArNSCustodyMessage('set-record', [
|
|
437
|
+
antId,
|
|
438
|
+
undername,
|
|
439
|
+
transactionId,
|
|
440
|
+
String(ttlSeconds),
|
|
441
|
+
]));
|
|
442
|
+
const query = `?undername=${encodeURIComponent(undername)}&transactionId=${transactionId}&ttlSeconds=${ttlSeconds}`;
|
|
443
|
+
return this.httpService.post({
|
|
444
|
+
endpoint: `/arns/manage/${antId}/set-record${query}`,
|
|
445
|
+
headers,
|
|
446
|
+
data: Buffer.from([]),
|
|
447
|
+
retry: false, // single-use action-bound nonce; don't re-POST on 5xx
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
/** Remove a resolution record (an undername) from a custodied ANT. */
|
|
451
|
+
async removeArNSRecord({ antId, undername, }) {
|
|
452
|
+
const nonce = (0, uuid_js_1.uuidV4)();
|
|
453
|
+
const headers = await this.signer.generateSignedRequestHeaders(nonce, this.buildArNSCustodyMessage('remove-record', [antId, undername]));
|
|
454
|
+
return this.httpService.post({
|
|
455
|
+
endpoint: `/arns/manage/${antId}/remove-record?undername=${encodeURIComponent(undername)}`,
|
|
456
|
+
headers,
|
|
457
|
+
data: Buffer.from([]),
|
|
458
|
+
retry: false, // single-use action-bound nonce; don't re-POST on 5xx
|
|
459
|
+
});
|
|
460
|
+
}
|
|
262
461
|
async getCreditShareApprovals({ userAddress, }) {
|
|
263
462
|
userAddress ??= await this.signer.getNativeAddress();
|
|
264
463
|
return super.getCreditShareApprovals({ userAddress });
|
package/lib/cjs/common/signer.js
CHANGED
|
@@ -73,15 +73,27 @@ class TurboDataItemAbstractSigner {
|
|
|
73
73
|
return (0, base64_js_1.ownerToAddress)(owner);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
async generateSignedRequestHeaders(
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
async generateSignedRequestHeaders(
|
|
77
|
+
// Callers may supply the nonce (e.g. a UUID required by some routes); the
|
|
78
|
+
// nonce round-trips to the service in `x-nonce` unchanged.
|
|
79
|
+
nonce = (0, crypto_2.randomBytes)(16).toString('hex'),
|
|
80
|
+
// Optional ACTION-BINDING data prepended to the nonce for SIGNING only (not
|
|
81
|
+
// sent): the service reconstructs the same string from the request and
|
|
82
|
+
// verifies the signature over `additionalData + nonce`. This binds the
|
|
83
|
+
// signature to a specific operation + params so it can't be replayed against
|
|
84
|
+
// a different request. Omitted → signs the bare nonce (unchanged behavior).
|
|
85
|
+
additionalData) {
|
|
86
|
+
const buffer = Buffer.from((additionalData ?? '') + nonce);
|
|
79
87
|
const signature = await this.signer.sign(Uint8Array.from(buffer));
|
|
80
88
|
const publicKey = (0, base64_js_1.toB64Url)(this.signer.publicKey);
|
|
81
89
|
return {
|
|
82
90
|
'x-public-key': publicKey,
|
|
83
91
|
'x-nonce': nonce,
|
|
84
92
|
'x-signature': (0, base64_js_1.toB64Url)(Buffer.from(signature)),
|
|
93
|
+
// Advertise the signature scheme so the service verifies with the right
|
|
94
|
+
// algorithm. Absent this, the server defaults to Arweave and every
|
|
95
|
+
// non-Arweave signed request (Ethereum, Solana, …) fails verification.
|
|
96
|
+
'x-signature-type': this.signer.signatureType.toString(),
|
|
85
97
|
};
|
|
86
98
|
}
|
|
87
99
|
async getPublicKey() {
|
package/lib/cjs/common/turbo.js
CHANGED
|
@@ -54,6 +54,18 @@ class TurboUnauthenticatedClient {
|
|
|
54
54
|
getBalance(address) {
|
|
55
55
|
return this.paymentService.getBalance(address);
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the price in 'winc' (and mARIO) to buy/extend/upgrade an ArNS name.
|
|
59
|
+
*/
|
|
60
|
+
getArNSPriceForName(params) {
|
|
61
|
+
return this.paymentService.getArNSPriceForName(params);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns the status of an ArNS purchase by its nonce.
|
|
65
|
+
*/
|
|
66
|
+
getArNSPurchaseStatus(p) {
|
|
67
|
+
return this.paymentService.getArNSPurchaseStatus(p);
|
|
68
|
+
}
|
|
57
69
|
/**
|
|
58
70
|
* Returns a list of all supported fiat currencies.
|
|
59
71
|
*/
|
|
@@ -159,6 +171,38 @@ class TurboAuthenticatedClient extends TurboUnauthenticatedClient {
|
|
|
159
171
|
getBalance(userAddress) {
|
|
160
172
|
return this.paymentService.getBalance(userAddress);
|
|
161
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Buys, extends, or upgrades an ArNS name, paying with the signer's Turbo
|
|
176
|
+
* credit balance. Poll {@link getArNSPurchaseStatus} with the returned nonce.
|
|
177
|
+
*/
|
|
178
|
+
purchaseArNSName(params) {
|
|
179
|
+
return this.paymentService.purchaseArNSName(params);
|
|
180
|
+
}
|
|
181
|
+
/** Buys a new ArNS name (lease or permabuy). */
|
|
182
|
+
buyArNSName(params) {
|
|
183
|
+
return this.paymentService.buyArNSName(params);
|
|
184
|
+
}
|
|
185
|
+
/** Extends the lease on an existing ArNS name. */
|
|
186
|
+
extendArNSLease(params) {
|
|
187
|
+
return this.paymentService.extendArNSLease(params);
|
|
188
|
+
}
|
|
189
|
+
/** Increases the undername limit on an existing ArNS name. */
|
|
190
|
+
increaseArNSUndernameLimit(params) {
|
|
191
|
+
return this.paymentService.increaseArNSUndernameLimit(params);
|
|
192
|
+
}
|
|
193
|
+
/** Upgrades an ArNS lease to a permabuy. */
|
|
194
|
+
upgradeArNSName(params) {
|
|
195
|
+
return this.paymentService.upgradeArNSName(params);
|
|
196
|
+
}
|
|
197
|
+
transferArNSAnt(params) {
|
|
198
|
+
return this.paymentService.transferArNSAnt(params);
|
|
199
|
+
}
|
|
200
|
+
setArNSRecord(params) {
|
|
201
|
+
return this.paymentService.setArNSRecord(params);
|
|
202
|
+
}
|
|
203
|
+
removeArNSRecord(params) {
|
|
204
|
+
return this.paymentService.removeArNSRecord(params);
|
|
205
|
+
}
|
|
162
206
|
/**
|
|
163
207
|
* Returns a list of all credit share approvals for the user.
|
|
164
208
|
*/
|
package/lib/cjs/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validChunkingModes = exports.isJWK = exports.isWebUploadFolderParams = exports.isNodeUploadFolderParams = exports.multipartFinalizedStatus = exports.multipartFailedStatus = exports.multipartPendingStatus = exports.X402Funding = exports.OnDemandFunding = exports.ExistingBalanceFunding = exports.supportedEvmSignerTokens = exports.tokenTypes = exports.fiatCurrencyTypes = void 0;
|
|
3
|
+
exports.arNSPurchaseIntents = exports.validChunkingModes = exports.isJWK = exports.isWebUploadFolderParams = exports.isNodeUploadFolderParams = exports.multipartFinalizedStatus = exports.multipartFailedStatus = exports.multipartPendingStatus = exports.X402Funding = exports.OnDemandFunding = exports.ExistingBalanceFunding = exports.supportedEvmSignerTokens = exports.tokenTypes = exports.fiatCurrencyTypes = void 0;
|
|
4
4
|
exports.isCurrency = isCurrency;
|
|
5
5
|
exports.isKyvePrivateKey = isKyvePrivateKey;
|
|
6
6
|
exports.isEthPrivateKey = isEthPrivateKey;
|
|
@@ -108,3 +108,10 @@ function isEthereumWalletAdapter(walletAdapter) {
|
|
|
108
108
|
return 'getSigner' in walletAdapter;
|
|
109
109
|
}
|
|
110
110
|
exports.validChunkingModes = ['force', 'disabled', 'auto'];
|
|
111
|
+
// ===== ArNS purchases paid with Turbo credits (via the bundler REST API) =====
|
|
112
|
+
exports.arNSPurchaseIntents = [
|
|
113
|
+
'Buy-Name',
|
|
114
|
+
'Extend-Lease',
|
|
115
|
+
'Increase-Undername-Limit',
|
|
116
|
+
'Upgrade-Name',
|
|
117
|
+
];
|
package/lib/cjs/utils/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AbortError = exports.ProvidedInputError = exports.FailedRequestError = exports.UnauthenticatedRequestError = exports.BaseError = void 0;
|
|
3
|
+
exports.AbortError = exports.InsufficientCreditsError = exports.ProvidedInputError = exports.FailedRequestError = exports.UnauthenticatedRequestError = exports.BaseError = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
6
6
|
*
|
|
@@ -42,6 +42,24 @@ class ProvidedInputError extends BaseError {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
exports.ProvidedInputError = ProvidedInputError;
|
|
45
|
+
/**
|
|
46
|
+
* Raised when a credit-paid operation (e.g. an ArNS purchase) is rejected by the
|
|
47
|
+
* service because the paying wallet does not hold enough Turbo credits. Maps the
|
|
48
|
+
* bundler's HTTP `402 Payment Required` response to a typed, catchable error so
|
|
49
|
+
* callers can prompt a top-up without string-matching on messages.
|
|
50
|
+
*
|
|
51
|
+
* Recovery: top up the balance, then retry the SAME operation reusing the
|
|
52
|
+
* captured `nonce` (the nonce is the idempotency key), or mint a fresh request.
|
|
53
|
+
*/
|
|
54
|
+
class InsufficientCreditsError extends BaseError {
|
|
55
|
+
constructor(message) {
|
|
56
|
+
super(message ??
|
|
57
|
+
'Insufficient Turbo credits to complete this purchase. Top up your balance and retry.');
|
|
58
|
+
/** Always the HTTP status that produced this error. */
|
|
59
|
+
this.status = 402;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.InsufficientCreditsError = InsufficientCreditsError;
|
|
45
63
|
class AbortError extends BaseError {
|
|
46
64
|
constructor(message = 'Request was aborted') {
|
|
47
65
|
super(message);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uuidV4 = uuidV4;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
const crypto_1 = require("crypto");
|
|
20
|
+
/**
|
|
21
|
+
* RFC 4122 version 4 UUID, derived from `randomBytes` (already used across the
|
|
22
|
+
* SDK in both the node and web builds). Avoids depending on
|
|
23
|
+
* `crypto.randomUUID`, whose availability varies by runtime/polyfill.
|
|
24
|
+
*/
|
|
25
|
+
function uuidV4() {
|
|
26
|
+
const bytes = (0, crypto_1.randomBytes)(16);
|
|
27
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
|
|
28
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC 4122 variant
|
|
29
|
+
const hex = bytes.toString('hex');
|
|
30
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
31
|
+
}
|
package/lib/cjs/web/signer.js
CHANGED
|
@@ -64,9 +64,11 @@ class TurboWebArweaveSigner extends signer_js_1.TurboDataItemAbstractSigner {
|
|
|
64
64
|
dataItemSizeFactory: () => signedDataItemSize,
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
-
async generateSignedRequestHeaders() {
|
|
67
|
+
async generateSignedRequestHeaders(nonce, additionalData) {
|
|
68
68
|
await this.setPublicKey();
|
|
69
|
-
|
|
69
|
+
// Pass through the caller's nonce + action-binding data (previously dropped,
|
|
70
|
+
// which would override a route-required UUID nonce and the H-2 binding).
|
|
71
|
+
return super.generateSignedRequestHeaders(nonce, additionalData);
|
|
70
72
|
}
|
|
71
73
|
async signData(dataToSign) {
|
|
72
74
|
await this.setPublicKey();
|
package/lib/esm/cli/cli.js
CHANGED
|
@@ -20,6 +20,7 @@ import { DataItem } from '@dha-team/arbundles';
|
|
|
20
20
|
import { program } from 'commander';
|
|
21
21
|
import { readFileSync, readdirSync } from 'fs';
|
|
22
22
|
import { version } from '../version.js';
|
|
23
|
+
import { arnsPrice, arnsPurchaseStatus, buyArNSName, extendArNSLease, increaseArNSUndernames, removeArNSRecord, setArNSRecord, transferArNSAnt, upgradeArNSName, } from './commands/arns.js';
|
|
23
24
|
import { fiatEstimate } from './commands/fiatEstimate.js';
|
|
24
25
|
import { balance, cryptoFund, price, topUp, uploadFile, uploadFolder, } from './commands/index.js';
|
|
25
26
|
import { listShares } from './commands/listShares.js';
|
|
@@ -27,7 +28,7 @@ import { revokeCredits } from './commands/revokeCredits.js';
|
|
|
27
28
|
import { shareCredits } from './commands/shareCredits.js';
|
|
28
29
|
import { tokenPrice } from './commands/tokenPrice.js';
|
|
29
30
|
import { x402UploadUnsignedFile } from './commands/x402UploadUnsignedData.js';
|
|
30
|
-
import { globalOptions, listSharesOptions, optionMap, revokeCreditsOptions, shareCreditsOptions, uploadFileOptions, uploadFolderOptions, walletOptions, } from './options.js';
|
|
31
|
+
import { arnsPriceOptions, arnsPurchaseStatusOptions, buyArNSNameOptions, extendArNSLeaseOptions, globalOptions, increaseArNSUndernamesOptions, listSharesOptions, optionMap, removeArNSRecordOptions, revokeCreditsOptions, setArNSRecordOptions, shareCreditsOptions, transferArNSAntOptions, upgradeArNSNameOptions, uploadFileOptions, uploadFolderOptions, walletOptions, } from './options.js';
|
|
31
32
|
import { applyOptions, runCommand } from './utils.js';
|
|
32
33
|
applyOptions(program
|
|
33
34
|
.name('turbo')
|
|
@@ -84,6 +85,51 @@ applyOptions(program
|
|
|
84
85
|
.description('Lists all given or received Turbo credit share approvals for specified address or connected wallet'), listSharesOptions).action(async (_commandOptions, command) => {
|
|
85
86
|
await runCommand(command, listShares);
|
|
86
87
|
});
|
|
88
|
+
applyOptions(program
|
|
89
|
+
.command('arns-price')
|
|
90
|
+
.description('Get the Turbo Credit (winc + mARIO) price to buy, extend, increase undernames, or upgrade an ArNS name'), arnsPriceOptions).action(async (_commandOptions, command) => {
|
|
91
|
+
await runCommand(command, arnsPrice);
|
|
92
|
+
});
|
|
93
|
+
applyOptions(program
|
|
94
|
+
.command('buy-arns-name')
|
|
95
|
+
.description('Buy an ArNS name (lease or permabuy) with Turbo Credits'), buyArNSNameOptions).action(async (_commandOptions, command) => {
|
|
96
|
+
await runCommand(command, buyArNSName);
|
|
97
|
+
});
|
|
98
|
+
applyOptions(program
|
|
99
|
+
.command('extend-arns-lease')
|
|
100
|
+
.description('Extend an ArNS name lease with Turbo Credits'), extendArNSLeaseOptions).action(async (_commandOptions, command) => {
|
|
101
|
+
await runCommand(command, extendArNSLease);
|
|
102
|
+
});
|
|
103
|
+
applyOptions(program
|
|
104
|
+
.command('increase-arns-undernames')
|
|
105
|
+
.description('Increase the undername limit of an ArNS name with Turbo Credits'), increaseArNSUndernamesOptions).action(async (_commandOptions, command) => {
|
|
106
|
+
await runCommand(command, increaseArNSUndernames);
|
|
107
|
+
});
|
|
108
|
+
applyOptions(program
|
|
109
|
+
.command('upgrade-arns-name')
|
|
110
|
+
.description('Upgrade an ArNS leased name to a permabuy with Turbo Credits'), upgradeArNSNameOptions).action(async (_commandOptions, command) => {
|
|
111
|
+
await runCommand(command, upgradeArNSName);
|
|
112
|
+
});
|
|
113
|
+
applyOptions(program
|
|
114
|
+
.command('arns-purchase-status')
|
|
115
|
+
.description('Get the status of an ArNS purchase by its nonce'), arnsPurchaseStatusOptions).action(async (_commandOptions, command) => {
|
|
116
|
+
await runCommand(command, arnsPurchaseStatus);
|
|
117
|
+
});
|
|
118
|
+
applyOptions(program
|
|
119
|
+
.command('transfer-arns-ant')
|
|
120
|
+
.description('Transfer a Turbo-custodied ANT to a Solana pubkey you control'), transferArNSAntOptions).action(async (_commandOptions, command) => {
|
|
121
|
+
await runCommand(command, transferArNSAnt);
|
|
122
|
+
});
|
|
123
|
+
applyOptions(program
|
|
124
|
+
.command('set-arns-record')
|
|
125
|
+
.description('Set a resolution record on a Turbo-custodied ANT'), setArNSRecordOptions).action(async (_commandOptions, command) => {
|
|
126
|
+
await runCommand(command, setArNSRecord);
|
|
127
|
+
});
|
|
128
|
+
applyOptions(program
|
|
129
|
+
.command('remove-arns-record')
|
|
130
|
+
.description('Remove a resolution record (undername) from a Turbo-custodied ANT'), removeArNSRecordOptions).action(async (_commandOptions, command) => {
|
|
131
|
+
await runCommand(command, removeArNSRecord);
|
|
132
|
+
});
|
|
87
133
|
applyOptions(program
|
|
88
134
|
.command('inspect-data-items')
|
|
89
135
|
.description('Lists all given or received Turbo credit share approvals for specified address or connected wallet'), [optionMap.folderPath]).action(async (_commandOptions, command) => {
|