Skip to content

Commit

Permalink
Merge pull request #198 from ardriveapp/PE-6754-credit-sharing
Browse files Browse the repository at this point in the history
refactor: use credit sharing in commands/methods/docs PE-6754
  • Loading branch information
fedellen authored Nov 1, 2024
2 parents d7a6f5e + b2acf6a commit 84216ef
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 189 deletions.
100 changes: 64 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac
- [Polygon (POL / MATIC) Crypto Top Up](#polygon-pol--matic-crypto-top-up)
- [Solana (SOL) Crypto Top Up](#solana-sol-crypto-top-up)
- [KYVE Crypto Top Up](#kyve-crypto-top-up)
- [`createDelegatedPaymentApproval({ approvedAddress, approvedWincAmount, expiresBySeconds })`](#createdelegatedpaymentapproval-approvedaddress-approvedwincamount-expiresbyseconds-)
- [`revokeDelegatedPaymentApprovals({ approvedAddress })`](#revokedelegatedpaymentapprovals-approvedaddress-)
- [`getDelegatedPaymentApprovals({ userAddress })`](#getdelegatedpaymentapprovals-useraddress-)
- [`shareCredits({ approvedAddress, approvedWincAmount, expiresBySeconds })`](#sharecredits-approvedaddress-approvedwincamount-expiresbyseconds-)
- [`revokeCredits({ approvedAddress })`](#revokecredits-approvedaddress-)
- [`getCreditShareApprovals({ userAddress })`](#getcreditshareapprovals-useraddress-)
- [CLI](#cli)
- [Install CLI](#install-cli)
- [CLI Usage](#cli-usage)
Expand All @@ -79,9 +79,10 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac
- [`upload-folder`](#upload-folder)
- [`upload-file`](#upload-file)
- [`price`](#price)
- [`create-approval`](#create-approval)
- [`revoke-approvals`](#revoke-approvals)
- [`list-approvals`](#list-approvals)
- [`share-credits`](#share-credits)
- [`revoke-credits`](#revoke-credits)
- [`list-shares`](#list-shares)
- [Turbo Credit Sharing](#turbo-credit-sharing)
- [Developers](#developers)
- [Requirements](#requirements)
- [Setup & Build](#setup--build)
Expand Down Expand Up @@ -683,36 +684,35 @@ const { winc, status, id, ...fundResult } = await turbo.topUpWithTokens({
});
```

#### `createDelegatedPaymentApproval({ approvedAddress, approvedWincAmount, expiresBySeconds })`
#### `shareCredits({ approvedAddress, approvedWincAmount, expiresBySeconds })`

Creates a delegated payment approval from the connected wallet to the provided native address and approved winc amount. This action will create a data item for the approval
Shares credits from the connected wallet to the provided native address and approved winc amount. This action will create a signed data item for the approval

```typescript
const { approvalDataItemId, approvedWincAmount } =
await turbo.createDelegatedPaymentApproval({
approvedAddress: '2cor...VUa',
approvedWincAmount: 0.08315565032,
expiresBySeconds: 3600,
});
const { approvalDataItemId, approvedWincAmount } = await turbo.shareCredits({
approvedAddress: '2cor...VUa',
approvedWincAmount: 0.08315565032,
expiresBySeconds: 3600,
});
```

#### `revokeDelegatedPaymentApprovals({ approvedAddress })`
#### `revokeCredits({ approvedAddress })`

Revokes all delegated payment approvals from the connected wallet to the provided native address.
Revokes all credits shared from the connected wallet to the provided native address.

```typescript
const revokedApprovals = await turbo.revokeDelegatePaymentApprovals({
const revokedApprovals = await turbo.revokeCredits({
approvedAddress: '2cor...VUa',
});
```

#### `getDelegatedPaymentApprovals({ userAddress })`
#### `getCreditShareApprovals({ userAddress })`

Returns all delegated payment approvals from the connected wallet or the provided native address.
Returns all given or received credit share approvals for the connected wallet or the provided native address.

```typescript
const { givenApprovals, receivedApprovals } =
await turbo.getDelegatedPaymentApprovals({
await turbo.getCreditShareApprovals({
userAddress: '2cor...VUa',
});
```
Expand Down Expand Up @@ -782,8 +782,8 @@ Wallet options:
Upload options:

- `--paid-by <paidBy...>` - A list of native addresses to pay for the upload.
- `--ignore-approvals` - When no paid by is provided, the CLI will look for and use any received delegated payment approvals to pay for the upload. This flag will ignore any approvals and only use the connected wallet's balance for upload payment. Default: false
- `--use-signer-balance-first` - Use the connected wallet's balance before using any delegated payment approvals for the upload. Default: false
- `--ignore-approvals` - When no paid by is provided, the CLI will look for and use any received credit share approvals to pay for the upload. This flag will ignore any approvals and only use the connected wallet's balance for upload payment. Default: false
- `--use-signer-balance-first` - Use the connected wallet's balance before using any credit share approvals for the upload. Default: false

#### Commands

Expand Down Expand Up @@ -896,50 +896,78 @@ turbo price --value 1024 --type bytes
turbo price --value 1.1 --type arweave
```

##### `create-approval`
##### `share-credits`

Create a delegated payment approval from the connected wallet to the provided native address and approved winc amount.
Shares credits from the connected wallet to the provided native address and approved winc amount.

Command Options:

- `-a, --address <nativeAddress>` - Native address to that will receive the delegated payment approval
- `-v, --value <value>` - Value of winc to create delegated payment approval for
- `-e, --expires-by-seconds <seconds>` - Expiry time in seconds for the delegated payment approval
- `-a, --address <nativeAddress>` - Native address to that will receive the Credits
- `-v, --value <value>` - Value of winc to share to the target address
- `-e, --expires-by-seconds <seconds>` - Expiry time in seconds for the credit share approval

e.g:

```shell
turbo create-approval --address 2cor...VUa --value 0.083155650320 --wallet-file ../path/to/my/wallet --expires-by-seconds 3600
turbo share-credits --address 2cor...VUa --value 0.083155650320 --wallet-file ../path/to/my/wallet --expires-by-seconds 3600
```

##### `revoke-approvals`
##### `revoke-credits`

Revoke all delegated payment approvals from the connected wallet to the provided native address.
Revoke all credits shared from the connected wallet to the provided native address.

Command Options:

- `-a, --address <nativeAddress>` - Native address to revoke delegated payment approvals for
- `-a, --address <nativeAddress>` - Native address to revoke credit share approvals for

e.g:

```shell
turbo revoke-approvals --wallet-file ../path/to/my/wallet
turbo revoke-credits --wallet-file ../path/to/my/wallet
```

##### `list-approvals`
##### `list-shares`

List all given and received delegated payment approvals from the connected wallet or the provided native address.
List all given and received credit share approvals from the connected wallet or the provided native address.

Command Options:

- `-a, --address <nativeAddress>` - Native address to list delegated payment approvals for
- `-a, --address <nativeAddress>` - Native address to list credit share approvals for

e.g:

```shell
turbo list-approvals --address 2cor...VUa --wallet-file ../path/to/my/wallet
turbo list-shares --address 2cor...VUa --wallet-file ../path/to/my/wallet
```

## Turbo Credit Sharing

Users can share their purchased Credits with other user's wallets by creating Credit Share Approvals. These approvals are created by uploading a signed data item with tags indicating the recipient's wallet address, the amount of Credits to share, and an optional amount of seconds that the approval will expire in. The recipient can then use the shared Credits to pay for their own uploads to Turbo.

Shared Credits cannot be re-shared by the recipient to other recipients. Only the owner of the Credits can share or revoke Credit Share Approvals. Credits that are shared to other wallets may not be used by the original owner of the Credits for sharing or uploading unless the Credit Share Approval is revoked or expired.

Approvals can be revoked at any time by similarly uploading a signed data item with tags indicating the recipient's wallet address. This will remove all approvals and prevent the recipient from using the shared Credits. All unused Credits from expired or revoked approvals are returned to the original owner of the Credits.

To use the shared Credits, recipient users must provide the wallet address of the user who shared the Credits with them in the `x-paid-by` HTTP header when uploading data. This tells Turbo services to look for and use Credit Share Approvals to pay for the upload before using the signer's balance.

For user convenience, during upload the Turbo CLI will use any available Credit Share Approvals found for the connected wallet before using the signing wallet's balance. To instead ignore all Credit shares and only use the signer's balance, use the `--ignore-approvals` flag. To use the signer's balance first before using Credit shares, use the `--use-signer-balance-first` flag. The Turbo SDK layer does not provide this functionality and will always use the signer's balance unless `paidBy` is provided.

The Turbo SDK provides the following methods to manage Credit Share Approvals:

- `shareCredits`: Creates a Credit Share Approval for the specified wallet address and amount of Credits.
- `revokeCredits`: Revokes all Credit Share Approvals for the specified wallet address.
- `listShares`: Lists all Credit Share Approvals for the specified wallet address or connected wallet.
- `dataItemOpts: { ...opts, paidBy: string[] }`: Upload methods now accept an array of wallet addresses to pay for the upload.

The Turbo CLI provides the following commands to manage Credit Share Approvals:

- `share-credits`: Creates a Credit Share Approval for the specified wallet address and amount of Credits.
- `revoke-credits`: Revokes all Credit Share Approvals for the specified wallet address.
- `list-shares`: Lists all Credit Share Approvals for the specified wallet address or connected wallet.
- `paidBy: --paid-by <paidBy...>`: Upload commands now accept an array of wallet addresses to pay for the upload.
- `--ignore-approvals`: Ignore all Credit Share Approvals and only use the signer's balance.
- `--use-signer-balance-first`: Use the signer's balance first before using Credit Share Approvals.

## Developers

### Requirements
Expand Down
38 changes: 18 additions & 20 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import { Command, program } from 'commander';

import { version } from '../version.js';
import { createApproval } from './commands/createApproval.js';
import {
balance,
cryptoFund,
Expand All @@ -29,14 +28,15 @@ import {
uploadFile,
uploadFolder,
} from './commands/index.js';
import { listApprovals } from './commands/listApprovals.js';
import { revokeApprovals } from './commands/revokeApprovals.js';
import { listShares } from './commands/listShares.js';
import { revokeCredits } from './commands/revokeCredits.js';
import { shareCredits } from './commands/shareCredits.js';
import {
createApprovalOptions,
globalOptions,
listApprovalsOptions,
listSharesOptions,
optionMap,
revokeApprovalsOptions,
revokeCreditsOptions,
shareCreditsOptions,
uploadFileOptions,
uploadFolderOptions,
walletOptions,
Expand Down Expand Up @@ -101,33 +101,31 @@ applyOptions(

applyOptions(
program
.command('create-approval')
.description('Create a Turbo delegated payment approval'),
createApprovalOptions,
.command('share-credits')
.description('Create a Turbo credit share approval'),
shareCreditsOptions,
).action(async (_commandOptions, command: Command) => {
await runCommand(command, createApproval);
await runCommand(command, shareCredits);
});

applyOptions(
program
.command('revoke-approvals')
.description(
'Revokes all Turbo delegated payment approvals for given address',
),
revokeApprovalsOptions,
.command('revoke-credits')
.description('Revokes all Turbo credit share approvals for given address'),
revokeCreditsOptions,
).action(async (_commandOptions, command: Command) => {
await runCommand(command, revokeApprovals);
await runCommand(command, revokeCredits);
});

applyOptions(
program
.command('list-approvals')
.command('list-shares')
.description(
'Lists all Turbo delegated payment approvals for given address or wallet',
'Lists all given or received Turbo credit share approvals for specified address or connected wallet',
),
listApprovalsOptions,
listSharesOptions,
).action(async (_commandOptions, command: Command) => {
await runCommand(command, listApprovals);
await runCommand(command, listShares);
});

if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@
* limitations under the License.
*/
import { TurboFactory } from '../../node/factory.js';
import { ListApprovalsOptions } from '../types.js';
import { ListSharesOptions } from '../types.js';
import { addressOrPrivateKeyFromOptions, configFromOptions } from '../utils.js';

export async function listApprovals(
options: ListApprovalsOptions,
): Promise<void> {
export async function listShares(options: ListSharesOptions): Promise<void> {
const config = configFromOptions(options);
const { address, privateKey } = await addressOrPrivateKeyFromOptions(options);

Expand All @@ -28,7 +26,7 @@ export async function listApprovals(
if (address !== undefined) {
const approvals = await TurboFactory.unauthenticated(
config,
).getDelegatedPaymentApprovals({
).getCreditShareApprovals({
userAddress: address,
});
return { ...approvals, nativeAddress: address };
Expand All @@ -40,7 +38,7 @@ export async function listApprovals(
...config,
privateKey,
});
const approvals = await turbo.getDelegatedPaymentApprovals();
const approvals = await turbo.getCreditShareApprovals();
return {
...approvals,
nativeAddress: await turbo.signer.getNativeAddress(),
Expand All @@ -51,8 +49,8 @@ export async function listApprovals(
givenApprovals?.length === 0 && receivedApprovals?.length === 0;
const body = {
message:
`${hasApprovals ? 'No d' : 'D'}` +
`elegated payment approvals found for native address '${nativeAddress}'`,
`${hasApprovals ? 'No ' : ''}` +
`Credit Share Approvals found for native address '${nativeAddress}'`,
givenApprovals,
receivedApprovals,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RevokeApprovalsOptions } from '../types.js';
import { RevokeCreditsOptions } from '../types.js';
import { turboFromOptions } from '../utils.js';

export async function revokeApprovals(
options: RevokeApprovalsOptions,
export async function revokeCredits(
options: RevokeCreditsOptions,
): Promise<void> {
const { address: revokedAddress } = options;
if (revokedAddress === undefined) {
Expand All @@ -28,13 +28,13 @@ export async function revokeApprovals(

const turbo = await turboFromOptions(options);

const revokedApprovals = await turbo.revokeDelegatedPaymentApprovals({
const revokedApprovals = await turbo.revokeCredits({
revokedAddress,
});

console.log(
JSON.stringify(
{ message: 'Revoked delegated payment approvals!', revokedApprovals },
{ message: 'Revoked credit share approvals!', revokedApprovals },
null,
2,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/
import { BigNumber } from 'bignumber.js';

import { CreateApprovalOptions } from '../types.js';
import { ShareCreditsOptions } from '../types.js';
import { turboFromOptions } from '../utils.js';

export async function createApproval(
options: CreateApprovalOptions,
export async function shareCredits(
options: ShareCreditsOptions,
): Promise<void> {
const {
address: approvedAddress,
Expand All @@ -40,15 +40,15 @@ export async function createApproval(
const approvedWincAmount = new BigNumber(creditAmount)
.shiftedBy(12)
.toFixed(0);
const result = await turbo.createDelegatedPaymentApproval({
const result = await turbo.shareCredits({
approvedAddress,
approvedWincAmount,
expiresBySeconds,
});

console.log(
JSON.stringify(
{ message: 'Created delegated payment approval!', ...result },
{ message: 'Created credit share approval!', ...result },
null,
2,
),
Expand Down
10 changes: 5 additions & 5 deletions src/cli/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ export const optionMap = {
ignoreApprovals: {
alias: '--ignore-approvals',
description:
"Ignore all delegated payment approvals, only use signing wallet's balance",
"Ignore all credit share approvals, only use signing wallet's balance",
default: false,
},
useSignerBalanceFirst: {
alias: '--use-signer-balance-first',
description:
'Use the signer balance first before using delegated payment approvals',
'Use the signer balance first before using credit share approvals',
default: false,
},
} as const;
Expand Down Expand Up @@ -184,13 +184,13 @@ export const uploadFolderOptions = [

export const uploadFileOptions = [...uploadOptions, optionMap.filePath];

export const createApprovalOptions = [
export const shareCreditsOptions = [
...walletOptions,
optionMap.value,
optionMap.address,
optionMap.expiresBySeconds,
];

export const revokeApprovalsOptions = [...walletOptions, optionMap.address];
export const revokeCreditsOptions = [...walletOptions, optionMap.address];

export const listApprovalsOptions = revokeApprovalsOptions;
export const listSharesOptions = revokeCreditsOptions;
Loading

0 comments on commit 84216ef

Please sign in to comment.