@ardriveapp/turbo-sdk 🚀

Welcome to the @ardrive/turbo-sdk
! This SDK provides functionality for interacting with the Turbo Upload and Payment Services and is available for both NodeJS and Web environments.
Table of Contents
- Table of Contents
- Installation
- Quick Start
- Usage
- APIs
- TurboFactory
- TurboUnauthenticatedClient
- TurboAuthenticatedClient
getBalance()
getWincForFiat({ amount, promoCodes })
createCheckoutSession({ amount, owner, promoCodes })
uploadFile({ fileStreamFactory, fileSizeFactory, signal, dataItemOpts })
uploadFolder({ folderPath, files, dataItemOpts, signal, maxConcurrentUploads, throwOnFailure, manifestOptions })
topUpWithTokens({ tokenAmount, feeMultiplier })
- Developers
Installation
npm install @ardrive/turbo-sdk
or
yarn add @ardrive/turbo-sdk
Quick Start
import { TurboFactory, ArweaveSigner } from '@ardrive/turbo-sdk';
const jwk = fs.readFileSync('./my-jwk.json');
const address = arweave.wallets.jwkToAddress(jwk);
const turbo = TurboFactory.authenticated({ privateKey: jwk });
const signer = new ArweaveSigner(jwk);
const turbo = TurboFactory.authenticated({ signer });
const { winc: balance } = await turbo.getBalance();
const filePath = path.join(__dirname, './my-image.png');
const fileSize = fs.statSync(filePath).size;
const [{ winc: fileSizeCost }] = await turbo.getUploadCosts({
bytes: [fileSize],
});
if (balance < fileSizeCost) {
const { url } = await turbo.createCheckoutSession({
amount: fileSizeCost,
owner: address,
});
open(url);
return;
}
try {
const { id, owner, dataCaches, fastFinalityIndexes } = await turbo.uploadFile(() => {
fileStreamFactory => () => fs.createReadStream(filePath),
fileSizeFactory => () => fileSize,
});
console.log('Successfully upload data item!', { id, owner, dataCaches, fastFinalityIndexes });
} catch (error) {
console.error('Failed to upload data item!', error);
} finally {
const { winc: newBalance } = await turbo.getBalance();
console.log('New balance:', newBalance);
}
Usage
The SDK is provided in both CommonJS and ESM formats, and it's compatible with bundlers such as Webpack, Rollup, and ESbuild. Utilize the appropriately named exports provided by this SDK's package.json based on your project's configuration. Refer to the examples directory to see how to use the SDK in various environments.
Web
Bundlers (Webpack, Rollup, ESbuild, etc.)
CommonJS:
import { TurboFactory } from '@ardrive/turbo-sdk';
const turbo = TurboFactory.unauthenticated();
const rates = await turbo.getFiatRates();
[!WARNING]
Polyfills are not provided by default for bundled web projects (Vite, ESBuild, Webpack, Rollup, etc.) . Depending on your apps bundler configuration and plugins, you will need to provide polyfills for various imports including crypto
, process
, fs
and buffer
. Refer to your bundler's documentation for how to provide the necessary polyfills.
ESM:
import { TurboFactory } from '@ardrive/turbo-sdk/<node/web>';
const turbo = TurboFactory.unauthenticated();
const rates = await turbo.getFiatRates();
Browser
<script type="module">
import { TurboFactory } from 'https://unpkg.com/@ardrive/turbo-sdk';
const turbo = TurboFactory.unauthenticated();
const rates = await turbo.getFiatRates();
</script>
NodeJS
CommonJS
Example available in the examples/typescript/cjs.
ESM
Example available in the examples/typescript/esm.
Typescript
The SDK provides TypeScript types. When you import the SDK in a TypeScript project:
import { TurboFactory } from '@ardrive/turbo-sdk/<node/web>';
Types are exported from ./lib/types/[node/web]/index.d.ts
and should be automatically recognized, offering benefits such as type-checking and autocompletion.
Examples
Examples are available in the examples directory. To run examples:
yarn example:web
- opens up the example web pageyarn example:cjs
- runs example CJS node scriptyarn example:esm
- runs example ESM node script
APIs
TurboFactory
unauthenticated()
Creates an instance of a client that accesses Turbo's unauthenticated services.
const turbo = TurboFactory.unauthenticated();
authenticated()
Creates an instance of a client that accesses Turbo's authenticated and unauthenticated services. Requires either a signer, or private key to be provided.
Arweave JWK
const jwk = await arweave.crypto.generateJWK();
const turbo = TurboFactory.authenticated({ privateKey: jwk });
ArweaveSigner
const signer = new ArweaveSigner(jwk);
const turbo = TurboFactory.authenticated({ signer });
ArconnectSigner
const signer = new ArconnectSigner(window.arweaveWallet);
const turbo = TurboFactory.authenticated({ signer });
EthereumSigner
const signer = new EthereumSigner(privateKey);
const turbo = TurboFactory.authenticated({ signer });
Ethereum Private Key
const turbo = TurboFactory.authenticated({
privateKey: ethHexadecimalPrivateKey,
token: 'ethereum',
});
HexSolanaSigner
const signer = new HexSolanaSigner(bs58.encode(secretKey));
const turbo = TurboFactory.authenticated({ signer });
Solana Secret Key
const turbo = TurboFactory.authenticated({
privateKey: bs58.encode(secretKey),
token: 'solana',
});
TurboUnauthenticatedClient
getSupportedCurrencies()
Returns the list of currencies supported by the Turbo Payment Service for topping up a user balance of AR Credits (measured in Winston Credits, or winc).
const currencies = await turbo.getSupportedCurrencies();
getSupportedCountries()
Returns the list of countries supported by the Turbo Payment Service's top up workflow.
const countries = await turbo.getSupportedCountries();
getFiatToAR({ currency })
Returns the current raw fiat to AR conversion rate for a specific currency as reported by third-party pricing oracles.
const fiatToAR = await turbo.getFiatToAR({ currency: 'USD' });
getFiatRates()
Returns the current fiat rates for 1 GiB of data for supported currencies, including all top-up adjustments and fees.
const rates = await turbo.getFiatRates();
getWincForFiat({ amount })
Returns the current amount of Winston Credits including all adjustments for the provided fiat currency, amount. To leverage promo codes, see TurboAuthenticatedClient.
const { winc, paymentAmount, quotedPaymentAmount, adjustments } =
await turbo.getWincForFiat({
amount: USD(100),
});
getUploadCosts({ bytes })
Returns the estimated cost in Winston Credits for the provided file sizes, including all upload adjustments and fees.
const [uploadCostForFile] = await turbo.getUploadCosts({ bytes: [1024] });
const { winc, adjustments } = uploadCostForFile;
uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, signal })
Uploads a signed data item. The provided dataItemStreamFactory
should produce a NEW signed data item stream each time is it invoked. The dataItemSizeFactory
is a function that returns the size of the file. The signal
is an optional AbortSignal that can be used to cancel the upload or timeout the request.
const filePath = path.join(__dirname, './my-signed-data-item');
const dataItemSize = fs.statSync(filePath).size;
const uploadResponse = await turbo.uploadSignedDataItem({
dataItemStreamFactory: () => fs.createReadStream(filePath),
dataItemSizeFactory: () => dataItemSize,
signal: AbortSignal.timeout(10_000),
});
createCheckoutSession({ amount, owner })
Creates a Stripe checkout session for a Turbo Top Up with the provided amount, currency, owner. The returned URL can be opened in the browser, all payments are processed by Stripe. To leverage promo codes, see TurboAuthenticatedClient.
Arweave (AR)
const { url, winc, paymentAmount, quotedPaymentAmount, adjustments } =
await turbo.createCheckoutSession({
amount: USD(10.0),
owner: publicArweaveAddress,
});
if (process.platform === 'darwin') {
exec(`open ${url}`);
} else if (process.platform === 'win32') {
exec(`start "" "${url}"`, { shell: true });
} else {
open(url);
}
Ethereum (ETH)
const turbo = TurboFactory.unauthenticated({ token: 'ethereum' });
const { url, winc, paymentAmount } = await turbo.createCheckoutSession({
amount: USD(10.0),
owner: publicEthereumAddress,
});
Solana (SOL)
const turbo = TurboFactory.unauthenticated({ token: 'solana' });
const { url, winc, paymentAmount } = await turbo.createCheckoutSession({
amount: USD(10.0),
owner: publicSolanaAddress,
});
submitFundTransaction({ txId })
Submits the transaction ID of a funding transaction to Turbo Payment Service for top up processing. The txId
is the transaction ID of the transaction to be submitted.
[!NOTE]
Use this API if you've already executed your token transfer to the Turbo wallet. Otherwise, consider using topUpWithTokens
to execute a new token transfer to the Turbo wallet and submit its resulting transaction ID for top up processing all in one go
const turbo = TurboFactory.unauthenticated();
const { status, id, ...fundResult } = await turbo.submitFundTransaction({
txId: 'my-valid-arweave-fund-transaction-id',
});
TurboAuthenticatedClient
getBalance()
Issues a signed request to get the credit balance of a wallet measured in AR (measured in Winston Credits, or winc).
const { winc: balance } = await turbo.getBalance();
getWincForFiat({ amount, promoCodes })
Returns the current amount of Winston Credits including all adjustments for the provided fiat currency, amount, and optional promo codes.
const { winc, paymentAmount, quotedPaymentAmount, adjustments } =
await turbo.getWincForFiat({
amount: USD(100),
promoCodes: ['MY_PROMO_CODE'],
});
createCheckoutSession({ amount, owner, promoCodes })
Creates a Stripe checkout session for a Turbo Top Up with the provided amount, currency, owner, and optional promo codes. The returned URL can be opened in the browser, all payments are processed by Stripe. Promo codes require an authenticated client.
const { url, winc, paymentAmount, quotedPaymentAmount, adjustments } =
await turbo.createCheckoutSession({
amount: USD(10.0),
owner: publicArweaveAddress,
promoCodes: ['MY_PROMO_CODE'],
});
if (process.platform === 'darwin') {
exec(`open ${url}`);
} else if (process.platform === 'win32') {
exec(`start "" "${url}"`, { shell: true });
} else {
open(url);
}
uploadFile({ fileStreamFactory, fileSizeFactory, signal, dataItemOpts })
Signs and uploads a raw file. The provided fileStreamFactory
should produce a NEW file data stream each time is it invoked. The fileSizeFactory
is a function that returns the size of the file. The signal
is an optional AbortSignal that can be used to cancel the upload or timeout the request. dataItemOpts
is an optional object that can be used to configure tags, target, and anchor for the data item upload.
const filePath = path.join(__dirname, './my-unsigned-file.txt');
const fileSize = fs.stateSync(filePath).size;
const uploadResult = await turbo.uploadFile({
fileStreamFactory: () => fs.createReadStream(filePath),
fileSizeFactory: () => fileSize,
dataItemOpts: {
tags: [
{
name: 'Content-Type',
value: 'text/plain',
},
{
name: 'My-Custom-Tag',
value: 'my-custom-value',
},
],
},
});
uploadFolder({ folderPath, files, dataItemOpts, signal, maxConcurrentUploads, throwOnFailure, manifestOptions })
Signs and uploads a folder of files. For NodeJS, the folderPath
of the folder to upload is required. For the browser, an array of files
is required. The dataItemOpts
is an optional object that can be used to configure tags, target, and anchor for the data item upload. The signal
is an optional AbortSignal that can be used to cancel the upload or timeout the request. The maxConcurrentUploads
is an optional number that can be used to limit the number of concurrent uploads. The throwOnFailure
is an optional boolean that can be used to throw an error if any upload fails. The manifestOptions
is an optional object that can be used to configure the manifest file, including a custom index file, fallback file, or whether to disable manifests altogether. Manifests are enabled by default.
NodeJS Upload Folder
const folderPath = path.join(__dirname, './my-folder');
const { manifest, fileResponses, manifestResponse } = await turbo.uploadFolder({
folderPath,
dataItemOpts: {
tags: [
{
name: 'Content-Type',
value: 'text/plain',
},
{
name: 'My-Custom-Tag',
value: 'my-custom-value',
},
],
},
manifestOptions: {
indexFile: 'custom-index.html',
fallbackFile: 'custom-fallback.html',
disableManifests: false,
},
});
Browser Upload Folder
<input type="file" id="folder" name="folder" webkitdirectory />
<script type="module">
const folderInput = document.getElementById('folder');
folderInput.addEventListener('change', async (event) => {
const selectedFiles = folderInput.files;
console.log('Folder selected:', selectedFiles);
const { manifest, fileResponses, manifestResponse } =
await turbo.uploadFolder({
files: Array.from(selectedFiles).map((file) => file),
});
console.log(manifest, fileResponses, manifestResponse);
});
</script>
topUpWithTokens({ tokenAmount, feeMultiplier })
Tops up the connected wallet with Credits by submitting a payment transaction for the token amount to the Turbo wallet and then submitting that transaction id to Turbo Payment Service for top up processing.
- The
tokenAmount
is the amount of tokens in the token type's smallest unit value (e.g: Winston for arweave token type) to fund the wallet with. - The
feeMultiplier
(optional) is the multiplier to apply to the reward for the transaction to modify its chances of being mined. Credits will be added to the wallet balance after the transaction is confirmed on the given blockchain. Defaults to 1.0, meaning no multiplier.
const turbo = TurboFactory.authenticated({ signer, token: 'arweave' });
const { winc, status, id, ...fundResult } = await turbo.topUpWithTokens({
tokenAmount: WinstonToTokenAmount(100_000_000),
feeMultiplier: 1.1,
});
Ethereum (ETH)
const turbo = TurboFactory.authenticated({ signer, token: 'ethereum' });
const { winc, status, id, ...fundResult } = await turbo.topUpWithTokens({
tokenAmount: ETHToTokenAmount(0.00001),
});
Solana (SOL)
const turbo = TurboFactory.authenticated({ signer, token: 'solana' });
const { winc, status, id, ...fundResult } = await turbo.topUpWithTokens({
tokenAmount: SOLToTokenAmount(0.00001),
});
Developers
Requirements
Setup & Build
yarn install
- installs dependenciesyarn build
- builds web/node/bundled outputs
Testing
yarn test
- runs integration tests against dev environment (e.g. https://payment.ardrive.dev
and https://upload.ardrive.dev
)yarn test:docker
- runs integration tests against locally running docker containers (recommended)yarn example:web
- opens up the example web pageyarn example:cjs
- runs example CJS node scriptyarn example:esm
- runs example ESM node script
Linting & Formatting
yarn lint:check
- checks for linting errorsyarn lint:fix
- fixes linting errorsyarn format:check
- checks for formatting errorsyarn format:fix
- fixes formatting errors
Architecture
- Code to interfaces.
- Prefer type safety over runtime safety.
- Prefer composition over inheritance.
- Prefer integration tests over unit tests.
For more information on how to contribute, please see CONTRIBUTING.md.