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 type alias support #2637

Merged
merged 5 commits into from
Sep 27, 2023

Conversation

acheroncrypto
Copy link
Collaborator

Problem

Type aliases are not supported.

Summary of Changes

  • Add type alias support for the IDL, TS client, and the CLI
  • Add tests for type aliases

Example

Program:

use anchor_lang::prelude::*;

declare_id!("TypeA1ias1111111111111111111111111111111111");

#[program]
pub mod type_alias {
    use super::*;

    pub fn type_alias(ctx: Context<TypeAlias>, u8_array: U8Array) -> Result<()> {
        ctx.accounts.account.u8_array = u8_array;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct TypeAlias<'info> {
    #[account(zero)]
    pub account: Account<'info, TypeAliasAccount>,
}

#[account]
pub struct TypeAliasAccount {
    pub u8_array: U8Array,
}

pub type U8Array = [u8; 8];

IDL:

{
  "version": "0.1.0",
  "name": "type_alias",
  "instructions": [
    {
      "name": "typeAlias",
      "accounts": [
        {
          "name": "account",
          "isMut": true,
          "isSigner": false
        }
      ],
      "args": [
        {
          "name": "u8Array",
          "type": {
            "defined": "U8Array"
          }
        }
      ]
    }
  ],
  "accounts": [
    {
      "name": "TypeAliasAccount",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "u8Array",
            "type": {
              "defined": "U8Array"
            }
          }
        ]
      }
    }
  ],
  "types": [
    {
      "name": "U8Array",
      "type": {
        "kind": "alias",
        "value": {
          "array": [
            "u8",
            8
          ]
        }
      }
    }
  ]
}

TypeScript:

import * as anchor from "@coral-xyz/anchor";
import { assert } from "chai";

import type { TypeAlias } from "../target/types/type_alias";

describe("Type alias", () => {
  anchor.setProvider(anchor.AnchorProvider.env());
  const program = anchor.workspace.typeAlias as anchor.Program<TypeAlias>;

  it("Can use type aliases", async () => {
    const kp = anchor.web3.Keypair.generate();

    const u8Array = [1, 2, 3, 4, 5, 6, 7, 8];
    await program.methods
      .typeAlias(u8Array)
      .accounts({ account: kp.publicKey })
      .signers([kp])
      .preInstructions([
        await program.account.typeAliasAccount.createInstruction(kp),
      ])
      .rpc();

    const account = await program.account.typeAliasAccount.fetch(kp.publicKey);
    assert.deepEqual(account.u8Array, u8Array);
  });
});

Closes #1300, resolves #1632.

@vercel
Copy link

vercel bot commented Sep 27, 2023

@acheroncrypto is attempting to deploy a commit to the coral-xyz Team on Vercel.

A member of the Team first needs to authorize it.

@acheroncrypto acheroncrypto added enhancement New feature or request ts cli tests idl related to the IDL, either program or client side labels Sep 27, 2023
@acheroncrypto acheroncrypto marked this pull request as ready for review September 27, 2023 16:44
Copy link
Contributor

@buffalojoec buffalojoec left a comment

Choose a reason for hiding this comment

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

This is awesome! I left a couple comments but implementation is solid.

Having this capability in Anchor is going to be super helpful.

Comment on lines +431 to +436
Some(Ok(IdlTypeDefinition {
name,
generics: None,
docs: doc,
ty: IdlTypeDefinitionTy::Alias { value },
}))
Copy link
Contributor

Choose a reason for hiding this comment

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

This wouldn't support type aliases with lifetimes right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It supports the types that have FromStr implementation. It wouldn't support lifetimes because the IDL implementation itself doesn't support it.

Comment on lines +39 to +49
pub fn type_alias(
ctx: Context<TypeAlias>,
type_alias_u8: TypeAliasU8,
type_alias_u8_array: TypeAliasU8Array,
type_alias_struct: TypeAliasStruct,
) -> Result<()> {
ctx.accounts.account.type_alias_u8 = type_alias_u8;
ctx.accounts.account.type_alias_u8_array = type_alias_u8_array;
ctx.accounts.account.type_alias_struct = type_alias_struct;
Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice 🤌🏼

Comment on lines +166 to +171
case "alias": {
return IdlCoder.fieldLayout(
{ type: typeDef.type.value, name: typeDef.name },
types
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you dropped the catch-all else but didn't include a default case? ie:

default: {
   throw new Error(`Unknown type kind: ${typeDef}`);
}

The original is also spelled wrong lol (type kint)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I've dropped it because it should be unreachable, i.e. the value we are checking is generated from the IDL so it should never be outside of these specific cases.

@acheroncrypto acheroncrypto merged commit d1e3267 into coral-xyz:master Sep 27, 2023
46 checks passed
@acheroncrypto acheroncrypto mentioned this pull request Feb 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli enhancement New feature or request idl related to the IDL, either program or client side tests ts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't use idl with frontend - IdlError: Type not found Is any way to use type aliases?
2 participants