From 1bcb4b72e39e29e4fffec89eeba04e85c99d64ab Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 12:28:02 -0500 Subject: [PATCH 1/8] refactor: use credit sharing in commands/methods/docs PE-6754 --- README.md | 63 ++++++++------- src/cli/cli.ts | 20 +++-- src/cli/commands/listApprovals.ts | 4 +- .../{revokeApprovals.ts => revokeCredits.ts} | 10 +-- .../{createApproval.ts => shareCredits.ts} | 10 +-- src/cli/options.ts | 4 +- src/cli/types.ts | 6 +- src/common/payment.ts | 6 +- src/common/turbo.ts | 26 +++---- src/common/upload.ts | 24 +++--- src/types.ts | 8 +- tests/approval.node.test.ts | 78 +++++++++---------- 12 files changed, 127 insertions(+), 132 deletions(-) rename src/cli/commands/{revokeApprovals.ts => revokeCredits.ts} (78%) rename src/cli/commands/{createApproval.ts => shareCredits.ts} (84%) diff --git a/README.md b/README.md index 3faa8813..4eb6c199 100644 --- a/README.md +++ b/README.md @@ -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) @@ -79,8 +79,8 @@ 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) + - [`share-credits`](#share-credits) + - [`revoke-credits`](#revoke-credits) - [`list-approvals`](#list-approvals) - [Developers](#developers) - [Requirements](#requirements) @@ -683,22 +683,21 @@ 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({ @@ -706,13 +705,13 @@ const revokedApprovals = await turbo.revokeDelegatePaymentApprovals({ }); ``` -#### `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', }); ``` @@ -782,8 +781,8 @@ Wallet options: Upload options: - `--paid-by ` - 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 @@ -896,43 +895,43 @@ 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 ` - Native address to that will receive the delegated payment approval -- `-v, --value ` - Value of winc to create delegated payment approval for -- `-e, --expires-by-seconds ` - Expiry time in seconds for the delegated payment approval +- `-a, --address ` - Native address to that will receive the Credits +- `-v, --value ` - Value of winc to share to the target address +- `-e, --expires-by-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 ` - Native address to revoke delegated payment approvals for +- `-a, --address ` - 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 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 ` - Native address to list delegated payment approvals for +- `-a, --address ` - Native address to list credit share approvals for e.g: diff --git a/src/cli/cli.ts b/src/cli/cli.ts index 5b8cbdcd..e54a5b79 100644 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -20,7 +20,6 @@ import { Command, program } from 'commander'; import { version } from '../version.js'; -import { createApproval } from './commands/createApproval.js'; import { balance, cryptoFund, @@ -30,7 +29,8 @@ import { uploadFolder, } from './commands/index.js'; import { listApprovals } from './commands/listApprovals.js'; -import { revokeApprovals } from './commands/revokeApprovals.js'; +import { revokeCredits } from './commands/revokeCredits.js'; +import { shareCredits } from './commands/shareCredits.js'; import { createApprovalOptions, globalOptions, @@ -101,29 +101,27 @@ applyOptions( applyOptions( program - .command('create-approval') - .description('Create a Turbo delegated payment approval'), + .command('share-credits') + .description('Create a Turbo credit share approval'), createApprovalOptions, ).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', - ), + .command('revoke-credits') + .description('Revokes all Turbo credit share approvals for given address'), revokeApprovalsOptions, ).action(async (_commandOptions, command: Command) => { - await runCommand(command, revokeApprovals); + await runCommand(command, revokeCredits); }); applyOptions( program .command('list-approvals') .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, ).action(async (_commandOptions, command: Command) => { diff --git a/src/cli/commands/listApprovals.ts b/src/cli/commands/listApprovals.ts index 5fccd2f8..a4af7ac7 100644 --- a/src/cli/commands/listApprovals.ts +++ b/src/cli/commands/listApprovals.ts @@ -28,7 +28,7 @@ export async function listApprovals( if (address !== undefined) { const approvals = await TurboFactory.unauthenticated( config, - ).getDelegatedPaymentApprovals({ + ).getCreditShareApprovals({ userAddress: address, }); return { ...approvals, nativeAddress: address }; @@ -40,7 +40,7 @@ export async function listApprovals( ...config, privateKey, }); - const approvals = await turbo.getDelegatedPaymentApprovals(); + const approvals = await turbo.getCreditShareApprovals(); return { ...approvals, nativeAddress: await turbo.signer.getNativeAddress(), diff --git a/src/cli/commands/revokeApprovals.ts b/src/cli/commands/revokeCredits.ts similarity index 78% rename from src/cli/commands/revokeApprovals.ts rename to src/cli/commands/revokeCredits.ts index 48959d58..82bd7ad6 100644 --- a/src/cli/commands/revokeApprovals.ts +++ b/src/cli/commands/revokeCredits.ts @@ -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 { const { address: revokedAddress } = options; if (revokedAddress === undefined) { @@ -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, ), diff --git a/src/cli/commands/createApproval.ts b/src/cli/commands/shareCredits.ts similarity index 84% rename from src/cli/commands/createApproval.ts rename to src/cli/commands/shareCredits.ts index ba797c4a..1e76ff94 100644 --- a/src/cli/commands/createApproval.ts +++ b/src/cli/commands/shareCredits.ts @@ -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 { const { address: approvedAddress, @@ -40,7 +40,7 @@ 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, @@ -48,7 +48,7 @@ export async function createApproval( console.log( JSON.stringify( - { message: 'Created delegated payment approval!', ...result }, + { message: 'Created credit share approval!', ...result }, null, 2, ), diff --git a/src/cli/options.ts b/src/cli/options.ts index 7b82b7cd..fef0dc71 100644 --- a/src/cli/options.ts +++ b/src/cli/options.ts @@ -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; diff --git a/src/cli/types.ts b/src/cli/types.ts index 4123b477..ea5d7b2d 100644 --- a/src/cli/types.ts +++ b/src/cli/types.ts @@ -69,14 +69,14 @@ export type CryptoFundOptions = WalletOptions & { txId: string | undefined; }; -export type CreateApprovalOptions = WalletOptions & { +export type ShareCreditsOptions = WalletOptions & { address: string | undefined; value: string | undefined; expiresBySeconds: number | undefined; }; -export type RevokeApprovalsOptions = WalletOptions & { +export type RevokeCreditsOptions = WalletOptions & { address: string | undefined; }; -export type ListApprovalsOptions = RevokeApprovalsOptions; +export type ListApprovalsOptions = RevokeCreditsOptions; diff --git a/src/common/payment.ts b/src/common/payment.ts index b7709206..a3ff9e6d 100644 --- a/src/common/payment.ts +++ b/src/common/payment.ts @@ -265,7 +265,7 @@ export class TurboUnauthenticatedPaymentService throw new Error('Unknown response from payment service: ' + response); } - public async getDelegatedPaymentApprovals({ + public async getCreditShareApprovals({ userAddress, }: { userAddress: UserAddress; @@ -314,13 +314,13 @@ export class TurboAuthenticatedPaymentService return super.getBalance(userAddress); } - public async getDelegatedPaymentApprovals({ + public async getCreditShareApprovals({ userAddress, }: { userAddress?: string; }): Promise { userAddress ??= await this.signer.getNativeAddress(); - return super.getDelegatedPaymentApprovals({ userAddress }); + return super.getCreditShareApprovals({ userAddress }); } public async getWincForFiat({ diff --git a/src/common/turbo.ts b/src/common/turbo.ts index 621182dd..5cd3483d 100644 --- a/src/common/turbo.ts +++ b/src/common/turbo.ts @@ -213,12 +213,12 @@ export class TurboUnauthenticatedClient } /** - * Returns a list of all delegated payment approvals for the user. + * Returns a list of all credit share approvals for the user. */ - getDelegatedPaymentApprovals(p: { + getCreditShareApprovals(p: { userAddress: NativeAddress; }): Promise { - return this.paymentService.getDelegatedPaymentApprovals(p); + return this.paymentService.getCreditShareApprovals(p); } } @@ -248,14 +248,14 @@ export class TurboAuthenticatedClient } /** - * Returns a list of all delegated payment approvals for the user. + * Returns a list of all credit share approvals for the user. */ - getDelegatedPaymentApprovals( + getCreditShareApprovals( p: { userAddress?: NativeAddress; } = {}, ): Promise { - return this.paymentService.getDelegatedPaymentApprovals(p); + return this.paymentService.getCreditShareApprovals(p); } /** @@ -291,25 +291,25 @@ export class TurboAuthenticatedClient } /** - * Creates a data item with tags that designate it as a delegated payment approval. + * Creates a data item with tags that designate it as a credit share approval. * Signs the data item and sends it to the Turbo Upload Service, which will verify * the signature and forward the admin action towards the Turbo Payment Service. */ - createDelegatedPaymentApproval( + shareCredits( p: TurboCreateDelegatedPaymentApprovalParams, ): Promise { - return this.uploadService.createDelegatedPaymentApproval(p); + return this.uploadService.shareCredits(p); } /** - * Creates a data item with tags that designate it as a revoke action for delegated - * payment approvals for target revokedAddress. Signs the data item and sends it to + * Creates a data item with tags that designate it as a revoke action for credit + * share approvals for target revokedAddress. Signs the data item and sends it to * the Turbo Upload Service, which will verify the signature and forward the admin * action towards the Turbo Payment Service. */ - revokeDelegatedPaymentApprovals( + revokeCredits( p: TurboRevokeDelegatePaymentApprovalsParams, ): Promise { - return this.uploadService.revokeDelegatedPaymentApprovals(p); + return this.uploadService.revokeCredits(p); } } diff --git a/src/common/upload.ts b/src/common/upload.ts index e600251a..01446664 100644 --- a/src/common/upload.ts +++ b/src/common/upload.ts @@ -40,11 +40,11 @@ import { import { TurboHTTPService } from './http.js'; import { TurboWinstonLogger } from './logger.js'; -export const delegatedPaymentTagNames = { - createDelegatedPaymentApproval: 'x-approve-payment', - approvalAmount: 'x-amount', +export const creditSharingTagNames = { + shareCredits: 'x-approve-payment', + sharedWincAmount: 'x-amount', approvalExpiresBySeconds: 'x-expires-seconds', - revokeDelegatePaymentApproval: 'x-delete-payment-approval', + revokeCredits: 'x-delete-payment-approval', }; export const developmentUploadServiceURL = 'https://upload.ardrive.dev'; @@ -318,7 +318,7 @@ export abstract class TurboAuthenticatedBaseUploadService }; } - public async createDelegatedPaymentApproval({ + public async shareCredits({ approvedAddress, approvedWincAmount, expiresBySeconds, @@ -326,18 +326,18 @@ export abstract class TurboAuthenticatedBaseUploadService const dataItemOpts = { tags: [ { - name: delegatedPaymentTagNames.createDelegatedPaymentApproval, + name: creditSharingTagNames.shareCredits, value: approvedAddress, }, { - name: delegatedPaymentTagNames.approvalAmount, + name: creditSharingTagNames.sharedWincAmount, value: approvedWincAmount.toString(), }, ], }; if (expiresBySeconds !== undefined) { dataItemOpts.tags.push({ - name: delegatedPaymentTagNames.approvalExpiresBySeconds, + name: creditSharingTagNames.approvalExpiresBySeconds, value: expiresBySeconds.toString(), }); } @@ -352,14 +352,14 @@ export abstract class TurboAuthenticatedBaseUploadService }); if (!createdApproval) { throw new Error( - 'Failed to create delegated payment approval but upload has succeeded\n' + + 'Failed to create credit share approval but upload has succeeded\n' + JSON.stringify(uploadResponse), ); } return createdApproval; } - public async revokeDelegatedPaymentApprovals({ + public async revokeCredits({ revokedAddress, }: TurboRevokeDelegatePaymentApprovalsParams): Promise< DelegatedPaymentApproval[] @@ -367,7 +367,7 @@ export abstract class TurboAuthenticatedBaseUploadService const dataItemOpts = { tags: [ { - name: delegatedPaymentTagNames.revokeDelegatePaymentApproval, + name: creditSharingTagNames.revokeCredits, value: revokedAddress, }, ], @@ -381,7 +381,7 @@ export abstract class TurboAuthenticatedBaseUploadService }); if (!revokedApprovals) { throw new Error( - 'Failed to revoke delegated payment approvals but upload has succeeded\n' + + 'Failed to revoke credit share approvals but upload has succeeded\n' + JSON.stringify(uploadResponse), ); } diff --git a/src/types.ts b/src/types.ts index 6c1e9806..7a5aacaa 100644 --- a/src/types.ts +++ b/src/types.ts @@ -587,7 +587,7 @@ export interface TurboUnauthenticatedPaymentServiceInterface { submitFundTransaction(p: { txId: string; }): Promise; - getDelegatedPaymentApprovals(p: { + getCreditShareApprovals(p: { userAddress: UserAddress; }): Promise; } @@ -602,7 +602,7 @@ export interface TurboAuthenticatedPaymentServiceInterface extends TurboUnauthenticatedPaymentServiceInterface { getBalance: (userAddress?: UserAddress) => Promise; - getDelegatedPaymentApprovals(p: { + getCreditShareApprovals(p: { userAddress?: UserAddress; }): Promise; @@ -628,11 +628,11 @@ export interface TurboAuthenticatedUploadServiceInterface uploadFolder(p: TurboUploadFolderParams): Promise; - createDelegatedPaymentApproval( + shareCredits( p: TurboCreateDelegatedPaymentApprovalParams, ): Promise; - revokeDelegatedPaymentApprovals( + revokeCredits( p: TurboRevokeDelegatePaymentApprovalsParams, ): Promise; } diff --git a/tests/approval.node.test.ts b/tests/approval.node.test.ts index db4e45cf..205f4246 100644 --- a/tests/approval.node.test.ts +++ b/tests/approval.node.test.ts @@ -63,13 +63,12 @@ describe('Delegated Payments', () => { let oldestApprovalId: string; - describe('createDelegatedPaymentApproval', () => { - it('should properly create a delegated payment approval', async () => { - const { approvalDataItemId, payingAddress } = - await turbo.createDelegatedPaymentApproval({ - approvedWincAmount: '100', - approvedAddress: unfundedSignerAddress1, - }); + describe('shareCredits', () => { + it('should properly create a credit share approval', async () => { + const { approvalDataItemId, payingAddress } = await turbo.shareCredits({ + approvedWincAmount: '100', + approvedAddress: unfundedSignerAddress1, + }); oldestApprovalId = approvalDataItemId; expect(approvalDataItemId).to.be.a('string'); expect(payingAddress).to.equal(arweavePayerAddress); @@ -90,13 +89,12 @@ describe('Delegated Payments', () => { expect(receivedApprovals).to.have.length(0); }); - it('should properly create a delegated payment approval with expiration, and the approval should expire as expected', async () => { - const { approvalDataItemId, payingAddress } = - await turbo.createDelegatedPaymentApproval({ - approvedWincAmount: '100', - approvedAddress: unfundedSignerAddress1, - expiresBySeconds: 1, - }); + it('should properly create a credit share approval with expiration, and the approval should expire as expected', async () => { + const { approvalDataItemId, payingAddress } = await turbo.shareCredits({ + approvedWincAmount: '100', + approvedAddress: unfundedSignerAddress1, + expiresBySeconds: 1, + }); expect(approvalDataItemId).to.be.a('string'); expect(payingAddress).to.equal(arweavePayerAddress); @@ -134,23 +132,23 @@ describe('Delegated Payments', () => { it('should fail to create payment approvals to invalid addresses', async () => { await expectAsyncErrorThrow({ - promiseToError: turbo.createDelegatedPaymentApproval({ + promiseToError: turbo.shareCredits({ approvedWincAmount: '100', approvedAddress: 'invalidAddress', }), errorMessage: - 'Failed request: 400: Unable to create delegated payment approval : Invalid approved address', + 'Failed request: 400: Unable to create credit share approval : Invalid approved address', errorType: 'FailedRequestError', }); }); it('should fail to create payment approvals when payer has insufficient balance for approval', async () => { await expectAsyncErrorThrow({ - promiseToError: turbo.createDelegatedPaymentApproval({ + promiseToError: turbo.shareCredits({ approvedWincAmount: '10000', approvedAddress: unfundedSignerAddress1, }), - errorMessage: `Failed request: 400: Unable to create delegated payment approval : Insufficient balance for '${arweavePayerAddress}'`, + errorMessage: `Failed request: 400: Unable to create credit share approval : Insufficient balance for '${arweavePayerAddress}'`, errorType: 'FailedRequestError', }); }); @@ -164,40 +162,40 @@ describe('Delegated Payments', () => { owner: 'owner', }); await expectAsyncErrorThrow({ - promiseToError: turbo.createDelegatedPaymentApproval({ + promiseToError: turbo.shareCredits({ approvedAddress: 'stub-43-char-address-stub-43-char-address-0', approvedWincAmount: '100', }), - errorMessage: `Failed to create delegated payment approval but upload has succeeded\n{"winc":"100","dataCaches":[],"fastFinalityIndexes":[],"id":"id","owner":"owner"}`, + errorMessage: `Failed to create credit share approval but upload has succeeded\n{"winc":"100","dataCaches":[],"fastFinalityIndexes":[],"id":"id","owner":"owner"}`, errorType: 'Error', }); }); }); - describe('getDelegatedPaymentApprovals', () => { - it('should properly get all delegated payment approvals for given signer -- sorted by expiration date first, then by creation date', async () => { + describe('getCreditShareApprovals', () => { + it('should properly get all credit share approvals for given signer -- sorted by expiration date first, then by creation date', async () => { const newApprovalWithNoExpirationId = ( - await turbo.createDelegatedPaymentApproval({ + await turbo.shareCredits({ approvedWincAmount: '100', approvedAddress: unfundedSignerAddress1, }) ).approvalDataItemId; const approvalWithFarExpirationId = ( - await turbo.createDelegatedPaymentApproval({ + await turbo.shareCredits({ approvedWincAmount: '100', approvedAddress: unfundedSignerAddress1, expiresBySeconds: 10000, }) ).approvalDataItemId; const approvalWithNearExpirationId = ( - await turbo.createDelegatedPaymentApproval({ + await turbo.shareCredits({ approvedWincAmount: '100', approvedAddress: unfundedSignerAddress1, expiresBySeconds: 10, }) ).approvalDataItemId; - const { givenApprovals } = await turbo.getDelegatedPaymentApprovals(); + const { givenApprovals } = await turbo.getCreditShareApprovals(); expect(givenApprovals).to.have.length(4); expect(givenApprovals[0].approvalDataItemId).to.equal( approvalWithNearExpirationId, @@ -211,22 +209,22 @@ describe('Delegated Payments', () => { ); }); - it('should properly get delegated payment approvals when no approvals are present', async () => { + it('should properly get credit share approvals when no approvals are present', async () => { const { givenApprovals } = await TurboFactory.unauthenticated( {}, - ).getDelegatedPaymentApprovals({ + ).getCreditShareApprovals({ userAddress: 'stub-43-char-address-stub-43-char-address-0', }); expect(givenApprovals).to.have.length(0); }); }); - describe('revokeDelegatedPaymentApprovals', () => { - it('should properly revoke all delegated payment approvals for given address', async () => { + describe('revokeCredits', () => { + it('should properly revoke all credit share approvals for given address', async () => { const { givenApprovals } = await turbo.getBalance(); expect(givenApprovals).to.have.length(4); - await turbo.revokeDelegatedPaymentApprovals({ + await turbo.revokeCredits({ revokedAddress: unfundedSignerAddress1, }); @@ -234,13 +232,13 @@ describe('Delegated Payments', () => { expect(givenApprovalsLater).to.have.length(0); }); - it('should fail to revoke if there are no delegated payment approvals for given address', async () => { + it('should fail to revoke if there are no credit share approvals for given address', async () => { await expectAsyncErrorThrow({ - promiseToError: turbo.revokeDelegatedPaymentApprovals({ + promiseToError: turbo.revokeCredits({ revokedAddress: 'stub-43-char-address-stub-43-char-address-0', }), errorMessage: - 'Failed request: 400: Unable to revoke delegated payment approval !', + 'Failed request: 400: Unable to revoke credit share approval !', errorType: 'FailedRequestError', }); }); @@ -254,17 +252,17 @@ describe('Delegated Payments', () => { owner: 'owner', }); await expectAsyncErrorThrow({ - promiseToError: turbo.revokeDelegatedPaymentApprovals({ + promiseToError: turbo.revokeCredits({ revokedAddress: 'stub-43-char-address-stub-43-char-address-0', }), errorMessage: - 'Failed to revoke delegated payment approvals but upload has succeeded\n{"winc":"100","dataCaches":[],"fastFinalityIndexes":[],"id":"id","owner":"owner"}', + 'Failed to revoke credit share approvals but upload has succeeded\n{"winc":"100","dataCaches":[],"fastFinalityIndexes":[],"id":"id","owner":"owner"}', errorType: 'Error', }); }); }); - describe('using delegated payment approvals', () => { + describe('using credit share approvals', () => { let signerJwk: JWKInterface; let payingJwk: JWKInterface; @@ -296,7 +294,7 @@ describe('Delegated Payments', () => { txId: id, }); - await payingTurbo.createDelegatedPaymentApproval({ + await payingTurbo.shareCredits({ approvedWincAmount: 766_000_000_000, approvedAddress: signerAddress, }); @@ -312,7 +310,7 @@ describe('Delegated Payments', () => { const filePath = new URL('files/1MB_file', import.meta.url).pathname; const fileSize = statSync(filePath).size; - it('should properly use a delegated payment approvals to upload data when paid-by is provided', async () => { + it('should properly use a credit share approvals to upload data when paid-by is provided', async () => { const { winc } = await signerTurbo.uploadFile({ dataItemOpts: { paidBy: payingAddress }, fileStreamFactory: () => createReadStream(filePath), @@ -330,7 +328,7 @@ describe('Delegated Payments', () => { expect(+signerBalance.effectiveBalance).to.equal(766_000_000_000 - +winc); }); - it('should properly use a delegated payment approvals to upload data when multiple paid-bys are provided', async () => { + it('should properly use a credit share approvals to upload data when multiple paid-bys are provided', async () => { const payerBalance = await payingTurbo.getBalance(); const { winc } = await signerTurbo.uploadFile({ From 1e5872e16019676203557b384a96f5122585aac0 Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 12:33:20 -0500 Subject: [PATCH 2/8] test: update error case from API expectation PE-6754 --- tests/approval.node.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/approval.node.test.ts b/tests/approval.node.test.ts index 205f4246..009bea3c 100644 --- a/tests/approval.node.test.ts +++ b/tests/approval.node.test.ts @@ -137,7 +137,7 @@ describe('Delegated Payments', () => { approvedAddress: 'invalidAddress', }), errorMessage: - 'Failed request: 400: Unable to create credit share approval : Invalid approved address', + 'Failed request: 400: Unable to create delegated payment approval : Invalid approved address', errorType: 'FailedRequestError', }); }); @@ -148,7 +148,7 @@ describe('Delegated Payments', () => { approvedWincAmount: '10000', approvedAddress: unfundedSignerAddress1, }), - errorMessage: `Failed request: 400: Unable to create credit share approval : Insufficient balance for '${arweavePayerAddress}'`, + errorMessage: `Failed request: 400: Unable to create delegated payment approval : Insufficient balance for '${arweavePayerAddress}'`, errorType: 'FailedRequestError', }); }); @@ -238,7 +238,7 @@ describe('Delegated Payments', () => { revokedAddress: 'stub-43-char-address-stub-43-char-address-0', }), errorMessage: - 'Failed request: 400: Unable to revoke credit share approval !', + 'Failed request: 400: Unable to revoke delegated payment approval !', errorType: 'FailedRequestError', }); }); From 9166e7405754b22f29e75d4e665bd13fca6830b5 Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 12:37:06 -0500 Subject: [PATCH 3/8] refactor: use list-shares, update options to "sharing" PE-6754 --- README.md | 6 +++--- src/cli/cli.ts | 18 +++++++++--------- .../{listApprovals.ts => listShares.ts} | 6 ++---- src/cli/options.ts | 6 +++--- src/cli/types.ts | 2 +- 5 files changed, 18 insertions(+), 20 deletions(-) rename src/cli/commands/{listApprovals.ts => listShares.ts} (93%) diff --git a/README.md b/README.md index 4eb6c199..a3b1a1f8 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac - [`price`](#price) - [`share-credits`](#share-credits) - [`revoke-credits`](#revoke-credits) - - [`list-approvals`](#list-approvals) + - [`list-shares`](#list-shares) - [Developers](#developers) - [Requirements](#requirements) - [Setup & Build](#setup--build) @@ -925,7 +925,7 @@ e.g: turbo revoke-credits --wallet-file ../path/to/my/wallet ``` -##### `list-approvals` +##### `list-shares` List all given and received credit share approvals from the connected wallet or the provided native address. @@ -936,7 +936,7 @@ Command Options: 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 ``` ## Developers diff --git a/src/cli/cli.ts b/src/cli/cli.ts index e54a5b79..91679673 100644 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -28,15 +28,15 @@ import { uploadFile, uploadFolder, } from './commands/index.js'; -import { listApprovals } from './commands/listApprovals.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, @@ -103,7 +103,7 @@ applyOptions( program .command('share-credits') .description('Create a Turbo credit share approval'), - createApprovalOptions, + shareCreditsOptions, ).action(async (_commandOptions, command: Command) => { await runCommand(command, shareCredits); }); @@ -112,20 +112,20 @@ applyOptions( program .command('revoke-credits') .description('Revokes all Turbo credit share approvals for given address'), - revokeApprovalsOptions, + revokeCreditsOptions, ).action(async (_commandOptions, command: Command) => { await runCommand(command, revokeCredits); }); applyOptions( program - .command('list-approvals') + .command('list-shares') .description( '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 ( diff --git a/src/cli/commands/listApprovals.ts b/src/cli/commands/listShares.ts similarity index 93% rename from src/cli/commands/listApprovals.ts rename to src/cli/commands/listShares.ts index a4af7ac7..7edda627 100644 --- a/src/cli/commands/listApprovals.ts +++ b/src/cli/commands/listShares.ts @@ -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 { +export async function listShares(options: ListSharesOptions): Promise { const config = configFromOptions(options); const { address, privateKey } = await addressOrPrivateKeyFromOptions(options); diff --git a/src/cli/options.ts b/src/cli/options.ts index fef0dc71..f038fdd8 100644 --- a/src/cli/options.ts +++ b/src/cli/options.ts @@ -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; diff --git a/src/cli/types.ts b/src/cli/types.ts index ea5d7b2d..24613653 100644 --- a/src/cli/types.ts +++ b/src/cli/types.ts @@ -79,4 +79,4 @@ export type RevokeCreditsOptions = WalletOptions & { address: string | undefined; }; -export type ListApprovalsOptions = RevokeCreditsOptions; +export type ListSharesOptions = RevokeCreditsOptions; From fbe2880eafc052866f00760ccf57bde6fabde68e Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 12:47:22 -0500 Subject: [PATCH 4/8] refactor: update DelegatedPaymentApproval to CreditShareApproval PE-6754 --- src/common/payment.ts | 8 ++--- src/common/turbo.ts | 20 ++++++------ src/common/upload.ts | 12 +++---- src/types.ts | 32 +++++++++---------- ...ode.test.ts => creditSharing.node.test.ts} | 2 +- 5 files changed, 34 insertions(+), 40 deletions(-) rename tests/{approval.node.test.ts => creditSharing.node.test.ts} (99%) diff --git a/src/common/payment.ts b/src/common/payment.ts index a3ff9e6d..afd053e7 100644 --- a/src/common/payment.ts +++ b/src/common/payment.ts @@ -18,7 +18,7 @@ import { Buffer } from 'node:buffer'; import { Currency, - GetDelegatedPaymentApprovalsResponse, + GetCreditShareApprovalsResponse, RawWincForTokenResponse, TokenTools, TokenType, @@ -269,9 +269,9 @@ export class TurboUnauthenticatedPaymentService userAddress, }: { userAddress: UserAddress; - }): Promise { + }): Promise { const response = await this.httpService.get< - GetDelegatedPaymentApprovalsResponse | undefined + GetCreditShareApprovalsResponse | undefined >({ endpoint: `/account/approvals/get?userAddress=${userAddress}`, allowedStatuses: [200, 404], @@ -318,7 +318,7 @@ export class TurboAuthenticatedPaymentService userAddress, }: { userAddress?: string; - }): Promise { + }): Promise { userAddress ??= await this.signer.getNativeAddress(); return super.getCreditShareApprovals({ userAddress }); } diff --git a/src/common/turbo.ts b/src/common/turbo.ts index 5cd3483d..7b79e75a 100644 --- a/src/common/turbo.ts +++ b/src/common/turbo.ts @@ -14,9 +14,9 @@ * limitations under the License. */ import { + CreditShareApproval, Currency, - DelegatedPaymentApproval, - GetDelegatedPaymentApprovalsResponse, + GetCreditShareApprovalsResponse, NativeAddress, TokenType, TurboAbortSignal, @@ -28,7 +28,7 @@ import { TurboCheckoutSessionParams, TurboCheckoutSessionResponse, TurboCountriesResponse, - TurboCreateDelegatedPaymentApprovalParams, + TurboCreateCreditShareApprovalParams, TurboCryptoFundResponse, TurboCurrenciesResponse, TurboDataItemSigner, @@ -37,7 +37,7 @@ import { TurboFundWithTokensParams, TurboPriceResponse, TurboRatesResponse, - TurboRevokeDelegatePaymentApprovalsParams, + TurboRevokeCreditsParams, TurboSignedDataItemFactory, TurboSubmitFundTxResponse, TurboUnauthenticatedClientConfiguration, @@ -217,7 +217,7 @@ export class TurboUnauthenticatedClient */ getCreditShareApprovals(p: { userAddress: NativeAddress; - }): Promise { + }): Promise { return this.paymentService.getCreditShareApprovals(p); } } @@ -254,7 +254,7 @@ export class TurboAuthenticatedClient p: { userAddress?: NativeAddress; } = {}, - ): Promise { + ): Promise { return this.paymentService.getCreditShareApprovals(p); } @@ -296,8 +296,8 @@ export class TurboAuthenticatedClient * the signature and forward the admin action towards the Turbo Payment Service. */ shareCredits( - p: TurboCreateDelegatedPaymentApprovalParams, - ): Promise { + p: TurboCreateCreditShareApprovalParams, + ): Promise { return this.uploadService.shareCredits(p); } @@ -307,9 +307,7 @@ export class TurboAuthenticatedClient * the Turbo Upload Service, which will verify the signature and forward the admin * action towards the Turbo Payment Service. */ - revokeCredits( - p: TurboRevokeDelegatePaymentApprovalsParams, - ): Promise { + revokeCredits(p: TurboRevokeCreditsParams): Promise { return this.uploadService.revokeCredits(p); } } diff --git a/src/common/upload.ts b/src/common/upload.ts index 01446664..1f9b0524 100644 --- a/src/common/upload.ts +++ b/src/common/upload.ts @@ -19,17 +19,17 @@ import { pLimit } from 'plimit-lit'; import { ArweaveManifest, + CreditShareApproval, DataItemOptions, - DelegatedPaymentApproval, TokenType, TurboAbortSignal, TurboAuthenticatedUploadServiceConfiguration, TurboAuthenticatedUploadServiceInterface, - TurboCreateDelegatedPaymentApprovalParams, + TurboCreateCreditShareApprovalParams, TurboDataItemSigner, TurboFileFactory, TurboLogger, - TurboRevokeDelegatePaymentApprovalsParams, + TurboRevokeCreditsParams, TurboSignedDataItemFactory, TurboUnauthenticatedUploadServiceConfiguration, TurboUnauthenticatedUploadServiceInterface, @@ -322,7 +322,7 @@ export abstract class TurboAuthenticatedBaseUploadService approvedAddress, approvedWincAmount, expiresBySeconds, - }: TurboCreateDelegatedPaymentApprovalParams): Promise { + }: TurboCreateCreditShareApprovalParams): Promise { const dataItemOpts = { tags: [ { @@ -361,9 +361,7 @@ export abstract class TurboAuthenticatedBaseUploadService public async revokeCredits({ revokedAddress, - }: TurboRevokeDelegatePaymentApprovalsParams): Promise< - DelegatedPaymentApproval[] - > { + }: TurboRevokeCreditsParams): Promise { const dataItemOpts = { tags: [ { diff --git a/src/types.ts b/src/types.ts index 7a5aacaa..5ee78bbb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -155,7 +155,7 @@ export type TurboCheckoutSessionResponse = TurboWincForFiatResponse & { paymentAmount: number; }; -export interface DelegatedPaymentApproval { +export interface CreditShareApproval { approvalDataItemId: TransactionId; approvedAddress: UserAddress; payingAddress: UserAddress; @@ -165,9 +165,9 @@ export interface DelegatedPaymentApproval { expirationDate: string | undefined; } -export interface GetDelegatedPaymentApprovalsResponse { - givenApprovals: DelegatedPaymentApproval[]; - receivedApprovals: DelegatedPaymentApproval[]; +export interface GetCreditShareApprovalsResponse { + givenApprovals: CreditShareApproval[]; + receivedApprovals: CreditShareApproval[]; } export type TurboBalanceResponse = { @@ -186,8 +186,8 @@ export type TurboBalanceResponse = { */ effectiveBalance: string; - receivedApprovals: DelegatedPaymentApproval[]; - givenApprovals: DelegatedPaymentApproval[]; + receivedApprovals: CreditShareApproval[]; + givenApprovals: CreditShareApproval[]; }; export type TurboFiatToArResponse = { @@ -207,8 +207,8 @@ export type TurboUploadDataItemResponse = { id: TransactionId; owner: PublicArweaveAddress; winc: string; - createdApproval?: DelegatedPaymentApproval; - revokedApprovals?: DelegatedPaymentApproval[]; + createdApproval?: CreditShareApproval; + revokedApprovals?: CreditShareApproval[]; }; type UploadFolderParams = { @@ -240,13 +240,13 @@ export const isWebUploadFolderParams = ( ): p is WebUploadFolderParams => (p as WebUploadFolderParams).files !== undefined; -export type TurboCreateDelegatedPaymentApprovalParams = { +export type TurboCreateCreditShareApprovalParams = { approvedAddress: string; approvedWincAmount: BigNumber.Value; expiresBySeconds?: number; }; -export type TurboRevokeDelegatePaymentApprovalsParams = { +export type TurboRevokeCreditsParams = { revokedAddress: string; }; @@ -589,7 +589,7 @@ export interface TurboUnauthenticatedPaymentServiceInterface { }): Promise; getCreditShareApprovals(p: { userAddress: UserAddress; - }): Promise; + }): Promise; } export type TurboFundWithTokensParams = { @@ -604,7 +604,7 @@ export interface TurboAuthenticatedPaymentServiceInterface getCreditShareApprovals(p: { userAddress?: UserAddress; - }): Promise; + }): Promise; topUpWithTokens( p: TurboFundWithTokensParams, @@ -629,12 +629,10 @@ export interface TurboAuthenticatedUploadServiceInterface uploadFolder(p: TurboUploadFolderParams): Promise; shareCredits( - p: TurboCreateDelegatedPaymentApprovalParams, - ): Promise; + p: TurboCreateCreditShareApprovalParams, + ): Promise; - revokeCredits( - p: TurboRevokeDelegatePaymentApprovalsParams, - ): Promise; + revokeCredits(p: TurboRevokeCreditsParams): Promise; } export interface TurboUnauthenticatedClientInterface diff --git a/tests/approval.node.test.ts b/tests/creditSharing.node.test.ts similarity index 99% rename from tests/approval.node.test.ts rename to tests/creditSharing.node.test.ts index 009bea3c..f9cbc04e 100644 --- a/tests/approval.node.test.ts +++ b/tests/creditSharing.node.test.ts @@ -18,7 +18,7 @@ import { turboDevelopmentConfigurations, } from './helpers.js'; -describe('Delegated Payments', () => { +describe('Credit Sharing', () => { afterEach(() => { // Restore all stubs restore(); From 43c3e2ea4564555baede78215370c9a7aca267c1 Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 13:20:45 -0500 Subject: [PATCH 5/8] docs: add turbo credit sharing section in README PE-6754 --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a3b1a1f8..9edc1662 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac - [`share-credits`](#share-credits) - [`revoke-credits`](#revoke-credits) - [`list-shares`](#list-shares) +- [Credit Sharing](#credit-sharing) - [Developers](#developers) - [Requirements](#requirements) - [Setup & Build](#setup--build) @@ -700,7 +701,7 @@ const { approvalDataItemId, approvedWincAmount } = await turbo.shareCredits({ 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', }); ``` @@ -939,6 +940,32 @@ e.g: 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 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. + +Approvals can be revoked at any time by similarly uploading a signed data item with 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 `: 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 From acaea67ca742c29002f995c900420a4478818ea9 Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 14:12:39 -0500 Subject: [PATCH 6/8] docs: update credit sharing section in README PE-6754 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9edc1662..9e3a2ad2 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac - [`share-credits`](#share-credits) - [`revoke-credits`](#revoke-credits) - [`list-shares`](#list-shares) -- [Credit Sharing](#credit-sharing) +- [Turbo Credit Sharing](#turbo-credit-sharing) - [Developers](#developers) - [Requirements](#requirements) - [Setup & Build](#setup--build) @@ -944,6 +944,8 @@ turbo list-shares --address 2cor...VUa --wallet-file ../path/to/my/wallet 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 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 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. From 2e81aafcc38d7a44a1f488fb84689406a14bee75 Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 14:16:51 -0500 Subject: [PATCH 7/8] docs: update credit sharing section in README PE-6754 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e3a2ad2..bae2c699 100644 --- a/README.md +++ b/README.md @@ -942,11 +942,11 @@ 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 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. +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 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. +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. From b2acf6a05f4333172ef57dedb3eceb4d8a486873 Mon Sep 17 00:00:00 2001 From: Derek Sonnenberg Date: Fri, 1 Nov 2024 15:05:37 -0500 Subject: [PATCH 8/8] refactor: update list-share message for Credit Share Approvals PE-6754 --- src/cli/commands/listShares.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli/commands/listShares.ts b/src/cli/commands/listShares.ts index 7edda627..f80ad57c 100644 --- a/src/cli/commands/listShares.ts +++ b/src/cli/commands/listShares.ts @@ -49,8 +49,8 @@ export async function listShares(options: ListSharesOptions): Promise { 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, };