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

feat/Node: Native token feature #1616

Merged
merged 11 commits into from
Nov 22, 2023
13 changes: 8 additions & 5 deletions bindings/nodejs/examples/client/05-get-address-balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,14 @@ async function run() {
for (const outputResponse of addressOutputs) {
const output = outputResponse['output'];
if (output instanceof CommonOutput) {
(output as CommonOutput).getNativeTokens()?.forEach((token) => {
totalNativeTokens[token.id] =
(totalNativeTokens[token.id] || BigInt(0)) +
token.amount;
});
const nativeTokenFeature = (
output as CommonOutput
).getNativeToken();
if (nativeTokenFeature != undefined) {
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
totalNativeTokens[nativeTokenFeature.id] =
(totalNativeTokens[nativeTokenFeature.id] ||
BigInt(0)) + nativeTokenFeature.amount;
}
}

totalAmount += output.getAmount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ async function run() {
outputs.forEach(({ output, address }, i) => {
console.log(`OUTPUT #${i}`);
console.log(
'- address: %s\n- amount: %d\n- native tokens: %s',
'- address: %s\n- amount: %d\n- native token: %s',
Utils.hexToBech32(address.toString(), 'rms'),
output.getAmount(),
output instanceof CommonOutput
? (output as CommonOutput).getNativeTokens()
? (output as CommonOutput).getNativeToken() ?? []
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
: [],
);
});
Expand Down Expand Up @@ -91,7 +91,7 @@ async function run() {
Utils.hexToBech32(address.toString(), 'rms'),
output.getAmount(),
output instanceof CommonOutput
? (output as CommonOutput).getNativeTokens()
? (output as CommonOutput).getNativeToken()
: undefined,
);
});
Expand Down
40 changes: 39 additions & 1 deletion bindings/nodejs/lib/types/block/output/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {
BlockIssuerKey,
BlockIssuerKeyDiscriminator,
} from './block-issuer-key';
import { u64 } from '../../utils/type-aliases';
import { u256, u64 } from '../../utils/type-aliases';
import { EpochIndex } from '../../block/slot';
import { INativeToken } from '../../models/native-token';
import { HexEncodedString } from '../../utils/hex-encoding';

/**
* All of the feature block types.
Expand Down Expand Up @@ -113,6 +115,40 @@ class TagFeature extends Feature {
}
}

/**
* Native token feature.
*/
class NativeTokenFeature extends Feature {
/**
* Identifier of the native token.
*/
readonly id: HexEncodedString;
/**
* Amount of native tokens of the given Token ID.
*/
readonly amount: u256;
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved

/**
* Creates a new `NativeTokenFeature`.
* @param nativeToken The native token stored with the feature.
*/
constructor(nativeToken: INativeToken) {
super(FeatureType.NativeToken);
this.id = nativeToken.id;
this.amount = nativeToken.amount;
}

/**
* Returns the native token contained in this feature.
*/
public asNativeToken(): INativeToken {
return {
id: this.id,
amount: this.amount,
};
}
}

/**
* Block Issuer feature.
*/
Expand Down Expand Up @@ -178,6 +214,7 @@ const FeatureDiscriminator = {
{ value: IssuerFeature, name: FeatureType.Issuer as any },
{ value: MetadataFeature, name: FeatureType.Metadata as any },
{ value: TagFeature, name: FeatureType.Tag as any },
{ value: NativeTokenFeature, name: FeatureType.NativeToken as any },
{ value: BlockIssuerFeature, name: FeatureType.BlockIssuer as any },
{ value: StakingFeature, name: FeatureType.Staking as any },
],
Expand All @@ -191,6 +228,7 @@ export {
IssuerFeature,
MetadataFeature,
TagFeature,
NativeTokenFeature,
BlockIssuerFeature,
StakingFeature,
};
28 changes: 12 additions & 16 deletions bindings/nodejs/lib/types/block/output/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import {
UnlockCondition,
UnlockConditionDiscriminator,
} from './unlock-condition';
import { Feature, FeatureDiscriminator } from './feature';
import { Feature, FeatureDiscriminator, NativeTokenFeature } from './feature';

// Temp solution for not double parsing JSON
import { plainToInstance, Type } from 'class-transformer';
import { HexEncodedString, hexToBigInt, NumericString, u64 } from '../../utils';
import { HexEncodedString, NumericString, u64 } from '../../utils';
import { TokenScheme, TokenSchemeDiscriminator } from './token-scheme';
import { INativeToken } from '../../models';
import { AccountId, NftId, AnchorId, DelegationId } from '../id';
import { EpochIndex } from '../../block/slot';
import { INativeToken } from '../../models/native-token';

export type OutputId = HexEncodedString;

Expand Down Expand Up @@ -102,9 +102,6 @@ abstract class CommonOutput extends Output {
})
readonly unlockConditions: UnlockCondition[];

// Getter transforms it into nativeTokens with a proper number
private nativeTokens?: INativeToken[];

/**
* The features contained by the output.
*/
Expand All @@ -126,22 +123,21 @@ abstract class CommonOutput extends Output {
super(type, amount);
this.unlockConditions = unlockConditions;
}

/**
* The native tokens held by the output.
* The native token held by the output.
*/
getNativeTokens(): INativeToken[] | undefined {
if (!this.nativeTokens) {
return this.nativeTokens;
getNativeToken(): INativeToken | undefined {
if (!this.features) {
return undefined;
}

// Make sure the amount of native tokens are of bigint type.
for (let i = 0; i < this.nativeTokens.length; i++) {
const token = this.nativeTokens[i];
if (typeof token.amount === 'string') {
this.nativeTokens[i].amount = hexToBigInt(token.amount);
for (const feature of this.features) {
if (feature instanceof NativeTokenFeature) {
return (feature as NativeTokenFeature).asNativeToken();
}
}
return this.nativeTokens;
return undefined;
}
}

Expand Down