Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HIP-904 Frictionless Airdrops design #8127

Merged
merged 12 commits into from
May 9, 2024
171 changes: 171 additions & 0 deletions docs/design/frictionless-airdrops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# HIP-336 Approval and Allowance
xin-hedera marked this conversation as resolved.
Show resolved Hide resolved

## Purpose

[HIP-904](https://hips.hedera.com/hip/hip-904) enables frictionless airdrops of both fungible and non-fungible tokens by removing the requirement to pre-associate tokens with the receiver’s account.

## Goals

- Ingest `TokenAirdrop` transactions and persist to the database
- Ingest `PendingAirdrop` transactions and persist to the database
- Ingest `TokenCancelAirdrop` and `TokenClaimAirdrop` transactions and remove entries from the database
edwin-greene marked this conversation as resolved.
Show resolved Hide resolved
- Ingest `TokenReject` transactions and persist to the database
- Expose Pending Airdrop information via the Java REST API

## Non-Goals

- Support for historical airdrop information
- Enhance gRPC APIs with Pending Airdrop information
- Enhance Web3 APIs with Pending Airdrop information
edwin-greene marked this conversation as resolved.
Show resolved Hide resolved

## Architecture

### Database

#### Pending Airdrops

```sql
create table if not exists pending_airdrop
(
account_id bigint not null,
amount bigint
payer_account_id bigint not null,
serial_number bigint
token_id bigint not null
primary key (account_id, payer_account_id, token_id)
);
xin-hedera marked this conversation as resolved.
Show resolved Hide resolved

create index if not exists pending__airdrop on pending_airdrop (account_id, payer_account_id);
```

edwin-greene marked this conversation as resolved.
Show resolved Hide resolved
### Importer

#### Pending Airdrop Parsing

When parsing pending airdrops,

- Persist pending airdrops to the `pending_airdrop` table.
- If a pending airdrop entry already exists, the new amount should be added to the existing amount.

#### Domain

- Add an `TokenAirdrop` domain object with the same fields as `CryptoTransfer`.
- Add an `TokenCancelAirdrop` domain object which contains the fields `accountId`, `payerAccountId`, `tokenId`, and `serialNumber`.
- Add an `TokenClaimAirdrop` domain object which contains the fields `accountId`, `payerAccountId`, `tokenId`, and `serialNumber`.
- Add an `TokenReject` domain object which contains the fields `accountId`, `tokenId`, and `serialNumber`.
- Add an `PendingAirdrop` domain object with the same fields as the schema.

#### Entity Listener

- Add `onCancelAirdrop` to handle deletes from the `pending_airdrop` table.
- Add `onClaimAirdrop` to handle deletes from the `pending_airdrop` table.
- Add `onPendingAirdrop` to handle inserts to the `pending_airdrop` table.
- Add `onTokenReject` which will be similar to `onCryptoTransfer` except the balance will be zero.
- Add `onTokenAirdrop` which will be similar to `onCryptoTransfer`.
edwin-greene marked this conversation as resolved.
Show resolved Hide resolved

#### Transaction Handlers

- Add `TokenAirdropTransactionHandler` which will be similar to `CryptoTransferTransactionHandler`
- Add `TokenCancelAirdropTransactionHandler`
- Add `TokenClaimAirdropTransactionHandler`
- Add `TokenRejectTransactionHandler` which will be similar to `CryptoTransferTransactionHandler`
- Add `PendingAirdropTransactionHandler`

#### Batch Deletion

- Add a batch deletion velocity template to be used by Claim airdrop and Cancel airdrop.
- Add a `GenericDeleteQueryGenerator` to be used for batch deletion.

### REST API

- Add the new endpoints to Java REST.
steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved
steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved

#### List of outstanding airdrops sent by senderIdOrEvmAddress which have not been claimed by recipients
steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved

`/api/v1/accounts/{senderIdOrEvmAddress}/airdrops/outstanding`
edwin-greene marked this conversation as resolved.
Show resolved Hide resolved

```json
{
"airdrops": [
{
"amount": 333,
"receiver_id": "0.0.999",
"sender_id": "0.0.222",
"serial_number": null,
"token_id": "0.0.111"
},
{
"amount": 555,
"receiver_id": "0.0.999",
"sender_id": "0.0.222",
"serial_number": null,
"token_id": "0.0.444"
},
{
"amount": null,
"receiver_id": "0.0.999",
"sender_id": "0.0.222",
"serial_number": 888,
"token_id": "0.0.666"
}
],
"links": {
"next": null
}
}
```

Optional Filters

- `limit` - The maximum number of airdrops to return in the response. Defaults to `25` with a max of `100`.
- `order` - The direction to sort the items by `token_id` in the response. Can be `asc` or `desc` with a default of `asc`.
steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved
- `receiver.id` - The receiver account the outstanding airdrop was intended for.
- `serialnumber` - The specific serial number associated with airdrop. Supports `eq`, `gt`, `gte`, `lt`, and `lte` operators. Only one occurrence is allowed.
- `token.id` - The token ID this airdrop is associated with. Supports `eq`, `gt`, `gte`, `lt`, and `lte` operators. Only one occurrence is allowed.
xin-hedera marked this conversation as resolved.
Show resolved Hide resolved

#### List of pending airdrops that receiverIdOrEvmAddress has not yet claimed

`/api/v1/accounts/{receiverIdOrEvmAddress}/airdrops/pending`

```json
{
"airdrops": [
{
"amount": 333,
"receiver_id": "0.0.999",
"sender_id": "0.0.222",
"serial_number": null,
"token_id": "0.0.111"
},
{
"amount": 555,
"receiver_id": "0.0.999",
"sender_id": "0.0.222",
"serial_number": null,
"token_id": "0.0.444"
},
{
"amount": null,
"receiver_id": "0.0.999",
"sender_id": "0.0.222",
"serial_number": 888,
"token_id": "0.0.666"
}
],
"links": {
"next": null
}
}
```

Optional Filters

- `limit` - The maximum number of airdrops to return in the response. Defaults to `25` with a max of `100`.
- `order` - The direction to sort the items by `token_id` in the response. Can be `asc` or `desc` with a default of `asc`.
- `sender.id` - The sender account that initiated the pending airdrop.
- `serialnumber` - The specific serial number associated with airdrop. Supports `eq`, `gt`, `gte`, `lt`, and `lte` operators. Only one occurrence is allowed.
- `token.id` - The token ID this airdrop is associated with. Supports `eq`, `gt`, `gte`, `lt`, and `lte` operators. Only one occurrence is allowed.

steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved
## Non-Functional Requirements
steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved
steven-sheehy marked this conversation as resolved.
Show resolved Hide resolved

- Ingest new transaction types at the same rate as consensus nodes