{"_id":"@algorandfoundation/algoland-sdk","_rev":"9-44fe0830987384ff1f6c557f50324e89","name":"@algorandfoundation/algoland-sdk","dist-tags":{"latest":"1.1.0"},"versions":{"0.0.1":{"name":"@algorandfoundation/algoland-sdk","version":"0.0.1","author":"","license":"MIT","_id":"@algorandfoundation/algoland-sdk@0.0.1","maintainers":[{"name":"bruno.martins.algorand.foundation","email":"bruno.martins@algorand.foundation"},{"name":"dev_algorand.foundation","email":"dev+npm@algorand.foundation"},{"name":"shane-at-algo","email":"shane.mcgovern@algorand.foundation"},{"name":"hmd2v","email":"yared@679labs.com"},{"name":"joe-p","email":"joepolny@gmail.com"}],"dist":{"shasum":"069d840c4aceae54fb28410e5544ce7e13cf3ea1","tarball":"https://registry.npmjs.org/@algorandfoundation/algoland-sdk/-/algoland-sdk-0.0.1.tgz","fileCount":1,"integrity":"sha512-cfB4dZYN9OdxUkiwHeDBHtlJEY+f+kZU9d4OY7X4O7WNLaYUP6uMHQ/4eTmerPNGYQYdQLxfK/t5oxrMIbhp/w==","signatures":[{"sig":"MEUCIGjjPf1wUE5g+0QTz52I1vkM8HG4iTCeF8I52iSTWPasAiEA7miL8bPS3w0xNu2YK3wYQQgDBlEcHS5HPt0/R2PKHlA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":228},"main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"dev_algorand.foundation","email":"dev+npm@algorand.foundation"},"_npmVersion":"10.9.2","directories":{},"_nodeVersion":"23.10.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/algoland-sdk_0.0.1_1755264596017_0.9406106374307734","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@algorandfoundation/algoland-sdk","version":"0.0.2","author":{"name":"Tasos Bitsios"},"license":"ISC","_id":"@algorandfoundation/algoland-sdk@0.0.2","maintainers":[{"name":"bruno.martins.algorand.foundation","email":"bruno.martins@algorand.foundation"},{"name":"dev_algorand.foundation","email":"dev+npm@algorand.foundation"},{"name":"shane-at-algo","email":"shane.mcgovern@algorand.foundation"},{"name":"hmd2v","email":"yared@679labs.com"},{"name":"joe-p","email":"joepolny@gmail.com"},{"name":"bitd13co","email":"bit@d13.co"}],"dist":{"shasum":"b02c797fdb432cdd43497520fab75e81231ff99b","tarball":"https://registry.npmjs.org/@algorandfoundation/algoland-sdk/-/algoland-sdk-0.0.2.tgz","fileCount":26,"integrity":"sha512-GAHWQF9AteAS4sbX59VmVSnhsRFv/lUdQFgPpS7AZWmbElyowr3Lwot8HSoyw/9kkGA2F0Qj93A4JGIHkv/NKQ==","signatures":[{"sig":"MEUCIFHcmF85qXMbZ9mj02tyWTdm1uulXXA0FryZkTlXJVVCAiEAkPZdnk/k1oSOvExJZ6Vdo61osUeUST7iy72gID1nKkQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":977986},"main":"dist/cjs/index.js","types":"dist/esm/index.d.ts","module":"dist/esm/index.js","exports":{".":{"import":"./dist/esm/index.js","require":"./dist/cjs/index.js"}},"gitHead":"713212c44edfa2f78db90108559d9568bb5e655e","scripts":{"build":"concurrently 'npm run build:cjs' 'npm run build:esm'","clean":"rm -rf dist/ src/generated/","generate":"npx @algorandfoundation/algokit-client-generator generate -o src/generated/AlgolandGenerated.ts -a ../algoland-contracts/smart_contracts/artifacts/algoland/Algoland.arc56.json","prebuild":"npm run clean && npm run generate","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json"},"_npmUser":{"name":"bitd13co","email":"bit@d13.co"},"_npmVersion":"10.9.2","description":"A TypeScript SDK for interacting with the Algoland smart contract on Algorand.","directories":{},"_nodeVersion":"22.17.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.3","@types/node":"^24.0.14","concurrently":"^9.2.0","@algorandfoundation/algokit-client-generator":"^6.0.0"},"peerDependencies":{"algosdk":"^3.0.0","@algorandfoundation/algokit-utils":"^9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/algoland-sdk_0.0.2_1755267929975_0.2702742341434423","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@algorandfoundation/algoland-sdk","version":"1.0.0","author":{"name":"Tasos Bitsios"},"license":"ISC","_id":"@algorandfoundation/algoland-sdk@1.0.0","maintainers":[{"name":"bruno.martins.algorand.foundation","email":"bruno.martins@algorand.foundation"},{"name":"dev_algorand.foundation","email":"dev+npm@algorand.foundation"},{"name":"shane-at-algo","email":"shane.mcgovern@algorand.foundation"},{"name":"hmd2v","email":"yared@679labs.com"},{"name":"joe-p","email":"joepolny@gmail.com"},{"name":"bitd13co","email":"bit@d13.co"},{"name":"krby","email":"kyle.breeding@algorand.foundation"}],"dist":{"shasum":"ed3a30b6947656d2e222781fbf2ea3ae9b491406","tarball":"https://registry.npmjs.org/@algorandfoundation/algoland-sdk/-/algoland-sdk-1.0.0.tgz","fileCount":56,"integrity":"sha512-5EAdm+QJGx54GI91G6gipNBF055yx+Gx3hxDR4w63jbV2ji8Psi2OdB1dXIEPLPWL3ATL/1Lqt9nL6ho660E6Q==","signatures":[{"sig":"MEUCIQCcTJqR7e2Mx0h6aJZVTF2AAIFF0nmLjvZHQjuvFL67xgIgcM/SS5u6xfoofITA38gi6z/gLplO7Jvo02OOauansHk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2113766},"main":"dist/cjs/index.js","types":"dist/esm/index.d.ts","module":"dist/esm/index.js","exports":{".":{"import":"./dist/esm/index.js","require":"./dist/cjs/index.js"}},"scripts":{"build":"concurrently 'npm run build:cjs' 'npm run build:esm'","clean":"rm -rf dist/ src/generated/","generate":"./scripts/generate.sh","prebuild":"npm run clean && npm run generate","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","print:fee-payer":"tsx scripts/print-funding-lsig-address.ts"},"_npmUser":{"name":"bitd13co","email":"bit@d13.co"},"_npmVersion":"7.14.0","description":"A TypeScript SDK for interacting with the Algoland smart contract on Algorand.","directories":{},"_nodeVersion":"16.20.0","dependencies":{"cids":"^1.1.9","multihashes":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","typescript":"^5.8.3","@types/node":"^24.0.14","concurrently":"^9.2.0","@algorandfoundation/algokit-client-generator":"^6.0.0"},"peerDependencies":{"algosdk":"^3.4.0","@algorandfoundation/algokit-utils":"^9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/algoland-sdk_1.0.0_1758127223352_0.8001176902686646","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@algorandfoundation/algoland-sdk","version":"1.1.0","author":{"name":"Tasos Bitsios"},"license":"ISC","_id":"@algorandfoundation/algoland-sdk@1.1.0","maintainers":[{"name":"bruno.martins.algorand.foundation","email":"bruno.martins@algorand.foundation"},{"name":"dev_algorand.foundation","email":"dev+npm@algorand.foundation"},{"name":"shane-at-algo","email":"shane.mcgovern@algorand.foundation"},{"name":"hmd2v","email":"yared@679labs.com"},{"name":"joe-p","email":"joepolny@gmail.com"},{"name":"bitd13co","email":"bit@d13.co"},{"name":"krby","email":"kyle.breeding@algorand.foundation"}],"dist":{"shasum":"3600a4238a1504fb303851e43a7a319a99ccaa3c","tarball":"https://registry.npmjs.org/@algorandfoundation/algoland-sdk/-/algoland-sdk-1.1.0.tgz","fileCount":56,"integrity":"sha512-rqeWhlJbd54mwBiNQnPuJxVeXMIj24j/t3weMaBthCra2kGRVjhyMflwwtybrr7aPkueWyNeQaQsRgZlg9Qf9A==","signatures":[{"sig":"MEUCIHBw5vcxQG7aXgBGnHeitbNgUJpl0DscskEt/PAYyWwgAiEAjOey4WHQkVSIIrentZHrEfv9vFs/woFZXrnOveF6A1I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2138028},"main":"dist/cjs/index.js","types":"dist/esm/index.d.ts","module":"dist/esm/index.js","exports":{".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.js"}}},"gitHead":"15e64c035bb52e9c5d00f62e3b69eb9c13b308f8","scripts":{"test":"npm run test:smoke","build":"concurrently 'npm run build:cjs' 'npm run build:esm'","clean":"rm -rf dist/ src/generated/","generate":"./scripts/generate.sh","prebuild":"npm run clean && npm run generate","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc --project tsconfig.esm.json","test:smoke":"node test/smoke-test.js","print:fee-payer":"tsx scripts/print-funding-lsig-address.ts"},"_npmUser":{"name":"bitd13co","email":"bit@d13.co"},"_npmVersion":"10.9.3","description":"A TypeScript SDK for interacting with the Algoland smart contract on Algorand.","directories":{},"_nodeVersion":"22.19.0","dependencies":{"cids":"^1.1.9","multihashes":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","typescript":"^5.8.3","@types/node":"^24.0.14","concurrently":"^9.2.0","@algorandfoundation/algokit-client-generator":"^6.0.0"},"peerDependencies":{"algosdk":"^3.4.0","@algorandfoundation/algokit-utils":"^9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/algoland-sdk_1.1.0_1758484539352_0.7299830129595961","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-08-15T13:29:55.904Z","modified":"2026-04-08T12:47:12.304Z","0.0.1":"2025-08-15T13:29:56.192Z","0.0.2":"2025-08-15T14:25:30.229Z","1.0.0":"2025-09-17T16:40:23.604Z","1.1.0":"2025-09-21T19:55:39.564Z"},"author":{"name":"Tasos Bitsios"},"license":"ISC","description":"A TypeScript SDK for interacting with the Algoland smart contract on Algorand.","maintainers":[{"email":"bruno.martins@algorand.foundation","name":"bruno.martins.algorand.foundation"},{"email":"dev+npm@algorand.foundation","name":"dev_algorand.foundation"},{"email":"shane.mcgovern@algorand.foundation","name":"shane-at-algo"},{"email":"joepolny@gmail.com","name":"joe-p"},{"email":"bit@d13.co","name":"bitd13co"},{"email":"kyle.breeding@algorand.foundation","name":"krby"}],"readme":"# Algoland SDK\n\nA TypeScript SDK for interacting with the Algoland smart contract on Algorand.\n\n## Installation\n\n```bash\nnpm install @algorandfoundation/algoland-sdk\n```\n\n## Requirements\n\nYour package should install the peer requirements **with the exact version matcher**:\n\n```json\n{\n  \"dependencies\": {\n    \"@algorandfoundation/algokit-utils\": \"^9.0.0\",\n    \"algosdk\": \"^3.0.0\"\n  }\n}\n```\n\nConfirm the SDK's package.json for the latest peerDependencies.\n\n## Usage\n\n### Creating an SDK Instance\n\n```typescript\nimport { AlgolandSDK } from '@algorandfoundation/algoland-sdk';\nimport { AlgorandClient } from '@algorandfoundation/algokit-utils/types/algorand-client';\n\nconst appId = 3215540125n; // Mainnet contract App ID\nconst algorand = AlgorandClient.mainNet()\n\n// Basic instantiation\nconst sdk = new AlgolandSDK({ appId, algorand });\n```\n\n### Usage with `@txnlab/use-wallet`\n\n```typescript\nimport { useWallet } from '@txnlab/use-wallet';\n\nconst { algodClient, transactionSigner, activeAddress } = useWallet();\nconst algorand = AlgorandClient.fromClients({ algod: algodClient });\nconst sdk = new AlgolandSDK({ appId, algorand });\n```\n\n## API Reference\n\n### Global State\n\nGet the global state of the Algoland contract:\n\n```typescript\nconst globalState = await sdk.getGlobalState();\n// Returns:\n// {\n//   admin: \"ADMIN_ADDRESS_HERE...\",\n//   userCounter: 1234n,\n//   drawAppId: 5678n,\n//   backend: \"BACKEND_ADDRESS_HERE...\"\n// }\n```\n\n### User Methods\n\n#### Get User by ID or Address\n\n```typescript\n// Get user by ID\nconst userById = await sdk.getUser({ userId: 1n });\n// Returns:\n// {\n//   address: \"ABCDEF..FEDCBA\",\n//   relativeId: 1,\n//   referrerId: 0,\n//   numReferrals: 3,\n//   referrals: [2, 5, 8],\n//   points: 59,                        // 30 (own quests) + 9 (referral points) + 20 (redeemed back in)\n//   redeemedPoints: 20,                // Points that were redeemed from prizes\n//   completedQuests: [1, 2, 3],        // 3 completed quests = 30 points\n//   completableChallenges: [2],\n//   completedChallenges: [1],\n//   weeklyDrawEligibility: [1],\n//   availableDrawPrizeAssetIds: [123456n, 789012n],\n//   claimedDrawPrizeAssetIds: [111111n],\n//   displayPoints: 5900,               // 59 × 100\n//   displayRedeemedPoints: 2000,       // 20 × 100\n//   referralPoints: 9,                 // 59 - 30 (quest points) - 20 (redeemed) = 9\n//   displayReferralPoints: 900         // 9 × 100\n// }\n\n// Get user by address\nconst userByAddress = await sdk.getUser({ userAddress: 'ABCDEF..FEDCBA' });\n// Returns the same structure as above, or undefined if user not found\n```\n\n#### Get Multiple Users\n\n```typescript\nconst userAddresses = ['ADDRESS1', 'ADDRESS2', 'ADDRESS3'];\nconst usersMap = await sdk.getUsers({ userAddresses });\n// Returns: Map<string, AlgolandUser | undefined>\n// Map {\n//   'ADDRESS1' => { address: 'ADDRESS1', relativeId: 1, ... },\n//   'ADDRESS2' => undefined, // user not found\n//   'ADDRESS3' => { address: 'ADDRESS3', relativeId: 5, ... }\n// }\n```\n\n#### Get All Users\n\n```typescript\nconst allUsersMap = await sdk.getAllUsers();\n// Returns: Map<string, AlgolandUser | undefined>\n// Same structure as getUsers but contains all users registered in the system\n```\n\n#### Get User Referrals\n\n```typescript\n// By user ID\nconst referrals = await sdk.getUserReferrals({ userId: 1 });\n// Returns: string[]\n// ['ADDRESS1', 'ADDRESS2', 'ADDRESS3']\n\n// By user address\nconst referrals = await sdk.getUserReferrals({ userAddress: 'ADDRESS' });\n// Returns: string[] - array of referral addresses\n```\n\n### Quest Methods\n\n#### Get All Quests\n\n```typescript\nconst questsMap = await sdk.getQuests();\n// Returns: Map<number, AlgolandQuest>\n// Map {\n//   1 => { id: 1, name: \"Complete First Challenge\", challengeId: 1 },\n//   2 => { id: 2, name: \"Refer 5 Friends\", challengeId: 2 },\n//   3 => { id: 3, name: \"Earn 100 Points\", challengeId: 1 }\n// }\n```\n\n#### Get Quest by ID\n\n```typescript\nconst quest = await sdk.getQuestById(1);\n// Returns: AlgolandQuest | undefined\n// { id: 1, name: \"Complete First Challenge\", challengeId: 1 }\n// or undefined if quest not found\n```\n\n### Challenge Methods\n\n#### Get All Challenges\n\n```typescript\nconst challengesMap = await sdk.getChallenges();\n// Returns: Map<number, AlgolandChallenge>\n// Map {\n//   1 => {\n//     id: 1,\n//     questIds: [1, 2],\n//     completionBadgeAssetId: 123456n,\n//     timeStart: 1640995200,\n//     timeEnd: 1672531200,\n//     numRequiredQuestsCompleted: 2,\n//     drawPrizeAssetIds: [789012n],\n//     numDrawEligibleAccounts: 100,\n//     numDrawWinners: 10,\n//     winners: [1, 5, 12, 23, 45]\n//   }\n// }\n```\n\n#### Get Challenge by ID\n\n```typescript\nconst challenge = await sdk.getChallengeById(1);\n// Returns: AlgolandChallenge | undefined\n// {\n//   id: 1,\n//   questIds: [1, 2],\n//   completionBadgeAssetId: 123456n,\n//   timeStart: 1640995200,\n//   timeEnd: 1672531200,\n//   numRequiredQuestsCompleted: 2,\n//   drawPrizeAssetIds: [789012n],\n//   numDrawEligibleAccounts: 100,\n//   numDrawWinners: 10,\n//   winners: [1, 5, 12, 23, 45]\n// }\n// or undefined if challenge not found\n```\n\n## Transaction Methods\n\n### User Enrollment\n\nEnroll a user into the campaign:\n\n```typescript\nconst { transactionSigner, activeAddress } = useWallet();\n\nconst result = await sdk.enrollCampaign({\n  referrerId: 0n, // no referrer, or use a valid user ID\n  sender: activeAddress,\n  signer: transactionSigner,\n});\n// Returns: SendAppTransactionResult with transaction details and app return values\n// {\n//   transaction: Transaction,\n//   confirmation: PendingTransactionResponse,\n//   return: {\n//     relativeId: 123,      // user's new relative ID\n//     referrerId: 0,        // referrer ID (0 if no referrer)\n//     numReferrals: 0,      // initial referral count\n//     referrals: [],        // initial empty referrals array\n//     points: 0,            // initial points\n//     completedQuests: [],  // initial empty completed quests\n//     completableChallenges: [], // challenges available to complete\n//     completedChallenges: [],   // initial empty completed challenges\n//     availableDrawPrizeAssetIds: [] // initial empty available prizes\n//   }\n// }\n```\n\n### Complete Challenge\n\nComplete a challenge and claim the badge:\n\n```typescript\nconst result = await sdk.completeChallenge({\n  challengeId: 1,\n  sender: activeAddress,\n  signer: transactionSigner,\n});\n// Returns: SendAtomicTransactionComposerResults\n// {\n//   transactions: Transaction[],\n//   confirmations: PendingTransactionResponse[],\n//   returns: [], // void method returns empty array\n//   txIds: ['TXN_ID_1', 'TXN_ID_2'] // may include asset opt-in transaction\n// }\n```\n\n## Admin Methods\n\n*Note: These methods require admin or backend permissions*\n\n### Quest Management\n\n```typescript\n// Complete a quest for a user (backend only)\nconst result = await sdk.completeQuest({\n  questId: 1,\n  user: 'USER_ADDRESS',\n  sender: backendAddress,\n  signer: backendSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Add a new quest (admin only)\nconst result = await sdk.addQuest({\n  questId: 1,\n  name: 'Quest Name',\n  challengeId: 1,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Delete a quest (admin only)\nconst result = await sdk.deleteQuest({\n  questId: 1,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n```\n\n### Challenge Management\n\n```typescript\n// Add a new challenge (admin only)\nconst result = await sdk.addChallenge({\n  challengeId: 1,\n  challenge: challengeObject,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Edit an existing challenge (admin only)\nconst result = await sdk.editChallenge({\n  challengeId: 1,\n  challenge: updatedChallengeObject,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Delete a challenge (admin only)\nconst result = await sdk.deleteChallenge({\n  challengeId: 1,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n```\n\n### Asset Management\n\n```typescript\n// Opt the contract into an asset (admin only)\nconst result = await sdk.optinAsset({\n  asset: assetId,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Opt in and send asset to contract (admin only)\nconst result = await sdk.optinAndSendAsset({\n  asset: assetId,\n  amount: 1000n,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAtomicTransactionComposerResults\n// {\n//   transactions: Transaction[], // optin + transfer transactions\n//   confirmations: PendingTransactionResponse[],\n//   returns: [],\n//   txIds: ['OPTIN_TXN_ID', 'TRANSFER_TXN_ID']\n// }\n```\n\n### Administrative Functions\n\n```typescript\n// Change backend address (admin only)\nconst result = await sdk.changeBackend({\n  newBackend: 'NEW_BACKEND_ADDRESS',\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Change admin address (admin only)\nconst result = await sdk.changeAdmin({\n  newAdmin: 'NEW_ADMIN_ADDRESS',\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n\n// Change draw app ID (admin only)\nconst result = await sdk.changeDrawAppId({\n  newDrawAppId: 5678n,\n  sender: adminAddress,\n  signer: adminSigner,\n});\n// Returns: SendAppTransactionResult (void method)\n// { transaction: Transaction, confirmation: PendingTransactionResponse }\n```\n\n## Types\n\nThe SDK exports all relevant types from the generated client and defines additional helper types:\n\n```typescript\nimport {\n  AlgolandUser,\n  AlgolandQuest,\n  AlgolandChallenge,\n  AlgolandGlobalState,\n  DrawGlobalState,\n  AlgolandWeeklyDrawState,\n  NFTSpecWithCID,\n  PointsNFTSpecWithCID\n} from '@algorandfoundation/algoland-sdk';\n```\n\n### Core Types\n\n#### AlgolandUser\n\nRepresents a user in the Algoland system with all their quest progress and achievements:\n\n```typescript\ntype AlgolandUser = {\n  address: string;                     // User's Algorand address\n  relativeId: number;                  // Small incremental user ID (1, 2, 3...)\n  referrerId: number;                  // RelativeId of the referrer\n  numReferrals: number;                // Number of referrals\n  referrals: number[];                 // Referrals' relative IDs\n  points: number;                      // Accumulated points\n  redeemedPoints: number;              // Redeemed points: points from redeeming Points prize assets\n  completedQuests: number[];           // Individual quests completed\n  completableChallenges: number[];     // Challenges that are ready to complete (by claiming NFT)\n  completedChallenges: number[];       // Completed challenges\n  weeklyDrawEligibility: number[];     // Weekly draw eligibility: completed challenges in time (values are challengeId)\n  availableDrawPrizeAssetIds: bigint[]; // Available prizes (asset IDs) from weekly/final VRF draws\n  claimedDrawPrizeAssetIds: bigint[];  // Claimed prizes (asset IDs) from weekly/final VRF draws\n\n  // Computed properties (getters)\n  displayPoints: number;               // Display-friendly points value (multiplied by display multiplier)\n  displayRedeemedPoints: number;       // Display-friendly redeemed points value (multiplied by display multiplier)\n  referralPoints: number;              // Points earned from referrals (total points minus own quest points and redeemed points)\n  displayReferralPoints: number;       // Display-friendly referral points value (multiplied by display multiplier)\n}\n```\n\n#### AlgolandQuest\n\nRepresents a quest that users can complete to earn points and progress in challenges:\n\n```typescript\ntype AlgolandQuest = {\n  id: number;                   // Unique quest identifier\n  name: string;                 // Human-readable quest name\n  challengeId: number;          // ID of the challenge this quest belongs to\n}\n```\n\n#### AlgolandChallenge\n\nRepresents a challenge that groups multiple quests and offers rewards:\n\n```typescript\ntype AlgolandChallenge = {\n  id: number;                           // Unique challenge identifier\n  questIds: number[];                   // Quest IDs for this challenge\n  completionBadgeAssetId: bigint;       // Badge asset ID given out for completing the challenge (including after time end)\n  timeStart: number;                    // Start time of challenge\n  timeEnd: number;                      // End time of challenge. Only affects eligibility for weekly VRF draw. Challenge can be completed after this time\n  numRequiredQuestsCompleted: number;   // Number of quest completions required to mark this challenge as complete. Usually equals to number of quests\n  drawPrizeAssetIds: bigint[];          // Asset prize asset IDs for weekly draws\n  numDrawEligibleAccounts: number;      // Tracks the number of accounts eligible for the weekly VRF draw\n  numDrawWinners: number;               // Number of winners to be picked at the weekly VRF draw\n  winners: number[];                    // Relative ID of weekly draw winners\n}\n```\n\n#### AlgolandGlobalState\n\nRepresents the global state of the Algoland smart contract:\n\n```typescript\ntype AlgolandGlobalState = {\n  admin: string;                // Address of the contract administrator\n  userCounter: bigint;          // Total number of registered users\n  drawAppId: bigint;            // App ID of the weekly draw contract\n  backend: string;              // Address authorized to complete quests\n}\n```\n\n#### DrawGlobalState\n\nRepresents the global state of the weekly draw smart contract:\n\n```typescript\ntype DrawGlobalState = {\n  admin: string;                // Address of the draw contract administrator\n  backend: string;              // Address authorized to operate the draw contract\n  beaconAppId: bigint;          // App ID of the VRF beacon contract\n  registryAppId: bigint;        // App ID of the main Algoland registry contract\n}\n```\n\n#### AlgolandWeeklyDrawState\n\nRepresents the state of a weekly draw for a specific challenge:\n\n```typescript\ntype AlgolandWeeklyDrawState = {\n  status: 'BLD' | 'RST' | 'RUN' | 'END';  // Build/Reset/Run/End status of the draw\n  accountsIngested: bigint;               // Number of accounts processed for the draw\n  lastRelativeId: bigint;                 // Last user relative ID processed\n  commitBlocks: bigint[];                 // Block numbers used for VRF commit rounds\n  winners: number[];                      // Relative IDs of draw winners\n  txIds: Uint8Array[];                    // Transaction IDs associated with the draw\n}\n```\n\n#### NFTSpecWithCID\n\nRepresents an NFT specification with optional IPFS CID:\n\n```typescript\ntype NFTSpecWithCID = {\n  total: bigint;                // Total supply of the NFT\n  assetName: string;            // Asset name\n  unitName: string;             // Unit name\n  url: string;                  // Asset URL\n  freeze: string;               // Freeze address\n  clawback: string;             // Clawback address\n  reserve: string;              // Reserve address\n  metadataHash: Uint8Array;     // Metadata hash (32 bytes)\n  ipfsCid?: string;             // Optional IPFS CID for metadata\n}\n```\n\n#### PointsNFTSpecWithCID\n\nRepresents an NFT specification for points-based assets:\n\n```typescript\ntype PointsNFTSpecWithCID = NFTSpecWithCID & {\n  points: number;               // Points value associated with this NFT\n}\n```\n\n### Event Types\n\nThese types represent events emitted by the smart contract (useful for indexing and monitoring):\n\n#### QuestCompletionEvent\n\nEmitted when a user completes a quest:\n\n```typescript\ntype QuestCompletionEvent = {\n  account: string;              // Address of the user completing the quest\n  userId: number;               // Relative ID of the user\n  questId: number;              // ID of the completed quest\n  challengeId: number;          // ID of the challenge the quest belongs to\n}\n```\n\n#### ChallengeCompletableEvent\n\nEmitted when a user becomes eligible to complete a challenge:\n\n```typescript\ntype ChallengeCompletableEvent = {\n  account: string;              // Address of the user\n  userId: number;               // Relative ID of the user\n  challengeId: number;          // ID of the challenge now available to complete\n}\n```\n\n#### ChallengeCompletedEvent\n\nEmitted when a user completes a challenge and claims the NFT:\n\n```typescript\ntype ChallengeCompletedEvent = {\n  account: string;              // Address of the user\n  userId: number;               // Relative ID of the user\n  challengeId: number;          // ID of the completed challenge\n}\n```\n\n#### PointsEvent\n\nEmitted when points are awarded to a user:\n\n```typescript\ntype PointsEvent = {\n  account: string;              // Address of the user receiving points\n  userId: number;               // Relative ID of the user receiving points\n  questId: number;              // ID of the quest that generated the points\n  addedPoints: number;          // Number of points added in this event\n  totalPoints: number;          // User's total points after this addition\n  actorUserId: number;          // ID of the user who triggered the points:\n                               // - If points from own completion: actorUserId === userId\n                               // - If referral points: actorUserId = referred user, userId = referrer\n}\n```\n\n### Type Usage Examples\n\n#### Working with Users\n\n```typescript\nconst user: AlgolandUser = await sdk.getUser({ userId: 1n });\n\nif (user) {\n  console.log(`User ${user.address} has ${user.points} points (display: ${user.displayPoints})`);\n  // Output: User ABCDEF..FEDCBA has 59 points (display: 5900)\n  \n  console.log(`Completed quests: ${user.completedQuests.join(', ')}`);\n  // Output: Completed quests: 1, 2, 3\n  \n  console.log(`Ready to claim challenges: ${user.completableChallenges.join(', ')}`);\n  // Output: Ready to claim challenges: 2\n  \n  console.log(`Completed challenges: ${user.completedChallenges.join(', ')}`);\n  // Output: Completed challenges: 1\n  \n  // Check points breakdown\n  console.log(`Total display points: ${user.displayPoints}`);\n  // Output: Total display points: 5900\n  \n  console.log(`Referral display points: ${user.displayReferralPoints}`);\n  // Output: Referral display points: 900\n  \n  console.log(`Redeemed display points: ${user.displayRedeemedPoints}`);\n  // Output: Redeemed display points: 2000\n  \n  // Check weekly draw eligibility\n  if (user.weeklyDrawEligibility.length > 0) {\n    console.log(`Eligible for weekly draws: ${user.weeklyDrawEligibility.join(', ')}`);\n    // Output: Eligible for weekly draws: 1\n  }\n  \n  // Check available prizes\n  if (user.availableDrawPrizeAssetIds.length > 0) {\n    console.log(`Available prizes: ${user.availableDrawPrizeAssetIds.join(', ')}`);\n    // Output: Available prizes: 123456, 789012\n  }\n\n  // Check if user has referrals\n  if (user.numReferrals > 0) {\n    console.log(`User has referred ${user.numReferrals} users`);\n    // Output: User has referred 3 users\n    \n    const referralAddresses = await sdk.getUserReferrals({ userId: user.relativeId });\n    console.log(`Referral addresses: ${referralAddresses.join(', ')}`);\n    // Output: Referral addresses: ADDRESS1, ADDRESS2, ADDRESS3\n  }\n}\n```\n\n#### Working with Challenges\n\n```typescript\nconst challenge: AlgolandChallenge = await sdk.getChallengeById(1);\n\nif (challenge) {\n  const now = Math.floor(Date.now() / 1000);\n  const isActive = now >= challenge.timeStart && now <= challenge.timeEnd;\n\n  console.log(`Challenge \"${challenge.id}\" is ${isActive ? 'active' : 'inactive'}`);\n  console.log(`Requires ${challenge.numRequiredQuestsCompleted} quests to complete`);\n  console.log(`Completion badge: Asset ID ${challenge.completionBadgeAssetId}`);\n\n  if (challenge.winners.length > 0) {\n    console.log(`Draw winners: ${challenge.winners.join(', ')}`);\n  }\n}\n```\n\n## Error Handling\n\nAll async methods may throw errors. It's recommended to wrap calls in try-catch blocks:\n\n```typescript\ntry {\n  const user = await sdk.getUser({ userId: 1n });\n  console.log('User found:', user);\n} catch (error) {\n  console.error('Failed to get user:', error.message);\n}\n```\n","readmeFilename":"README.md"}