Skip to content

Commit

Permalink
feat: Token Claim and Cancel Transaction (#2499)
Browse files Browse the repository at this point in the history
* feat: add airdrop claim and cancel transactions

Signed-off-by: Ivaylo Nikolov <[email protected]>

* chore: update protobufs

Signed-off-by: Ivaylo Nikolov <[email protected]>

* feat: update commit messages

Signed-off-by: Ivaylo Nikolov <[email protected]>

* test: add unit tests for cancel and claim

Signed-off-by: Ivaylo Nikolov <[email protected]>

* wip(test): add integration tests for cancel and claim transactions

Signed-off-by: Ivaylo Nikolov <[email protected]>

* fix: claim used the wrong channel function

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: rename transaction name

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: remove claim references in airdropcancel integration test

Signed-off-by: Ivaylo Nikolov <[email protected]>

* test(fix): fix not working test for airdrop cancel and claim

Signed-off-by: Ivaylo Nikolov <[email protected]>

* fix: airdropcancel transaction should work on sender not receiver

Signed-off-by: Ivaylo Nikolov <[email protected]>

* feat: add token airdrop example

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: rename transactions to have the same name as java

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: remove redundant imports and empty lines

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: rename transaction tests  to have the same name as java sdk

Signed-off-by: Ivaylo Nikolov <[email protected]>

* docs: add licenses

Signed-off-by: Ivaylo Nikolov <[email protected]>

* fix: remove dead code from token cancel

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: consistency in constructor

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: change airdrop_supply_per_person naming

Signed-off-by: Ivaylo Nikolov <[email protected]>

* test: fix setting sender id

Signed-off-by: Ivaylo Nikolov <[email protected]>

* refactor: specify what kind of tokens are airdropped

Signed-off-by: Ivaylo Nikolov <[email protected]>

---------

Signed-off-by: Ivaylo Nikolov <[email protected]>
  • Loading branch information
ivaylonikolov7 authored Sep 11, 2024
1 parent dda20d3 commit 7a36f44
Show file tree
Hide file tree
Showing 15 changed files with 2,214 additions and 11 deletions.
419 changes: 419 additions & 0 deletions examples/token-airdrop-example.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/proto/src/proto
47 changes: 47 additions & 0 deletions src/Status.js
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,14 @@ export default class Status {
return "PENDING_NFT_AIRDROP_ALREADY_EXISTS";
case Status.AccountHasPendingAirdrops:
return "ACCOUNT_HAS_PENDING_AIRDROPS";
case Status.ThrottledAtConsensus:
return "THROTTLED_AT_CONSENSUS";
case Status.InvalidPendingAirdropId:
return "INVALID_PENDING_AIRDROP_ID";
case Status.TokenAirdropWithFallbackRoyalty:
return "TOKEN_AIRDROP_WITH_FALLBACK_ROYALTY";
case Status.InvalidTokenInPendingAirdrop:
return "INVALID_TOKEN_IN_PENDING_AIRDROP";
default:
return `UNKNOWN (${this._code})`;
}
Expand Down Expand Up @@ -1349,6 +1357,14 @@ export default class Status {
return Status.PendingNftAirdropAlreadyExists;
case 365:
return Status.AccountHasPendingAirdrops;
case 366:
return Status.ThrottledAtConsensus;
case 367:
return Status.InvalidPendingAirdropId;
case 368:
return Status.TokenAirdropWithFallbackRoyalty;
case 369:
return Status.InvalidTokenInPendingAirdrop;
default:
throw new Error(
`(BUG) Status.fromCode() does not handle code: ${code}`,
Expand Down Expand Up @@ -3030,3 +3046,34 @@ Status.PendingNftAirdropAlreadyExists = new Status(364);
* this transaction.
*/
Status.AccountHasPendingAirdrops = new Status(365);

/**
* Consensus throttle did not allow execution of this transaction.<br/>
* The transaction should be retried after a modest delay.
*/
Status.ThrottledAtConsensus = new Status(366);

/**
* The provided pending airdrop id is invalid.<br/>
* This pending airdrop MAY already be claimed or cancelled.
* <p>
* The client SHOULD query a mirror node to determine the current status of
* the pending airdrop.
*/
Status.InvalidPendingAirdropId = new Status(367);

/**
* The token to be airdropped has a fallback royalty fee and cannot be
* sent or claimed via an airdrop transaction.
*/
Status.TokenAirdropWithFallbackRoyalty = new Status(368);

/**
* This airdrop claim is for a pending airdrop with an invalid token.<br/>
* The token might be deleted, or the sender may not have enough tokens
* to fulfill the offer.
* <p>
* The client SHOULD query mirror node to determine the status of the pending
* airdrop and whether the sender can fulfill the offer.
*/
Status.InvalidTokenInPendingAirdrop = new Status(369);
2 changes: 2 additions & 0 deletions src/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export { default as KeyList } from "./KeyList.js";
export { default as Key } from "./Key.js";
export { default as Mnemonic } from "./Mnemonic.js";
export { default as TokenAirdropTransaction } from "./token/TokenAirdropTransaction.js";
export { default as TokenClaimAirdropTransaction } from "./token/TokenClaimAirdropTransaction.js";
export { default as TokenCancelAirdropTransaction } from "./token/TokenCancelAirdropTransaction.js";
// eslint-disable-next-line deprecation/deprecation
export { default as AccountAllowanceAdjustTransaction } from "./account/AccountAllowanceAdjustTransaction.js";
export { default as AccountAllowanceApproveTransaction } from "./account/AccountAllowanceApproveTransaction.js";
Expand Down
20 changes: 20 additions & 0 deletions src/token/AbstractTokenTransferTransaction.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/*-
* ‌
* Hedera JavaScript SDK
* ​
* Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import TokenTransfer from "./TokenTransfer.js";
import TokenNftTransfer from "../token/TokenNftTransfer.js";
import TokenId from "./TokenId.js";
Expand Down
77 changes: 77 additions & 0 deletions src/token/AirdropPendingTransaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*-
* ‌
* Hedera JavaScript SDK
* ​
* Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import Transaction from "../transaction/Transaction.js";

/**
* @typedef {import("../token/PendingAirdropId.js").default} PendingAirdropId
*/
export default class AirdropPendingTransaction extends Transaction {
/**
* @param {object} [props]
* @param {PendingAirdropId[]} [props.pendingAirdropIds]
*/
constructor(props) {
/**
* @private
* @type {PendingAirdropId[]}
*/
super();

/**
* @private
* @type {PendingAirdropId[]}
*/
this._pendingAirdropIds = [];

if (props?.pendingAirdropIds != null) {
this._pendingAirdropIds = props.pendingAirdropIds;
}
}

/**
* @returns {PendingAirdropId[]}
*/
get pendingAirdropIds() {
return this._pendingAirdropIds;
}

/**
*
* @param {PendingAirdropId} pendingAirdropId
* @returns {this}
*/
addPendingAirdropId(pendingAirdropId) {
this._requireNotFrozen();
this._pendingAirdropIds.push(pendingAirdropId);
return this;
}

/**
*
* @param {PendingAirdropId[]} pendingAirdropIds
* @returns {this}
*/
setPendingAirdropIds(pendingAirdropIds) {
this._requireNotFrozen();
this._pendingAirdropIds = pendingAirdropIds;
return this;
}
}
114 changes: 104 additions & 10 deletions src/token/PendingAirdropId.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/*-
* ‌
* Hedera JavaScript SDK
* ​
* Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

/**
* @namespace proto
* @typedef {import("@hashgraph/proto").proto.PendingAirdropId} HashgraphProto.proto.PendingAirdropId
Expand All @@ -11,18 +31,27 @@ export default class PendingAirdropId {
/**
*
* @param {object} props
* @param {AccountId} props.senderId
* @param {AccountId} props.receiverId
* @param {AccountId} [props.senderId]
* @param {AccountId} [props.receiverId]
* @param {TokenId?} props.tokenId
* @param {NftId?} props.nftId
*/
constructor(props) {
this.senderId = props.senderId;
this.receiverId = props.receiverId;
this._senderId = null;
this._receiverId = null;
this._tokenId = null;
this._nftId = null;

if (props.receiverId) {
this._receiverId = props.receiverId;
}
if (props.senderId) {
this._senderId = props.senderId;
}
if (props.tokenId) {
this.tokenId = new TokenId(props.tokenId);
this._tokenId = new TokenId(props.tokenId);
} else if (props.nftId) {
this.nftId = new NftId(props.nftId?.tokenId, props.nftId?.serial);
this._nftId = new NftId(props.nftId?.tokenId, props.nftId?.serial);
}
}

Expand Down Expand Up @@ -59,15 +88,80 @@ export default class PendingAirdropId {
});
}

/**
*
* @param {AccountId} senderId
* @returns

Check warning on line 94 in src/token/PendingAirdropId.js

View workflow job for this annotation

GitHub Actions / Test using Node 16

Missing JSDoc @returns type

Check warning on line 94 in src/token/PendingAirdropId.js

View workflow job for this annotation

GitHub Actions / Integration Tests on Node 16

Missing JSDoc @returns type

Check warning on line 94 in src/token/PendingAirdropId.js

View workflow job for this annotation

GitHub Actions / Integration Tests on Node 18

Missing JSDoc @returns type

Check warning on line 94 in src/token/PendingAirdropId.js

View workflow job for this annotation

GitHub Actions / Build using Node 16

Missing JSDoc @returns type

Check warning on line 94 in src/token/PendingAirdropId.js

View workflow job for this annotation

GitHub Actions / Build using Node 18

Missing JSDoc @returns type
*/
setSenderid(senderId) {
this._senderId = senderId;
return this;
}

/**
* @param {AccountId} receiverId
* @returns {this}
*/
setReceiverId(receiverId) {
this._receiverId = receiverId;
return this;
}

/**
* @param {TokenId} tokenId
* @returns {this}
*/
setTokenId(tokenId) {
this._tokenId = tokenId;
return this;
}

/**
* @param {NftId} nftId
* @returns {this}
*/
setNftId(nftId) {
this._nftId = nftId;
return this;
}

/**
* @returns {?AccountId}
*/
get senderId() {
return this._senderId;
}

/**
* @returns {?AccountId}
*/
get receiverId() {
return this._receiverId;
}

/**
* @returns {?TokenId}
*/
get tokenId() {
return this._tokenId;
}

/**
* @returns {?NftId}
*/
get nftId() {
return this._nftId;
}

/**
* @returns {HashgraphProto.proto.PendingAirdropId}
*/
toBytes() {
return {
senderId: this.senderId._toProtobuf(),
receiverId: this.receiverId._toProtobuf(),
fungibleTokenType: this.tokenId?._toProtobuf(),
nonFungibleToken: this.nftId?._toProtobuf(),
senderId: this.senderId?._toProtobuf(),
receiverId: this._receiverId?._toProtobuf(),
fungibleTokenType: this._tokenId?._toProtobuf(),
nonFungibleToken: this._nftId?._toProtobuf(),
};
}
}
20 changes: 20 additions & 0 deletions src/token/PendingAirdropRecord.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/*-
* ‌
* Hedera JavaScript SDK
* ​
* Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

/**
* @namespace proto
* @typedef {import("@hashgraph/proto").proto.PendingAirdropRecord} HashgraphProto.proto.PendingAirdropRecord
Expand Down
20 changes: 20 additions & 0 deletions src/token/TokenAirdropTransaction.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/*-
* ‌
* Hedera JavaScript SDK
* ​
* Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import Transaction, {
TRANSACTION_REGISTRY,
} from "../transaction/Transaction.js";
Expand Down
Loading

0 comments on commit 7a36f44

Please sign in to comment.