UNPKG

@ar.io/sdk

Version:

[![codecov](https://codecov.io/gh/ar-io/ar-io-sdk/graph/badge.svg?token=7dXKcT7dJy)](https://codecov.io/gh/ar-io/ar-io-sdk)

224 lines (223 loc) 8.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TurboArNSPaymentProviderAuthenticated = exports.TurboArNSPaymentProviderUnauthenticated = exports.TurboArNSPaymentFactory = exports.defaultHeaders = void 0; exports.signedRequestHeadersFromSigner = signedRequestHeadersFromSigner; exports.isTurboArNSSigner = isTurboArNSSigner; /** * Copyright (C) 2022-2024 Permanent Data Solutions, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const arbundles_1 = require("@dha-team/arbundles"); const token_js_1 = require("../types/token.js"); const base64_js_1 = require("../utils/base64.js"); const url_js_1 = require("../utils/url.js"); const version_js_1 = require("../version.js"); const logger_js_1 = require("./logger.js"); exports.defaultHeaders = { 'x-source-version': `${version_js_1.version}`, 'x-source-identifier': 'ar-io-sdk', }; async function signedRequestHeadersFromSigner({ signer, nonce = crypto.randomUUID(), }) { let signature = undefined; let publicKey = undefined; const signatureType = isWanderArweaveBrowserSigner(signer) ? arbundles_1.SignatureConfig.ARWEAVE : signer.signatureType; // equivalent to window.arweaveWallet if (isWanderArweaveBrowserSigner(signer)) { signature = (0, base64_js_1.toB64Url)(Buffer.from(await signer.signMessage(Uint8Array.from(Buffer.from(nonce))))); } else if (signer instanceof arbundles_1.ArconnectSigner) { signature = (0, base64_js_1.toB64Url)(Buffer.from(await signer['signer'].signMessage(Uint8Array.from(Buffer.from(nonce))))); } else if (signer instanceof arbundles_1.ArweaveSigner || signer instanceof arbundles_1.EthereumSigner || signer instanceof arbundles_1.InjectedEthereumSigner) { if ('setPublicKey' in signer && signer['publicKey'] === undefined) { await signer.setPublicKey(); } signature = (0, base64_js_1.toB64Url)(Buffer.from(await signer.sign(Uint8Array.from(Buffer.from(nonce))))); } switch (signatureType) { case arbundles_1.SignatureConfig.ARWEAVE: if (isWanderArweaveBrowserSigner(signer)) { publicKey = await signer.getActivePublicKey(); } else if ('setPublicKey' in signer) { await signer.setPublicKey(); publicKey = (0, base64_js_1.toB64Url)(signer.publicKey); } else if ('publicKey' in signer) { publicKey = (0, base64_js_1.toB64Url)(signer.publicKey); } break; case arbundles_1.SignatureConfig.ETHEREUM: if ('publicKey' in signer) { publicKey = '0x' + signer.publicKey.toString('hex'); } else { throw new Error('Public key not found'); } break; // TODO: solana sig support // case SignatureConfig.SOLANA: // case SignatureConfig.ED25519: default: throw new Error(`Unsupported signer type for signing requests: ${signatureType}`); } if (publicKey === undefined || signature === undefined) { throw new Error('Public key or signature not found'); } return { 'x-public-key': publicKey, 'x-nonce': nonce, 'x-signature': signature, 'x-signature-type': signatureType.toString(), }; } class TurboArNSPaymentFactory { static init(config) { const { signer, paymentUrl, logger } = config ?? {}; if (signer !== undefined) { return new TurboArNSPaymentProviderAuthenticated({ signer, paymentUrl, logger, }); } return new TurboArNSPaymentProviderUnauthenticated({ paymentUrl, logger, }); } } exports.TurboArNSPaymentFactory = TurboArNSPaymentFactory; // Base class for unauthenticated operations class TurboArNSPaymentProviderUnauthenticated { paymentUrl; logger; constructor({ paymentUrl = 'https://payment.ardrive.io', logger = logger_js_1.Logger.default, }) { this.paymentUrl = paymentUrl; this.logger = logger; } async getArNSPriceDetails({ intent, name, quantity, type, years, }) { const url = (0, url_js_1.urlWithSearchParams)({ baseUrl: `${this.paymentUrl}/v1/arns/price/${intent}/${name}`, params: { increaseQty: quantity, type, years, }, }); const response = await fetch(url, { method: 'GET', headers: exports.defaultHeaders, }); const status = response.status; const data = (await response.json()); this.logger.debug('getArNSPriceDetails', { intent, name, quantity, type, years, data, status, }); if (status !== 200) { throw new Error('Failed to get ArNS purchase price ' + JSON.stringify(data)); } if (!data.winc || !data.mARIO) { throw new Error('Invalid response from Turbo ' + JSON.stringify(data)); } return { winc: data.winc, mARIO: new token_js_1.mARIOToken(+data.mARIO), }; } async getPrice(params) { const { winc } = await this.getArNSPriceDetails(params); return +winc; } } exports.TurboArNSPaymentProviderUnauthenticated = TurboArNSPaymentProviderUnauthenticated; // Class for authenticated operations, extending the base class class TurboArNSPaymentProviderAuthenticated extends TurboArNSPaymentProviderUnauthenticated { signer; constructor({ signer, ...restConfig }) { super(restConfig); // Pass unauthenticated config to base class+ if (!isTurboArNSSigner(signer)) { throw new Error('Signer must be a TurboArNSSigner'); } this.signer = signer; } async initiateArNSPurchase({ intent, name, quantity, type, processId, years, paidBy = [], referrer, }) { // Signer check is implicitly handled by requiring it in the constructor const url = (0, url_js_1.urlWithSearchParams)({ baseUrl: `${this.paymentUrl}/v1/arns/purchase/${intent}/${name}`, params: { increaseQty: quantity, processId, type, years, paidBy, referrer, }, }); const signedHeaders = await signedRequestHeadersFromSigner({ signer: this.signer, }); const response = await fetch(url, { method: 'POST', headers: { ...exports.defaultHeaders, ...signedHeaders, }, }); const status = response.status; const data = (await response.json()); this.logger.debug('Initiated ArNS purchase', { intent, name, quantity, processId, type, years, data, status, }); if (status !== 200) { throw new Error('Failed to initiate ArNS purchase ' + JSON.stringify(data)); } return { id: data.arioWriteResult.id, result: data.purchaseReceipt, }; } } exports.TurboArNSPaymentProviderAuthenticated = TurboArNSPaymentProviderAuthenticated; function isWanderArweaveBrowserSigner(signer) { return (typeof signer === 'object' && signer !== null && 'signMessage' in signer && 'getActivePublicKey' in signer); } function isTurboArNSSigner(signer) { const isWanderWallet = isWanderArweaveBrowserSigner(signer); const isSigner = signer instanceof arbundles_1.EthereumSigner || signer instanceof arbundles_1.InjectedEthereumSigner || signer instanceof arbundles_1.ArweaveSigner || signer instanceof arbundles_1.ArconnectSigner; return isWanderWallet || isSigner; }