Skip to content

Commit

Permalink
Nodejs: Anchor related changes (#1528)
Browse files Browse the repository at this point in the history
* Nodejs: Anchor related changes

* Nit

* Remove StateMetadataOutput
  • Loading branch information
thibault-martinez authored Oct 30, 2023
1 parent 3f1dc46 commit 86a839a
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 6 deletions.
29 changes: 28 additions & 1 deletion bindings/nodejs/lib/types/block/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { plainToInstance, Type } from 'class-transformer';
import { HexEncodedString } from '../utils';
import { AccountId, NftId } from './id';
import { AccountId, AnchorId, NftId } from './id';

/**
* An address prepended by its network type.
Expand All @@ -22,6 +22,8 @@ enum AddressType {
Nft = 16,
/** An implicit account creation address. */
ImplicitAccountCreation = 24,
/** An Anchor address. */
Anchor = 28,
/** An address with restricted capabilities. */
Restricted = 40,
}
Expand Down Expand Up @@ -65,6 +67,8 @@ abstract class Address {
ImplicitAccountCreationAddress,
data,
) as any as ImplicitAccountCreationAddress;
} else if (data.type == AddressType.Anchor) {
return plainToInstance(AnchorAddress, data) as any as AnchorAddress;
} else if (data.type == AddressType.Restricted) {
return plainToInstance(
RestrictedAddress,
Expand Down Expand Up @@ -160,6 +164,27 @@ class ImplicitAccountCreationAddress extends Address {
}
}

/**
* An Anchor address.
*/
class AnchorAddress extends Address {
/**
* The anchor ID.
*/
readonly anchorId: AnchorId;
/**
* @param address An anchor address as anchor ID.
*/
constructor(address: AnchorId) {
super(AddressType.Anchor);
this.anchorId = address;
}

toString(): string {
return this.anchorId;
}
}

const RestrictedAddressDiscriminator = {
property: 'type',
subTypes: [
Expand Down Expand Up @@ -234,6 +259,7 @@ const AddressDiscriminator = {
value: ImplicitAccountCreationAddress,
name: AddressType.ImplicitAccountCreation as any,
},
{ value: AnchorAddress, name: AddressType.Anchor as any },
{ value: RestrictedAddress, name: AddressType.Restricted as any },
],
};
Expand All @@ -246,4 +272,5 @@ export {
Ed25519Address,
AccountAddress,
NftAddress,
AnchorAddress,
};
5 changes: 5 additions & 0 deletions bindings/nodejs/lib/types/block/id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { HexEncodedString } from '../utils';
*/
export type AccountId = HexEncodedString;

/**
* An Anchor ID represented as hex-encoded string.
*/
export type AnchorId = HexEncodedString;

/**
* An NFT ID represented as hex-encoded string.
*/
Expand Down
67 changes: 62 additions & 5 deletions bindings/nodejs/lib/types/block/output/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { plainToInstance, Type } from 'class-transformer';
import { HexEncodedString, hexToBigInt, NumericString, u64 } from '../../utils';
import { TokenScheme, TokenSchemeDiscriminator } from './token-scheme';
import { INativeToken } from '../../models';
import { AccountId, DelegationId } from '../id';
import { AccountId, NftId, AnchorId, DelegationId } from '../id';
import { EpochIndex } from '../../block/slot';

export type OutputId = HexEncodedString;
Expand All @@ -31,6 +31,8 @@ enum OutputType {
Nft = 3,
/** A Delegation output. */
Delegation = 4,
/** An Anchor output. */
Anchor = 5,
}

/**
Expand Down Expand Up @@ -76,6 +78,13 @@ abstract class Output {
return plainToInstance(FoundryOutput, data) as any as FoundryOutput;
} else if (data.type == OutputType.Nft) {
return plainToInstance(NftOutput, data) as any as NftOutput;
} else if (data.type == OutputType.Delegation) {
return plainToInstance(
DelegationOutput,
data,
) as any as DelegationOutput;
} else if (data.type == OutputType.Anchor) {
return plainToInstance(AnchorOutput, data) as any as AnchorOutput;
}
throw new Error('Invalid JSON');
}
Expand Down Expand Up @@ -185,7 +194,7 @@ class AccountOutput extends ImmutableFeaturesOutput {
* Unique identifier of the account, which is the BLAKE2b-256 hash of the Output ID that created it.
* Unless its a newly created account, then the id is zeroed.
*/
readonly accountId: HexEncodedString;
readonly accountId: AccountId;
/**
* A counter that denotes the number of foundries created by this account output.
*/
Expand All @@ -205,7 +214,7 @@ class AccountOutput extends ImmutableFeaturesOutput {
constructor(
amount: u64,
mana: u64,
accountId: HexEncodedString,
accountId: AccountId,
foundryCounter: number,
unlockConditions: UnlockCondition[],
) {
Expand All @@ -215,6 +224,53 @@ class AccountOutput extends ImmutableFeaturesOutput {
this.mana = mana;
}
}

/**
* An Anchor output.
*/
class AnchorOutput extends ImmutableFeaturesOutput {
/**
* Unique identifier of the anchor, which is the BLAKE2b-256 hash of the Output ID that created it.
* Unless its a newly created anchor, then the id is zeroed.
*/
readonly anchorId: AnchorId;
/**
* A counter that must increase by 1 every time the anchor output is state transitioned.
*/
readonly stateIndex: number;
/**
* The amount of (stored) Mana held by the output.
*/
readonly mana: u64;
/**
* Metadata that can only be changed by the state controller.
*/
readonly stateMetadata?: HexEncodedString;

/**
* @param amount The amount of the output.
* @param mana The amount of stored mana.
* @param anchorId The anchor ID as hex-encoded string.
* @param stateIndex A counter that must increase by 1 every time the anchor output is state transitioned.
* @param unlockConditions The unlock conditions of the output.
* @param stateMetadata Metadata that can only be changed by the state controller.
*/
constructor(
amount: u64,
mana: u64,
anchorId: AnchorId,
stateIndex: number,
unlockConditions: UnlockCondition[],
stateMetadata?: HexEncodedString,
) {
super(OutputType.Account, amount, unlockConditions);
this.anchorId = anchorId;
this.stateIndex = stateIndex;
this.mana = mana;
this.stateMetadata = stateMetadata;
}
}

/**
* An NFT output.
*/
Expand All @@ -223,7 +279,7 @@ class NftOutput extends ImmutableFeaturesOutput {
* Unique identifier of the NFT, which is the BLAKE2b-256 hash of the Output ID that created it.
* Unless its newly minted, then the id is zeroed.
*/
readonly nftId: HexEncodedString;
readonly nftId: NftId;

/**
* The amount of (stored) Mana held by the output.
Expand All @@ -239,7 +295,7 @@ class NftOutput extends ImmutableFeaturesOutput {
constructor(
amount: u64,
mana: u64,
nftId: HexEncodedString,
nftId: NftId,
unlockConditions: UnlockCondition[],
) {
super(OutputType.Nft, amount, unlockConditions);
Expand Down Expand Up @@ -359,6 +415,7 @@ export {
CommonOutput,
BasicOutput,
AccountOutput,
AnchorOutput,
NftOutput,
FoundryOutput,
DelegationOutput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ enum UnlockType {
* An NFT unlock.
*/
Nft = 3,
/**
* An Anchor unlock.
*/
Anchor = 4,
}

/**
Expand Down Expand Up @@ -117,6 +121,24 @@ class NftUnlock extends Unlock {
}
}

/**
* An unlock which must reference a previous unlock which unlocks the anchor that the input is locked to.
*/
class AnchorUnlock extends Unlock {
/**
* The reference.
*/
readonly reference: number;

/**
* @param reference An index referencing a previous unlock.
*/
constructor(reference: number) {
super(UnlockType.Anchor);
this.reference = reference;
}
}

const UnlockDiscriminator = {
property: 'type',
subTypes: [
Expand All @@ -136,6 +158,10 @@ const UnlockDiscriminator = {
value: NftUnlock,
name: UnlockType.Nft as any,
},
{
value: AnchorUnlock,
name: UnlockType.Anchor as any,
},
],
};

Expand All @@ -146,5 +172,6 @@ export {
ReferenceUnlock,
AccountUnlock,
NftUnlock,
AnchorUnlock,
UnlockDiscriminator,
};

0 comments on commit 86a839a

Please sign in to comment.