{"version":3,"file":"nft.cjs","sources":["../../../src/states/nft.ts"],"sourcesContent":["import {\r\n  Address,\r\n  Base58EncodedBytes,\r\n  GetAccountInfoApi,\r\n  GetProgramAccountsApi,\r\n  Rpc,\r\n  fetchEncodedAccount,\r\n  getProgramDerivedAddress,\r\n} from \"@solana/kit\";\r\nimport { deserialize } from \"borsh\";\r\n\r\nimport { addressCodec, base64Codec, utf8Codec } from \"../codecs\";\r\nimport { NAME_TOKENIZER_ADDRESS } from \"../constants/addresses\";\r\nimport { InvalidSerializedDataError, NftAccountNotFoundError } from \"../errors\";\r\n\r\nexport enum NftTag {\r\n  Uninitialized = 0,\r\n  CentralState = 1,\r\n  ActiveRecord = 2,\r\n  InactiveRecord = 3,\r\n}\r\n\r\nexport class NftState {\r\n  tag: NftTag;\r\n  nonce: number;\r\n  nameAccount: Address;\r\n  owner: Address;\r\n  nftMint: Address;\r\n\r\n  static schema = {\r\n    struct: {\r\n      tag: \"u8\",\r\n      nonce: \"u8\",\r\n      nameAccount: { array: { type: \"u8\", len: 32 } },\r\n      owner: { array: { type: \"u8\", len: 32 } },\r\n      nftMint: { array: { type: \"u8\", len: 32 } },\r\n    },\r\n  };\r\n\r\n  // The total length of the struct is calculated as the sum of:\r\n  // - `tag`: 1 byte (`u8`)\r\n  // - `nonce`: 1 byte (`u8`)\r\n  // - `nameAccount`: 32 bytes (array of `u8` with length 32)\r\n  // - `owner`: 32 bytes (array of `u8` with length 32)\r\n  // - `nftMint`: 32 bytes (array of `u8` with length 32)\r\n  static LEN = 1 + 1 + 32 + 32 + 32;\r\n\r\n  constructor(obj: {\r\n    tag: number;\r\n    nonce: number;\r\n    nameAccount: Uint8Array;\r\n    owner: Uint8Array;\r\n    nftMint: Uint8Array;\r\n  }) {\r\n    this.tag = obj.tag as NftTag;\r\n    this.nonce = obj.nonce;\r\n    this.nameAccount = addressCodec.decode(obj.nameAccount);\r\n    this.owner = addressCodec.decode(obj.owner);\r\n    this.nftMint = addressCodec.decode(obj.nftMint);\r\n  }\r\n\r\n  static deserialize(data: Uint8Array): NftState {\r\n    try {\r\n      return new NftState(deserialize(this.schema, data) as any);\r\n    } catch {\r\n      throw new InvalidSerializedDataError(\r\n        \"Failed to deserialize NftState data\"\r\n      );\r\n    }\r\n  }\r\n\r\n  static async retrieve(\r\n    rpc: Rpc<GetAccountInfoApi>,\r\n    address: Address\r\n  ): Promise<NftState> {\r\n    const nftAccount = await fetchEncodedAccount(rpc, address);\r\n    if (!nftAccount.exists) {\r\n      throw new NftAccountNotFoundError(`NFT not found: ${address}`);\r\n    }\r\n    return this.deserialize(nftAccount.data);\r\n  }\r\n\r\n  static async retrieveFromMint(\r\n    rpc: Rpc<GetProgramAccountsApi>,\r\n    mint: Address\r\n  ): Promise<NftState> {\r\n    const data = await rpc\r\n      .getProgramAccounts(NAME_TOKENIZER_ADDRESS, {\r\n        encoding: \"base64\",\r\n        filters: [\r\n          { dataSize: BigInt(NftState.LEN) },\r\n          {\r\n            memcmp: {\r\n              offset: BigInt(0),\r\n              bytes: \"3\" as Base58EncodedBytes,\r\n              encoding: \"base58\",\r\n            },\r\n          },\r\n          {\r\n            memcmp: {\r\n              offset: BigInt(1 + 1 + 32 + 32),\r\n              bytes: mint as string as Base58EncodedBytes,\r\n              encoding: \"base58\",\r\n            },\r\n          },\r\n        ],\r\n      })\r\n      .send();\r\n\r\n    if (data.length !== 1) {\r\n      throw new NftAccountNotFoundError(`NFT not found: ${mint}`);\r\n    }\r\n\r\n    return this.deserialize(\r\n      base64Codec.encode(data[0].account.data[0]) as Uint8Array\r\n    );\r\n  }\r\n\r\n  static async getAddress(domainAddress: Address): Promise<Address> {\r\n    const [address] = await getProgramDerivedAddress({\r\n      programAddress: NAME_TOKENIZER_ADDRESS,\r\n      seeds: [\r\n        utf8Codec.encode(\"nft_record\"),\r\n        addressCodec.encode(domainAddress),\r\n      ],\r\n    });\r\n\r\n    return address;\r\n  }\r\n}\r\n"],"names":["NftTag","NftState","tag","nonce","nameAccount","owner","nftMint","static","struct","array","type","len","constructor","obj","this","addressCodec","decode","deserialize","data","schema","InvalidSerializedDataError","retrieve","rpc","address","nftAccount","fetchEncodedAccount","exists","NftAccountNotFoundError","retrieveFromMint","mint","getProgramAccounts","NAME_TOKENIZER_ADDRESS","encoding","filters","dataSize","BigInt","LEN","memcmp","offset","bytes","send","length","base64Codec","encode","account","getAddress","domainAddress","getProgramDerivedAddress","programAddress","seeds","utf8Codec"],"mappings":"iBAeYA,8KAAAA,QAAAA,YAAAA,GAAAA,EAAAA,QAAMA,SAANA,eAKX,CAAA,IAJCA,EAAA,cAAA,GAAA,gBACAA,EAAAA,EAAA,aAAA,GAAA,eACAA,EAAAA,EAAA,aAAA,GAAA,eACAA,EAAAA,EAAA,eAAA,GAAA,uBAGWC,EACXC,IACAC,MACAC,YACAC,MACAC,QAEAC,cAAgB,CACdC,OAAQ,CACNN,IAAK,KACLC,MAAO,KACPC,YAAa,CAAEK,MAAO,CAAEC,KAAM,KAAMC,IAAK,KACzCN,MAAO,CAAEI,MAAO,CAAEC,KAAM,KAAMC,IAAK,KACnCL,QAAS,CAAEG,MAAO,CAAEC,KAAM,KAAMC,IAAK,OAUzCJ,WAAa,GAEb,WAAAK,CAAYC,GAOVC,KAAKZ,IAAMW,EAAIX,IACfY,KAAKX,MAAQU,EAAIV,MACjBW,KAAKV,YAAcW,EAAAA,aAAaC,OAAOH,EAAIT,aAC3CU,KAAKT,MAAQU,EAAAA,aAAaC,OAAOH,EAAIR,OACrCS,KAAKR,QAAUS,EAAAA,aAAaC,OAAOH,EAAIP,SAGzC,kBAAOW,CAAYC,GACjB,IACE,OAAO,IAAIjB,EAASgB,EAAWA,YAACH,KAAKK,OAAQD,IAC7C,MACA,MAAM,IAAIE,EAA0BA,2BAClC,wCAKN,qBAAaC,CACXC,EACAC,GAEA,MAAMC,QAAmBC,sBAAoBH,EAAKC,GAClD,IAAKC,EAAWE,OACd,MAAM,IAAIC,EAAAA,wBAAwB,kBAAkBJ,KAEtD,OAAOT,KAAKG,YAAYO,EAAWN,MAGrC,6BAAaU,CACXN,EACAO,GAEA,MAAMX,QAAaI,EAChBQ,mBAAmBC,EAAAA,uBAAwB,CAC1CC,SAAU,SACVC,QAAS,CACP,CAAEC,SAAUC,OAAOlC,EAASmC,MAC5B,CACEC,OAAQ,CACNC,OAAQH,OAAO,GACfI,MAAO,IACPP,SAAU,WAGd,CACEK,OAAQ,CACNC,OAAQH,OAAO,IACfI,MAAOV,EACPG,SAAU,cAKjBQ,OAEH,GAAoB,IAAhBtB,EAAKuB,OACP,MAAM,IAAId,EAAAA,wBAAwB,kBAAkBE,KAGtD,OAAOf,KAAKG,YACVyB,EAAWA,YAACC,OAAOzB,EAAK,GAAG0B,QAAQ1B,KAAK,KAI5C,uBAAa2B,CAAWC,GACtB,MAAOvB,SAAiBwB,2BAAyB,CAC/CC,eAAgBjB,EAAsBA,uBACtCkB,MAAO,CACLC,EAASA,UAACP,OAAO,cACjB5B,EAAYA,aAAC4B,OAAOG,MAIxB,OAAOvB"}