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

NEP-452 Linkdrop Standard #452

Merged
merged 29 commits into from
Jan 27, 2024
Merged
Changes from 8 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
de47911
initial impl
BenKurrek Jan 24, 2023
de454c1
renamed nep to PR number
BenKurrek Jan 24, 2023
c0d764b
Apply suggestions from code review
BenKurrek Jan 25, 2023
f4df068
Update neps/nep-0452.md
BenKurrek Jan 27, 2023
54322db
applied suggestions from code review
BenKurrek Jan 27, 2023
62398fd
marked get key balance as deprecated
BenKurrek Jan 27, 2023
7eac04f
added required gas field to key info
BenKurrek Feb 3, 2023
f2f0486
adding security implications and example scenarios (#459)
kenobijon Feb 3, 2023
8a2b1d7
review comments from frol
BenKurrek Feb 23, 2023
f52586a
swapped deletion of key with transfer of assets
BenKurrek Mar 13, 2023
e1b4b18
Update neps/nep-0452.md
BenKurrek Mar 13, 2023
5877eba
removed reference PR
BenKurrek Mar 13, 2023
11d006c
Apply suggestions from code review
BenKurrek Mar 28, 2023
e5bf766
implemented 471 and renamed rational and alternatives to just alterna…
BenKurrek Mar 28, 2023
8e50122
applied all code review
BenKurrek Mar 28, 2023
382d4a8
made required gas non optional
BenKurrek Mar 29, 2023
3968d96
final review passthrough
BenKurrek Apr 17, 2023
845cd53
ts formatter
BenKurrek Apr 18, 2023
2bd6fcd
Apply suggestions from code review
BenKurrek Apr 19, 2023
1bf0268
code review
BenKurrek Apr 19, 2023
c61f9fb
fixed past vs present tense for example scenarios
BenKurrek Apr 20, 2023
07f4da2
Update neps/nep-0452.md
BenKurrek Apr 20, 2023
ac9a8bd
applied code reviews
BenKurrek Apr 21, 2023
17c0294
rename yoctoNEAR -> yoctonear
BenKurrek Apr 21, 2023
09ee654
Merge branch 'master' into ben/linkdrop-nep
frol Jun 2, 2023
d513e1b
added final review from frol
BenKurrek Jun 14, 2023
75e6e9b
code formatter
BenKurrek Jun 14, 2023
256a24b
Merge branch 'master' into ben/linkdrop-nep
gagdiez Jan 27, 2024
f349084
fix lint
njelich Jan 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 213 additions & 0 deletions neps/nep-0452.md
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
---
NEP: 452
Title: Linkdrop Standard
Author: Ben Kurrek <ben.kurrek@near.org>, Ken Miyachi <ken.miyachi@near.foundation>
DiscussionsTo: https://gov.near.org/t/official-linkdrop-standard/32463/1
Status: Draft
Type: Standards Track
Category: Contract
Version: 1.0.0
Created: 24-Jan-2023
Updated: 24-Jan-2023
---

## Summary

A standard interface for linkdrops that support $NEAR, fungible tokens, non-fungible tokens, and is extensible for linkdrops of any type.

## Motivation

Linkdrops are an extremely powerful tool that enable seamless onboarding and instant crypto experiences with the click of a link. The original [near-linkdrop](https://github.com/near/near-linkdrop) contract provides a minimal interface allowing users to embed $NEAR within an access key and create a simple Web2 style link that can then be used as a means of onboarding. This simple $NEAR linkdrop is not enough as many artists, developers, event coordinators, and applications want to drop more digital assets such as NFTs, FTs, tickets etc.

As linkdrop implementations start to push the boundaries of what’s possible, new data structures, methods, and interfaces are being developed. There needs to be a standard data model and interface put into place to ensure assets can be claimed independent of the contract they came from. If not, integrating any application with linkdrops will require customized solutions, which would become cumbersome for the developer and deteriorate the user onboarding experience. The linkdrop standard addresses these issues by providing a simple and extensible standard data model and interface.

The initial discussion can be found [here](https://gov.near.org/t/official-linkdrop-standard/32463/1).

## Rationale and Alternatives
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

* Why is this design the best in the space of possible designs?
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

This design allows for flexibility and extensibility of the standard while providing a set of criteria that cover the majority of current linkdrop use cases. The design was heavily inspired by current, functional NEPs such as the Fungible Token and Non-Fungible Token standards.

* What other designs have been considered and what is the rationale for not choosing them?
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

A generic data struct that all drop types needed to inherit from. This struct contained a name and some metadata in the form of stringified JSON. This made it easily extensible for any new types down the road. The rationale for not choosing this design was both simplicity and flexibility. Having one data struct required keys to be of one type only when in reality, they can be many at once. In addition, having a generic, open-ended metadata field could lead to many interpretations and different designs. We chose to use a KeyInfo struct that can be easily extensible and can cover all use-cases by having optional vectors of different data types. The proposed standard is simple, supports drops with multiple assets, and is backwards compatible with all previous linkdrops, and can be extended very easily.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

A standard linkdrop creation interface. A standardized linkdrop creation interface would provide data models and functions to ensure linkdrops were created and stored in a specific format. The rationale for not choosing this design was that is was too restrictive. Standardizing linkdrop creation adds complexity and reduces flexibility by restricting linkdrop creators in the process in which linkdrops are created, and potentially limiting linkdrop functionality. The functionality of the linkdrop creation, such as refunding of assets, access keys, and batch creation, should be chosen by the linkdrop creator and live within the linkdrop creator platform. Further, linkdrop creation is often not displayed to end users and there is not an inherent value proposition for a standardized linkdrop creation interface from a client perspective.

* What is the impact of not doing this?
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

The impact of not doing this is creating a fragmented ecosystem of linkdrops, increasing the friction for user onboarding. Linkdrop claim pages (e.g. wallet providers) would have to implement custom integrations for every linkdrop provider platform. Inherently this would lead to a bad user experience when new users are onboarding and interacting with linkdrops in general.

## Specification
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

```ts
/// Information about a specific public key.
type KeyInfo = {
/// How much Gas should be attached when the key is used to call `claim` or `create_account_and_claim`.
/// If not provided, a default value of 100 TGas will be attached to the transaction.
robert-zaremba marked this conversation as resolved.
Show resolved Hide resolved
required_gas: string | null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you see this gas being split between the calls? There are two arrays that require cross-contract calls (NFTData[] and FTData[]), and there is also some gas to be preallocated for the account creation callback and assets transfer callback functions, so there is a lot to unpack here.

P.S. It feels that it is quite trivial to end up with a linkdrop that won't have enough gas to transfer all the assets in a single transaction. Thus, one area for future possibilities would be a multi-stage withdrawal.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not provided, will the gas for each leg of the transaction be deducted from the deposit? I would clarify this behavior in the comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly believe that the gas distribution and the inner workings of the logic should not be addressed in this standard. In my eyes, this standard allows anyone to claim a linkdrop regardless of where it originated from (keypom, near / testnet, neardrop etc...). If you have a linkdrop that follows this standard, you will know how to claim it and what to expect.

How gas is distributed should be left to the smart contract developer in my opinion.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How gas is distributed should be left to the smart contract developer in my opinion.

@BenKurrek Well, this is exactly who I care about, the developers of the smart contract who would be in a tough situation where they only have the total gas allocation, and they need to somehow figure out how to spend it wisely. While alternatively, we might have required_gas specified on the FTData / NFTData level. How does Keypom handle it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly believe that the gas distribution and the inner workings of the logic should not be addressed in this standard.

After a second thought, I agree with this statement. Consider adding a hint to the readers that it is expected that it is the responsibility of a linkdrop contract to define how exactly to calculate the required gas (either automatically on the contract side with linkdrop creation, or even move this responsibility to the client code of linkdrop creation)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think that we should not standarize the gas logic here. However we should document the issue here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, remove the field at all, is it a so useful field? The user won't be dissatisfied with attaching the 100Tgas by default, or 300TGas in a case of failure.

For instance, what happens if ft_transfer_call fails? Nothing bad, the front-end developer specifies more Gas. I also foresee the gas amount is going to be hard-coded (predictable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference is to standardize how much gas to attach but leave it to the developers to choose how they distribute that gas throughout the transaction. I can leave a note explaining that it's the developer's responsibility but not force them through a certain flow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a note under the field. Let me know if this suffices.

BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// yoctoNEAR$ amount that will be sent to the claiming account (either new or existing)
/// when the key is successfully used.
balance: string,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered renaming it to near_amount or even introducing NEARData type to match FTData type where amount is used?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

near_amount would make sense here and possibly minimize potential confusion with FT drops

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good suggestion although the amount will be in yocto... do you think this would be obvious enough?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, we can go with yoctonear_amount then

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yNEAR or yoctoNEAR, y_near

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like yoctoNEAR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BenKurrek I just noticed that you've changed it to yoctoNEAR - it's against Rust naming convention, it's better to go with yoctonear or yoctonear_amount.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do yoctonear


/// If using the NFT standard extension, a set of NFTData can be linked to the public key
/// indicating that all those assets will be sent to the claiming account (either new or
/// existing) when the key is successfully used.
nft_data: NFTData[] | null,
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

/// If using the FT standard extension, a set of FTData can be linked to the public key
/// indicating that all those assets will be sent to the claiming account (either new or
/// existing) when the key is successfully used.
ft_data: FTData[] | null,

/// ... other types can be introduced and the standard is easily extendable.
}


/// Data outlining a specific Non-Fungible Token that should be sent to the claiming account /// (either new or existing) when a key is successfully used.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
type NFTData = {
/// the id of the token to transfer
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
token_id: string,
/// The valid NEAR account indicating the Non-Fungible Token contract.
contract_id: string
}


/// Data outlining Fungible Tokens that should be sent to the claiming account
/// (either new or existing) when a key is successfully used.
type FTData = {
/// The number of tokens to transfer, wrapped in quotes and treated
/// like a string, although the number will be stored as an unsigned integer
/// with 128 bits.
Comment on lines +102 to +104
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The number of tokens to transfer, wrapped in quotes and treated
/// like a string, although the number will be stored as an unsigned integer
/// with 128 bits.
/// The number of tokens to transfer as a stringified integer number. Max value: 2^128-1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied this directly from the FT standard - do you still wanna change it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the suggestion is more meaningful.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@robert-zaremba I feel both explanations are equally cumbersome πŸ€·β€β™‚οΈ , so I would leave the original one for now since it is an extract from an existing NEP, and think about how we can improve this situation with stringified numbers universally for all the NEPs going forward.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, the original is text is not clear. Should be changed. Replicating bad documentation should not be an excuse.

amount: string,
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// The valid NEAR account indicating the Fungible Token contract.
contract_id: string
}



BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

/****************/
/* VIEW METHODS */
/****************/

/// Deprecated - use `get_key_information` instead. This method provides backwards compatibility with previous implementations.
/// Returns the $yoctoNEAR amount associated with a given public key
/// Panics if the key does not exist.
/// The Public key must be in a binary format with base58 string serialization with human-readable curve. The key types currently supported are secp256k1 and ed25519. Ed25519 public keys accepted are 32 bytes and secp256k1 keys are the uncompressed 64 format.
function get_key_balance(key: string) -> string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we include this in a new standard if it is deprecated? let's remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I included it as to be backwards compatible with legacy contracts. If we change it, we're forcing every contract to change if they want to be compatible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frol do you have opinions here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's better explain it:

  1. either we move it to "recommended methods" -- this way we won't require every contract to implement it, and inform the community to rather not relay on it and not use it.
  2. or we better explain that this is required. in that case we should not call it "deprecated", because it is a valid method and provide correct response.

Personally I prefer 2.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BenKurrek I think we should drop the deprecated method from the spec, and migrate wallets to the new method (we should update get_key_information in the near-linkdrop to return yoctoNEAR and deploy it)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seams the spec was not updated, but the comment was resolved. Reopening it.

BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

/// Returns the KeyInfo associated with a given public key
/// Panics if the key does not exist
/// The Public key must be in a binary format with base58 string serialization with human-readable curve. The key types currently supported are secp256k1 and ed25519. Ed25519 public keys accepted are 32 bytes and secp256k1 keys are the uncompressed 64 format.
function get_key_information(key: string) -> KeyInfo
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

/******************/
/* CHANGE METHODS */
/******************/

/// Transfer all assets linked to the signer’s public key to an *existing* NEAR account.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// If the transfer fails for whatever reason, it is up to the smart contract developer to
/// choose what should happen. For example, the contract can choose to keep the assets
/// or send them back to the original linkdrop creator.
///
/// Requirements:
/// * The predecessor account *MUST* be the current contract ID.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// * The assets being sent *MUST* be associated with the signer’s public key.
/// * The assets *MUST* be sent to the `account_id` passed in.
///
/// Arguments:
/// * `account_id` the account that should receive the linkdrop assets.
function claim(account_id: string) -> Promise
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved



/// Creates a new NEAR account and transfers all assets linked to the signer’s public key to
/// the *newly created account*. If the transfer fails for whatever reason, it is up to the
/// smart contract developer to choose what should happen. For example, the contract can
/// choose to keep the assets or return them to the original linkdrop creator.
///
/// Requirements
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// * The predecessor account *MUST* be the current contract ID.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// * The assets being sent *MUST* be associated with the signer’s public key.
/// * The assets *MUST* be sent to the `new_account_id` passed in.
/// * The newly created account *MUST* have a new access key added to its account (either
/// full or limited access) in the same receipt that the account was created in.
///
/// Arguments
/// * `new_account_id`: the valid NEAR account which is being created and should
/// receive the linkdrop assets
/// * `new_public_key`: the valid public key that should be used for the access key added to
/// The Public key must be in a binary format with base58 string serialization with human-readable curve. The key types currently supported are secp256k1 and ed25519. Ed25519 public keys accepted are 32 bytes and secp256k1 keys are the uncompressed 64 format.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
/// the newly created account.
function create_account_and_claim(new_account_id: string, new_public_key: string) -> Promise
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved
```

## Example Scenarios
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

*Pre-requisite Steps*: Linkdrop creation:
The linkdrop creator that has an account and some $NEAR:

- creates a keypair locally (`pubKey1`, `privKey1`). (The keypair is not written to chain at this time)
- calls send on the contract and passes in the pubKey1 as an argument as well as the desired balance for the linkdrop.
frol marked this conversation as resolved.
Show resolved Hide resolved
- The contract will map the `pubKey1` to the desired balance for the linkdrop.
- The contract will then add the `pubKey1` as a function call access key with the ability to call claim and create_account_and_claim. This means that anyone with the `privKey1` that was created locally, can claim this linkdrop.
frol marked this conversation as resolved.
Show resolved Hide resolved
- Linkdrop creator will then create a link to send to someone that contains this privKey1. The link may follow the format: wallet.testnet.near.org/linkdrop/{fundingContractAccountId}/{linkdropKeyPairSecretKey}?redirectUrl={redirectUrl}
frol marked this conversation as resolved.
Show resolved Hide resolved
`fundingContractAccountId`: The contract accountId that was used to send the funds.
frol marked this conversation as resolved.
Show resolved Hide resolved
`linkdropKeyPairSecretKey`: The corresponding secret key to the public key sent to the contract.
`redirectUrl`: The url that wallet will redirect to after funds are successfully claimed to an existing account. The URL is sent the accountId used to claim the funds as a query param.

### Claiming a linkdrop without a NEAR Account

The receiver of the link that is claiming the linkdrop:

- Receives the link which redirects them to a linkdrop claiming page (such as NEAR wallet).
frol marked this conversation as resolved.
Show resolved Hide resolved
- The linkdrop claim page calls `get_key_information` to display information associated with the linkdrop
frol marked this conversation as resolved.
Show resolved Hide resolved
- The linkdrop claiming page creates a new keypair (`pubKey2`, `privKey2`) locally. (The keypair is not written to chain at this time)
- Receiver will then choose an account ID such as alice.near.
frol marked this conversation as resolved.
Show resolved Hide resolved
- Wallet will then use the privKey1 which has access to call `claim` and `create_account_and_claim` in order to call `create_account_and_claim` on the contract.
frol marked this conversation as resolved.
Show resolved Hide resolved
- It will pass in `pubKey2` which will be used to create a full access key for the new account.
frol marked this conversation as resolved.
Show resolved Hide resolved
- The contract will create the new account and transfer the funds to it alongside any NFT or fungible tokens included in the linkdrop.
frol marked this conversation as resolved.
Show resolved Hide resolved

### Claiming a linkdrop with a NEAR Account
frol marked this conversation as resolved.
Show resolved Hide resolved
The receiver of the link that is claiming the linkdrop:

- Receives the link which redirects them to a linkdrop claiming page (such as NEAR wallet).
- The linkdrop claim page calls `get_key_information` to display information associated with the linkdrop
- The linkdrop claiming page connects to an existing NEAR Account.
- Wallet will then use the `privKey1` which has access to call `claim` and `create_account_and_claim` in order to call `claim` on the contract.
- The contract will transfer the funds to the existing account alongside any NFT or fungible tokens included in the linkdrop.


## Reference Implementation

Below are some references for linkdrop contracts. A specific implementation of this standard can be seen in [this pull request](https://github.com/near/near-linkdrop/pull/24).β—Š
frol marked this conversation as resolved.
Show resolved Hide resolved

- [Link Drop Contract](https://github.com/near/near-linkdrop)
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

- [Keypom Contract](https://github.com/keypom/keypom)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is worth linking to a specific commit state as who knows how the implementations will evolve in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't implemented this specific standard as it's not finalized but once we finish with the interface, I'll make a PR into keypom and then link the commit here.



## Security Implications
frol marked this conversation as resolved.
Show resolved Hide resolved

1. Linkdrop Creation
Linkdrop creation involves creating keypairs associated with mapping to assets such as $NEAR, FTs, NFTs and access keys. There are security implications with the access keys associated with the keypairs. These access keys should be function call access keys and be limited to specific functionality. For example, keypairs can be generated with function call access keys which have permission to only call `claim` and `create_account_and_claim`. Another important security implication of linkdrop creation is to ensure that only one key is mapped to a set of assets at any given time. Linkdrop creation can happen in real-time or prior to being received. The mass creation of linkdrops involves creating multiple keypairs associated with mapping to assets and access keys. The security implications mentioned above are increased with the mass creation of linkdrops.
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

2. Linkdrop Key Management
Key management is a critical saftey component of linkdrops. The linkdrop creator should implement a key management strategy for linkdrop keys upon the receiver claiming the linkdrops assets. For example, one strategy may be to delete the linkdrop keypair in the same block the receiver claims the linkdrop assets, so a single linkdrop cannot be used multiple times. In another example, a linkdrop creator may allow for a linkdrop to be used X number of times, where they could track the number of calls to `claim` or `create_account_and_claim` and delete the keypair after X uses of the linkdrop. It is very important to implement your key management strategy in `claim` and `create_account_and_claim` as opposed to a callback function to ensure the linkdrop keys are not improperly used. Implementing key management in a callback has a security implication of such as 'double-spending' a linkdrop.

## Future possibilities
frol marked this conversation as resolved.
Show resolved Hide resolved

- Function call data types
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

- Optional configurations added to KeyInfo which can include multi-usekeys, time-based claiming etc…

- Standard process for how links connect to claim pages (i.e a standardized URL such as an app’s baseUrl/contractId= [LINKDROP_CONTRACT]&secretKey=[SECRET_KEY]

- Standard for deleting keys and refunding assets.
frol marked this conversation as resolved.
Show resolved Hide resolved

## Copyright
[copyright]: #copyright
BenKurrek marked this conversation as resolved.
Show resolved Hide resolved

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).