Skip to content

Commit

Permalink
Merge pull request #168 from ardriveapp/alpha
Browse files Browse the repository at this point in the history
chore: release v1.16.0
  • Loading branch information
fedellen authored Sep 12, 2024
2 parents 2bc8478 + 066b73e commit da6b0a1
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 9 deletions.
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac
- [`getFiatToAR({ currency })`](#getfiattoar-currency-)
- [`getFiatRates()`](#getfiatrates)
- [`getWincForFiat({ amount })`](#getwincforfiat-amount-)
- [`getWincForToken({ tokenAmount })`](#getwincfortoken-tokenamount-)
- [`getUploadCosts({ bytes })`](#getuploadcosts-bytes-)
- [`uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, signal })`](#uploadsigneddataitem-dataitemstreamfactory-dataitemsizefactory-signal-)
- [`createCheckoutSession({ amount, owner })`](#createcheckoutsession-amount-owner-)
Expand Down Expand Up @@ -340,13 +341,23 @@ 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].
Returns the current amount of Winston Credits including all adjustments for the provided fiat currency.

```typescript
const { winc, paymentAmount, quotedPaymentAmount, adjustments } =
const { winc, actualPaymentAmount, quotedPaymentAmount, adjustments } =
await turbo.getWincForFiat({
amount: USD(100),
// promo codes require an authenticated client
});
```

#### `getWincForToken({ tokenAmount })`

Returns the current amount of Winston Credits including all adjustments for the provided token amount.

```typescript
const { winc, actualTokenAmount, equivalentWincTokenAmount } =
await turbo.getWincForToken({
tokenAmount: WinstonToTokenAmount(100_000_000),
});
```

Expand Down Expand Up @@ -727,18 +738,23 @@ turbo top-up --address 'crypto-wallet-public-native-address' --token ethereum --

##### `crypto-fund`

Fund a wallet with Turbo Credits by submitting a payment transaction for the crypto amount to the Turbo wallet and then submitting that transaction id to Turbo Payment Service for top up processing.
Fund a wallet with Turbo Credits by submitting a payment transaction for the crypto amount to the Turbo wallet and then submitting that transaction id to Turbo Payment Service for top up processing. Alternatively, submit a transaction ID of an existing funding transaction to Turbo Payment Service for top up processing.

Command Options:

- `-v, --value <value>` - Value of crypto token for fund. e.g: 0.0001 for 0.0001 KYVE
- `-i, --tx-id <txId>` - Transaction ID of an existing funding transaction

e.g:

```shell
turbo crypto-fund --value 0.0001 --token kyve --private-key 'b27...45c'
```

```shell
turbo crypto-fund --tx-id 'my-valid-arweave-fund-transaction-id' --token arweave
```

##### `upload-folder`

Upload a folder of files and create and upload a manifest file for the folder upload to the Turbo Upload Service.
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ardrive/turbo-sdk",
"version": "1.15.0",
"version": "1.16.0-alpha.3",
"main": "./lib/cjs/node/index.js",
"types": "./lib/types/node/index.d.ts",
"module": "./lib/esm/node/index.js",
Expand Down Expand Up @@ -91,6 +91,7 @@
"ethers": "^6.12.0",
"mime-types": "^2.1.35",
"plimit-lit": "^3.0.1",
"prompts": "^2.4.2",
"tweetnacl": "^1.0.3",
"winston": "^3.14.1"
},
Expand All @@ -106,6 +107,7 @@
"@types/mime-types": "^2.1.4",
"@types/mocha": "^10.0.1",
"@types/node": "^20.4.8",
"@types/prompts": "^2.4.9",
"@types/sinon": "^10.0.15",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^6.4.0",
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ applyOptions(

applyOptions(
program.command('crypto-fund').description('Top up a wallet with crypto'),
[...walletOptions, optionMap.value],
[...walletOptions, optionMap.value, optionMap.txId],
).action(async (_commandOptions, command: Command) => {
await runCommand(command, cryptoFund);
});
Expand Down
40 changes: 38 additions & 2 deletions src/cli/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
import { exec } from 'node:child_process';
import { createReadStream, statSync } from 'node:fs';
import prompts from 'prompts';

import {
TurboFactory,
Expand Down Expand Up @@ -78,16 +79,51 @@ export async function getBalance(options: AddressOptions) {
/** Fund the connected signer with crypto */
export async function cryptoFund(options: CryptoFundOptions) {
const value = options.value;
const txId = options.txId;

if (txId !== undefined) {
const turbo = TurboFactory.unauthenticated(configFromOptions(options));
const result = await turbo.submitFundTransaction({ txId: txId });

console.log(
'Submitted existing crypto fund transaction to payment service: \n',
JSON.stringify(result, null, 2),
);
return;
}

if (value === undefined) {
throw new Error('Must provide a --value to top up');
throw new Error(
'Must provide a --value or --transaction-id for crypto-fund command',
);
}

const turbo = await turboFromOptions(options);

const token = tokenFromOptions(options);
const tokenAmount = tokenToBaseMap[token](value);

if (!options.skipConfirmation) {
const { winc } = await turbo.getWincForToken({ tokenAmount });
const targetWallet = (await turbo.getTurboCryptoWallets())[token];

const credits = (+winc / 1_000_000_000_000).toFixed(12);

const { confirm } = await prompts({
type: 'confirm',
name: 'confirm',
message: `\nTransaction details:\n\n Amount: ${value} ${token}\n Target: ${targetWallet}\n Credits received: ${credits}\n Credit recipient: ${await turbo.signer.getNativeAddress()}\n Network fees: (Gas fees apply)\n\nThis payment is non-refundable. Proceed with transaction?`,
initial: true,
});

if (!confirm) {
console.log('Aborted crypto fund transaction');
return;
}
}

const result = await turbo.topUpWithTokens({
tokenAmount: tokenToBaseMap[token](value),
tokenAmount,
});

console.log(
Expand Down
10 changes: 10 additions & 0 deletions src/cli/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export const optionMap = {
description: 'Fiat currency type to use for the action',
default: 'usd',
},
txId: {
alias: '-i, --tx-id <txId>',
description: 'Transaction ID or hash to use for action',
},
address: {
alias: '-a, --address <nativeAddress>',
description: 'Native address to use for action',
Expand Down Expand Up @@ -71,6 +75,11 @@ export const optionMap = {
description: 'Disable logging',
default: false,
},
skipConfirmation: {
alias: '--skip-confirmation',
description: 'Skip all confirmation prompts',
default: false,
},
folderPath: {
alias: '-f, --folder-path <folderPath>',
description: 'Directory to upload',
Expand Down Expand Up @@ -111,6 +120,7 @@ export const globalOptions = [
optionMap.debug,
optionMap.quiet,
optionMap.token,
optionMap.skipConfirmation,
];

export const uploadFolderOptions = [
Expand Down
2 changes: 2 additions & 0 deletions src/cli/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type GlobalOptions = {
gateway: string | undefined;
debug: boolean;
quiet: boolean;
skipConfirmation: boolean;
token: string;
};

Expand Down Expand Up @@ -52,4 +53,5 @@ export type UploadFileOptions = WalletOptions & {

export type CryptoFundOptions = WalletOptions & {
value: string | undefined;
txId: string | undefined;
};
27 changes: 27 additions & 0 deletions src/common/payment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Buffer } from 'node:buffer';

import {
Currency,
RawWincForTokenResponse,
TokenTools,
TokenType,
TopUpRawResponse,
Expand All @@ -44,6 +45,8 @@ import {
TurboUnauthenticatedPaymentServiceInterface,
TurboWincForFiatParams,
TurboWincForFiatResponse,
TurboWincForTokenParams,
TurboWincForTokenResponse,
} from '../types.js';
import { TurboHTTPService } from './http.js';
import { TurboWinstonLogger } from './logger.js';
Expand Down Expand Up @@ -139,11 +142,35 @@ export class TurboUnauthenticatedPaymentService
});
}

public async getWincForToken({
tokenAmount,
}: TurboWincForTokenParams): Promise<TurboWincForTokenResponse> {
const { actualPaymentAmount, fees, winc } =
await this.httpService.get<RawWincForTokenResponse>({
endpoint: `/price/${this.token}/${tokenAmount}`,
});

return {
winc,
fees,
actualTokenAmount: tokenAmount.toString(),
equivalentWincTokenAmount: actualPaymentAmount.toString(),
};
}

protected appendPromoCodesToQuery(promoCodes: string[]): string {
const promoCodesQuery = promoCodes.join(',');
return promoCodesQuery ? `promoCode=${promoCodesQuery}` : '';
}

public async getTurboCryptoWallets(): Promise<Record<TokenType, string>> {
const { addresses } = await this.httpService.get<TurboInfoResponse>({
endpoint: '/info',
});

return addresses;
}

protected async getCheckout(
{
amount,
Expand Down
19 changes: 19 additions & 0 deletions src/common/turbo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import {
Currency,
NativeAddress,
TokenType,
TurboAbortSignal,
TurboAuthenticatedClientConfiguration,
TurboAuthenticatedClientInterface,
Expand Down Expand Up @@ -45,6 +46,8 @@ import {
TurboUploadFolderResponse,
TurboWincForFiatParams,
TurboWincForFiatResponse,
TurboWincForTokenParams,
TurboWincForTokenResponse,
} from '../types.js';
import {
TurboUnauthenticatedPaymentService,
Expand Down Expand Up @@ -154,6 +157,15 @@ export class TurboUnauthenticatedClient
return this.paymentService.getWincForFiat(params);
}

/**
* Determines the amount of 'winc' that would be returned for a given token and amount, including all Turbo cost adjustments and fees.
*/
getWincForToken(
params: TurboWincForTokenParams,
): Promise<TurboWincForTokenResponse> {
return this.paymentService.getWincForToken(params);
}

/**
* Uploads a signed data item to the Turbo Upload Service.
*/
Expand Down Expand Up @@ -187,6 +199,13 @@ export class TurboUnauthenticatedClient
}): Promise<TurboSubmitFundTxResponse> {
return this.paymentService.submitFundTransaction(p);
}

/**
* Returns the connected target Turbo wallet addresses for all supported tokens.
*/
getTurboCryptoWallets(): Promise<Record<TokenType, string>> {
return this.paymentService.getTurboCryptoWallets();
}
}

export class TurboAuthenticatedClient
Expand Down
23 changes: 23 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,31 @@ export type TurboWincForFiatResponse = TurboPriceResponse & {
quotedPaymentAmount: number;
};

export type RawWincForTokenResponse = Omit<
TurboPriceResponse,
'adjustments'
> & {
actualPaymentAmount: number;
};

export type TurboWincForTokenResponse = Omit<
TurboPriceResponse,
'adjustments'
> & {
actualTokenAmount: string;
equivalentWincTokenAmount: string;
};

export type TurboWincForFiatParams = {
amount: CurrencyMap;
nativeAddress?: NativeAddress;
promoCodes?: string[];
};

export type TurboWincForTokenParams = {
tokenAmount: BigNumber.Value;
};

export type UiMode = 'embedded' | 'hosted';
export type TurboCheckoutSessionParams = TurboWincForFiatParams & {
owner: PublicArweaveAddress;
Expand Down Expand Up @@ -452,6 +471,7 @@ export interface TurboUnauthenticatedPaymentServiceInterface {
getBalance: (address: string) => Promise<TurboBalanceResponse>;
getSupportedCurrencies(): Promise<TurboCurrenciesResponse>;
getSupportedCountries(): Promise<TurboCountriesResponse>;
getTurboCryptoWallets(): Promise<Record<TokenType, string>>;
getFiatToAR({
currency,
}: {
Expand All @@ -461,6 +481,9 @@ export interface TurboUnauthenticatedPaymentServiceInterface {
getWincForFiat(
params: TurboWincForFiatParams,
): Promise<TurboWincForFiatResponse>;
getWincForToken(
params: TurboWincForTokenParams,
): Promise<TurboWincForTokenResponse>;
getUploadCosts({ bytes }: { bytes: number[] }): Promise<TurboPriceResponse[]>;
createCheckoutSession(
params: TurboCheckoutSessionParams,
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
*/

// AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
export const version = '1.15.0';
export const version = '1.16.0-alpha.3';
22 changes: 22 additions & 0 deletions tests/turbo.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,16 @@ describe('Node environment', () => {
expect(countries).to.include('United States');
});

it('getTurboCryptoWallets', async () => {
const wallets = await turbo.getTurboCryptoWallets();

expect(wallets).to.not.be.undefined;
expect(wallets).to.have.property('arweave');
expect(wallets).to.have.property('ethereum');
expect(wallets).to.have.property('solana');
expect(wallets).to.have.property('kyve');
});

it('getSupportedCurrencies()', async () => {
const { supportedCurrencies, limits } =
await turbo.getSupportedCurrencies();
Expand Down Expand Up @@ -313,6 +323,18 @@ describe('Node environment', () => {
expect(fees).to.have.length(1);
});

it('getWincForToken()', async () => {
const { winc, actualTokenAmount, equivalentWincTokenAmount, fees } =
await turbo.getWincForToken({
tokenAmount: 100000, // 100,000 winston
});
expect(winc).to.not.be.undefined;
expect(+winc).to.be.greaterThan(0);
expect(actualTokenAmount).to.equal('100000');
expect(equivalentWincTokenAmount).to.equal('100000');
expect(fees).to.have.length(1);
});

describe('uploadSignedDataItem()', () => {
const signer = new ArweaveSigner(testJwk);
it('should properly upload a signed Buffer to turbo', async () => {
Expand Down
Loading

0 comments on commit da6b0a1

Please sign in to comment.