{"_id":"@anastasia-labs/payment-subscription-offchain","_rev":"6-b35f99a664dc45c273be4e6edd9f8638","name":"@anastasia-labs/payment-subscription-offchain","dist-tags":{"latest":"1.1.2"},"versions":{"1.0.0":{"name":"@anastasia-labs/payment-subscription-offchain","version":"1.0.0","keywords":[],"author":"","license":"ISC","_id":"@anastasia-labs/payment-subscription-offchain@1.0.0","maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"dist":{"shasum":"fe5053c0b917040edf64d71a6fc53772f1615122","tarball":"https://registry.npmjs.org/@anastasia-labs/payment-subscription-offchain/-/payment-subscription-offchain-1.0.0.tgz","fileCount":5,"integrity":"sha512-5e9wQ8ml1WIXkQRlgAT0NwXBCa/dpvOM6lRxwAVfbOzw4kCWgPk1Z9JlADyDiERlke/zWqIjSzTiZF7JuTRD4g==","signatures":[{"sig":"MEUCIA+MJBArrmlqDwkZmNSdFZNjbswtiU61T12JFmg9zGA+AiEA5E5x14n6jwS/vCkRvIiN0VONDWhGG2hcEeSXsZSgi6E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":87494},"main":"./dist/index.js","type":"module","_from":"file:anastasia-labs-payment-subscription-offchain-1.0.0.tgz","types":"./dist/index.d.ts","scripts":{"lint":"eslint","test":"export NODE_ENV='emulator' && vitest run","build":"tsup src/index.ts --minify --format esm,cjs --dts --clean","repack":"pnpm run build  && pnpm pack","ts-node":"ts-node"},"_npmUser":{"name":"anastasia-labs","email":"info@anastasialabs.com"},"_resolved":"/tmp/de33c680f1413c6c5b6bcb411ea3e1b1/anastasia-labs-payment-subscription-offchain-1.0.0.tgz","_integrity":"sha512-5e9wQ8ml1WIXkQRlgAT0NwXBCa/dpvOM6lRxwAVfbOzw4kCWgPk1Z9JlADyDiERlke/zWqIjSzTiZF7JuTRD4g==","_npmVersion":"10.8.2","description":"Off-Chain SDK for Payment Subscription Smart Contract","directories":{"test":"test"},"_nodeVersion":"18.20.5","dependencies":{"dotenv":"^16.4.7","effect":"^3.11.2","@noble/hashes":"^1.6.1","@lucid-evolution/lucid":"0.4.16"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247","devDependencies":{"tsup":"^6.7.0","eslint":"^8.57.1","vitest":"0.34.6","ts-node":"^10.9.2","typescript":"^5.6.3","@types/node":"^20.17.6","@noble/hashes":"^1.5.0","@sinclair/typebox":"^0.25.24","eslint-config-prettier":"^8.10.0","@typescript-eslint/parser":"^5.62.0","@typescript-eslint/eslint-plugin":"^5.62.0"},"_npmOperationalInternal":{"tmp":"tmp/payment-subscription-offchain_1.0.0_1734711261803_0.2954363775117985","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@anastasia-labs/payment-subscription-offchain","version":"1.0.3","keywords":[],"author":"","license":"ISC","_id":"@anastasia-labs/payment-subscription-offchain@1.0.3","maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"dist":{"shasum":"194d38e4987c683956c635ef216f8c9dcf0982f2","tarball":"https://registry.npmjs.org/@anastasia-labs/payment-subscription-offchain/-/payment-subscription-offchain-1.0.3.tgz","fileCount":5,"integrity":"sha512-2VsiA2l47SVJ/enUppzc8TmIfiLP3/1w67izeCVRLVh+/PcGGuin/hmjs1ibglNxBCbupIseCGD4kYh7fMiWHQ==","signatures":[{"sig":"MEUCIQD734bzx7jMtA4GnnTbW0EE3dcNUoXUdN91ZeOy7w2C4gIgGFKWbZ0wcR4cNK+sYSiKTJaD90Xu8R8zGqueOg6IB3A=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":318540},"main":"./dist/index.js","type":"module","_from":"file:anastasia-labs-payment-subscription-offchain-1.0.3.tgz","types":"./dist/index.d.ts","scripts":{"lint":"eslint","test":"export NODE_ENV='emulator' && vitest run","build":"tsup src/index.ts --minify --format esm,cjs --dts --clean","repack":"pnpm run build && pnpm pack","ts-node":"ts-node"},"_npmUser":{"name":"anastasia-labs","email":"info@anastasialabs.com"},"_resolved":"/tmp/bf27901601cd11b2c27b251bf991ea00/anastasia-labs-payment-subscription-offchain-1.0.3.tgz","_integrity":"sha512-2VsiA2l47SVJ/enUppzc8TmIfiLP3/1w67izeCVRLVh+/PcGGuin/hmjs1ibglNxBCbupIseCGD4kYh7fMiWHQ==","_npmVersion":"10.8.2","description":"Off-Chain SDK for Payment Subscription Smart Contract","directories":{"test":"test"},"_nodeVersion":"18.20.5","dependencies":{"dotenv":"^16.4.7","effect":"^3.11.2","@noble/hashes":"^1.6.1","@lucid-evolution/lucid":"0.4.16"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247","devDependencies":{"tsup":"^6.7.0","eslint":"^8.57.1","vitest":"0.34.6","ts-node":"^10.9.2","typescript":"^5.6.3","@types/node":"^20.17.6","@noble/hashes":"^1.5.0","@sinclair/typebox":"^0.25.24","eslint-config-prettier":"^8.10.0","@typescript-eslint/parser":"^5.62.0","@typescript-eslint/eslint-plugin":"^5.62.0"},"_npmOperationalInternal":{"tmp":"tmp/payment-subscription-offchain_1.0.3_1735926709812_0.519334674440249","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@anastasia-labs/payment-subscription-offchain","version":"1.0.4","keywords":[],"author":"","license":"ISC","_id":"@anastasia-labs/payment-subscription-offchain@1.0.4","maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"dist":{"shasum":"7901033d9314e4ccfc11cdc91c5c67e570074b7f","tarball":"https://registry.npmjs.org/@anastasia-labs/payment-subscription-offchain/-/payment-subscription-offchain-1.0.4.tgz","fileCount":5,"integrity":"sha512-Oi5DChw4ef37B4Dp6K3Sw0U7ERCXxITPZvzAxV0SShnTiSAprNCAqH5Ngn48g70iifX6wzkeq+LZTPHPHJEJxg==","signatures":[{"sig":"MEUCIF+QtDFykGHx0blMcDiwREgxHF7cnkcw+S1AVfiTiCR7AiEAgukJcoK2adlkDmWFE/Q5pcaQ+E7vykuNrWE+MTq7slE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":317963},"main":"./dist/index.js","type":"module","_from":"file:anastasia-labs-payment-subscription-offchain-1.0.4.tgz","types":"./dist/index.d.ts","scripts":{"lint":"eslint","test":"export NODE_ENV='emulator' && vitest run","build":"tsup src/index.ts --minify --format esm,cjs --dts --clean","repack":"pnpm run build && pnpm pack","ts-node":"ts-node"},"_npmUser":{"name":"anastasia-labs","email":"info@anastasialabs.com"},"_resolved":"/tmp/915a2bc368546e195fca2e8925a27b97/anastasia-labs-payment-subscription-offchain-1.0.4.tgz","_integrity":"sha512-Oi5DChw4ef37B4Dp6K3Sw0U7ERCXxITPZvzAxV0SShnTiSAprNCAqH5Ngn48g70iifX6wzkeq+LZTPHPHJEJxg==","_npmVersion":"10.8.2","description":"Off-Chain SDK for Payment Subscription Smart Contract","directories":{"test":"test"},"_nodeVersion":"18.20.5","dependencies":{"dotenv":"^16.4.7","effect":"^3.11.2","@noble/hashes":"^1.6.1","@lucid-evolution/lucid":"0.4.16"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247","devDependencies":{"tsup":"^6.7.0","eslint":"^8.57.1","vitest":"0.34.6","ts-node":"^10.9.2","typescript":"^5.6.3","@types/node":"^20.17.6","@noble/hashes":"^1.5.0","@sinclair/typebox":"^0.25.24","eslint-config-prettier":"^8.10.0","@typescript-eslint/parser":"^5.62.0","@typescript-eslint/eslint-plugin":"^5.62.0"},"_npmOperationalInternal":{"tmp":"tmp/payment-subscription-offchain_1.0.4_1735970490662_0.4863138542976382","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@anastasia-labs/payment-subscription-offchain","version":"1.0.6","keywords":[],"author":"","license":"ISC","_id":"@anastasia-labs/payment-subscription-offchain@1.0.6","maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"dist":{"shasum":"d182edc8e4df759568f76943417133f1efeeae84","tarball":"https://registry.npmjs.org/@anastasia-labs/payment-subscription-offchain/-/payment-subscription-offchain-1.0.6.tgz","fileCount":4,"integrity":"sha512-btSTLtcn1HmrJOOrPzUeCdVHprH772TxXcql5qQCFmGVm04//1wgPk6BCmv4g5+3vtwPrFDqrlfeuTP45nkpGw==","signatures":[{"sig":"MEQCIGk7mGoGZi57vMmtYGHVLxOc6/U3Yn5Eek/NZzuwhjTtAiAixlEqoa5qK2uTyz6mYuceQ7uwqfLETgljdA1WD1etTg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141618},"main":"./dist/index.js","type":"module","_from":"file:anastasia-labs-payment-subscription-offchain-1.0.6.tgz","types":"./dist/index.d.ts","scripts":{"lint":"eslint","test":"export NODE_ENV='emulator' && vitest run","build":"tsup src/index.ts --minify --format esm --dts --clean","repack":"pnpm run build && pnpm pack","ts-node":"ts-node","build-examples":"tsup src/examples/*.ts --minify --format esm --clean --sourcemap"},"_npmUser":{"name":"anastasia-labs","email":"info@anastasialabs.com"},"_resolved":"/tmp/4112215de505f0460a185dff63dab592/anastasia-labs-payment-subscription-offchain-1.0.6.tgz","_integrity":"sha512-btSTLtcn1HmrJOOrPzUeCdVHprH772TxXcql5qQCFmGVm04//1wgPk6BCmv4g5+3vtwPrFDqrlfeuTP45nkpGw==","_npmVersion":"10.8.2","description":"Off-Chain SDK for Payment Subscription Smart Contract","directories":{"test":"test"},"_nodeVersion":"18.20.7","dependencies":{"effect":"^3.12.10","nanoid":"^5.0.9","@noble/hashes":"^1.6.1","@lucid-evolution/lucid":"0.4.25"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247","devDependencies":{"jiti":"^2.4.2","tsup":"^8.4.0","eslint":"^9.18.0","vitest":"0.34.6","ts-node":"^10.9.2","@eslint/js":"^9.18.0","typescript":"^5.6.3","@types/node":"^20.17.6","@noble/hashes":"^1.5.0","@eslint/eslintrc":"^3.2.0","@sinclair/typebox":"^0.25.24","eslint-config-prettier":"^8.10.0","@typescript-eslint/parser":"^8.19.1","@typescript-eslint/eslint-plugin":"^8.19.1"},"_npmOperationalInternal":{"tmp":"tmp/payment-subscription-offchain_1.0.6_1743402280486_0.2255043390576308","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@anastasia-labs/payment-subscription-offchain","version":"1.1.1","keywords":[],"author":"","license":"ISC","_id":"@anastasia-labs/payment-subscription-offchain@1.1.1","maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"dist":{"shasum":"d23dec94933243c85890c2b9e144b5e78984fdc5","tarball":"https://registry.npmjs.org/@anastasia-labs/payment-subscription-offchain/-/payment-subscription-offchain-1.1.1.tgz","fileCount":4,"integrity":"sha512-/k/QBVCzJJ2hs6vp/frVKMLGfQxocrjOT3UWfymtKtJkv+Q34VvR4GYmFEinSmjPIzX/LXe7dkuNbohOUzq/fw==","signatures":[{"sig":"MEQCIAN8YplZX7L2NTJAp0wUSaGV5qRNHw5mtFz0flLTogLSAiB9G4d2qpKooTfUO9wyXJk1pYMVoNT7xFKKE3/nET9M7A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141618},"main":"./dist/index.js","type":"module","_from":"file:anastasia-labs-payment-subscription-offchain-1.1.1.tgz","types":"./dist/index.d.ts","scripts":{"lint":"eslint","test":"export NODE_ENV='emulator' && vitest run","build":"tsup src/index.ts --minify --format esm --dts --clean","repack":"pnpm run build && pnpm pack","ts-node":"ts-node","build-examples":"tsup src/examples/*.ts --minify --format esm --clean --sourcemap"},"_npmUser":{"name":"anastasia-labs","email":"info@anastasialabs.com"},"_resolved":"/tmp/95af5b4280fc3ffc060375c69d2d69fc/anastasia-labs-payment-subscription-offchain-1.1.1.tgz","_integrity":"sha512-/k/QBVCzJJ2hs6vp/frVKMLGfQxocrjOT3UWfymtKtJkv+Q34VvR4GYmFEinSmjPIzX/LXe7dkuNbohOUzq/fw==","_npmVersion":"10.8.2","description":"Off-Chain SDK for Payment Subscription Smart Contract","directories":{"test":"test"},"_nodeVersion":"18.20.7","dependencies":{"effect":"^3.12.10","nanoid":"^5.0.9","@noble/hashes":"^1.6.1","@lucid-evolution/lucid":"0.4.25"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247","devDependencies":{"jiti":"^2.4.2","tsup":"^8.4.0","eslint":"^9.18.0","vitest":"0.34.6","ts-node":"^10.9.2","@eslint/js":"^9.18.0","typescript":"^5.6.3","@types/node":"^20.17.6","@noble/hashes":"^1.5.0","@eslint/eslintrc":"^3.2.0","@sinclair/typebox":"^0.25.24","eslint-config-prettier":"^8.10.0","@typescript-eslint/parser":"^8.19.1","@typescript-eslint/eslint-plugin":"^8.19.1"},"_npmOperationalInternal":{"tmp":"tmp/payment-subscription-offchain_1.1.1_1743430316990_0.908953300846272","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@anastasia-labs/payment-subscription-offchain","version":"1.1.2","description":"Off-Chain SDK for Payment Subscription Smart Contract","main":"./dist/index.js","types":"./dist/index.d.ts","type":"module","keywords":[],"author":"","license":"ISC","devDependencies":{"@eslint/eslintrc":"^3.2.0","@eslint/js":"^9.18.0","@noble/hashes":"^1.5.0","@sinclair/typebox":"^0.25.24","@types/node":"^20.17.6","@typescript-eslint/eslint-plugin":"^8.19.1","@typescript-eslint/parser":"^8.19.1","eslint":"^9.18.0","eslint-config-prettier":"^8.10.0","jiti":"^2.4.2","ts-node":"^10.9.2","tsup":"^8.4.0","typescript":"^5.6.3","vitest":"0.34.6"},"directories":{"test":"test"},"dependencies":{"@lucid-evolution/lucid":"0.4.25","@noble/hashes":"^1.6.1","effect":"^3.12.10","nanoid":"^5.0.9"},"packageManager":"pnpm@9.7.1+sha512.faf344af2d6ca65c4c5c8c2224ea77a81a5e8859cbc4e06b1511ddce2f0151512431dd19e6aff31f2c6a8f5f2aced9bd2273e1fed7dd4de1868984059d2c4247","scripts":{"test":"export NODE_ENV='emulator' && vitest run","build":"tsup src/index.ts --minify --format esm --dts --clean","build-examples":"tsup src/examples/*.ts --minify --format esm --clean --sourcemap","lint":"eslint","repack":"pnpm run build && pnpm pack","ts-node":"ts-node"},"_id":"@anastasia-labs/payment-subscription-offchain@1.1.2","_integrity":"sha512-VKtv44Is2dAZ8xmB5qbwvVLdb2GSnhjtmTLTIMg4ug5V/MvpqmX16QwsdVcDlq5LbeX3vZQdXC7RZ4TTUko1yg==","_resolved":"/tmp/a61bcc82db5a6cdcf50dfb0468fde719/anastasia-labs-payment-subscription-offchain-1.1.2.tgz","_from":"file:anastasia-labs-payment-subscription-offchain-1.1.2.tgz","_nodeVersion":"18.20.8","_npmVersion":"10.8.2","dist":{"integrity":"sha512-VKtv44Is2dAZ8xmB5qbwvVLdb2GSnhjtmTLTIMg4ug5V/MvpqmX16QwsdVcDlq5LbeX3vZQdXC7RZ4TTUko1yg==","shasum":"2d14eeb071c675a8a6595481c4eb9fca116af7e9","tarball":"https://registry.npmjs.org/@anastasia-labs/payment-subscription-offchain/-/payment-subscription-offchain-1.1.2.tgz","fileCount":4,"unpackedSize":141854,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAjnRJIjLdp5x/uE1cSc07aH93fTBeTXqYuzHv6gvlO1AiAQoQP43fHLIxx5BxddCo30JgJ8cU7pxrvkUNf0XvbDkg=="}]},"_npmUser":{"name":"anastasia-labs","email":"info@anastasialabs.com"},"maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/payment-subscription-offchain_1.1.2_1744378537093_0.20391172398561563"},"_hasShrinkwrap":false}},"time":{"created":"2024-12-20T16:14:21.709Z","modified":"2025-04-11T13:35:37.423Z","1.0.0":"2024-12-20T16:14:22.018Z","1.0.3":"2025-01-03T17:51:49.979Z","1.0.4":"2025-01-04T06:01:30.870Z","1.0.6":"2025-03-31T06:24:40.683Z","1.1.1":"2025-03-31T14:11:57.215Z","1.1.2":"2025-04-11T13:35:37.265Z"},"license":"ISC","keywords":[],"description":"Off-Chain SDK for Payment Subscription Smart Contract","maintainers":[{"name":"anastasia-labs","email":"info@anastasialabs.com"}],"readme":"# Table of Contents\n\n- [Payment Subscription Offchain](#payment-subscription-offchain)\n  - [Introduction](#introduction)\n  - [Documentation](#documentation)\n  - [Usage Example](#usage-example)\n    - [Setup](#setup-lucid--subscription-scripts)\n    - [Create a Service](#create-a-service)\n    - [Create a User Account](#create-a-user-account)\n    - [Initiate a Subscription](#initiate-a-subscription)\n    - [Unsubscribe](#unsubscribe)\n    - [Merchant Withdraw Subscription Fees](#merchant-withdraw-subscription-fees)\n  - [Local Build](#local-build)\n  - [Test Framework](#test-framework)\n  - [Running Tests](#running-tests)\n\n<!-- TODO: Clean up the examples with actual code -->\n# Payment Subscription Offchain\n\n## Introduction\n\nThe Payment Subscription Off-Chain SDK is a TypeScript library that conveniently interfaces with an Aiken-based Payment Subscription Smart Contract on the Cardano blockchain. It provides developers with an easy-to-use interface, enabling users to effortlessly manage recurring payments directly from their wallets. This SDK offers a decentralized and trustless solution for subscription-based services, leveraging the automation capabilities of smart contracts.\n\n**Key features:**\n\n- **Effortless Management of Recurring Payments:** Set up, manage, and cancel recurring payments seamlessly.\n\n- **User-Controlled Subscriptions:** Users maintain control over their funds without the need for intermediaries..\n- **Addition or Removal of Signers:** Update the list of signatories and threshold as needed.\n- **Secure and Transparent:** Built on the Cardano blockchain, ensuring security and transparency.\n- **Flexible Subscription Management:** Supports creation, updating, and cancellation of subscriptions.\n\nThis project is funded by the Cardano Treasury in [Catalyst Fund 11](https://projectcatalyst.io/funds/11/cardano-use-cases-product/anastasia-labs-x-maestro-plug-n-play-20)\n\n## Documentation\n\n### What is a Subscription Payments Smart Contract?\n\nA Subscription Payments Smart Contract is a blockchain-based contract that automates recurring payments between users and service providers without intermediaries. It allows users to authorize scheduled payments directly from their wallets, enhancing security and control over their funds.\n\n### How Does This Project Facilitate Payment Subscription Transactions?\n\nThis project provides an off-chain SDK to interact along with our [Payment Subscription Smart Contract](https://github.com/Anastasia-Labs/payment-subscription). The contract enables:\n\n- **Effortless Recurring Payments:** Automate subscription payments without intermediaries.\n\n- **User-Controlled Subscriptions:** Users have full control over their subscriptions and funds.\n- **Secure Transactions:** Leverages the security and transparency of the Cardano blockchain.\n- **Flexible Subscription Management:** Supports creation, updating, and cancellation of subscriptions.\n\n\n### Design Documentation\n\nFor a comprehensive understanding of the contract's architecture, design decisions, and implementation details, please refer to the [Payment Subscription Design Documentation](https://github.com/Anastasia-Labs/payment-subscription/blob/main/docs/payment-subscription-design-specs/subscription-smart-contract.pdf). This documentation provides in-depth insights into the contract's design, including its components, and detailed explanations of its functionality.\n\n## Usage Example\n\n### Install package\n\n```sh\nnpm install @anastasia-labs/payment-subscription-offchain\n```\n\nor\n\n```sh\npnpm install @anastasia-labs/payment-subscription-offchain\n```\n\nBelow are the basic instructions on how to use the Payment Subscription endpoints.\n\nFor a more comprehensive working example, checkout the [examples folder](https://github.com/Anastasia-Labs/payment-subscription-offchain/tree/main/examples)..\n\n### Setup Lucid & Subscription Scripts\n\n```ts\nimport { Lucid, Maestro } from \"@lucid-evolution/lucid\";\n\nconst lucid = await Lucid(\n  new Maestro({\n    network: \"Preprod\", // For MAINNET: \"Mainnet\"\n    apiKey: \"<Your-API-Key>\", // Get yours by visiting https://docs.gomaestro.org/getting-started\n    turboSubmit: false, // Read about paid turbo transaction submission feature at https://docs.gomaestro.org/cardano/turbo-submit-transaction\n  }),\n  \"Preprod\" // For MAINNET: \"Mainnet\"\n);\n\n```\n\n**Get Your [Maestro API Key](https://docs.gomaestro.org/getting-started)**\n\n## Service Endpoints\n\n### Create a Service\n\nThis endpoint is initiated by a Merchant with the \n- service fee: How much a Subscriber should pay for the service\n- penalty fee: (Opional), How much the Merchant wants to charge at the event a Subscriber unsubscribes before their initial number of intervals set when subscribing.\n- Interval length: The number of intervals such as one month.\n- Number of intervals: The intervals the subscription fee covers.\n\n```ts\nimport { ADA, createService, CreateServiceConfig, LucidEvolution, } from \"@anastasia-labs/payment-subscription-offchain\";\n\n try {\n        const utxos = await lucid.wallet().getUtxos()\n      // Configure the service configuration\n  const serviceConfig: CreateServiceConfig = {\n            selected_out_ref: utxos[0],\n            service_fee_policyid: ADA.policyId,\n            service_fee_assetname: ADA.assetName,\n            service_fee: 10_000_000n,\n            penalty_fee_policyid: ADA.policyId,\n            penalty_fee_assetname: ADA.assetName,\n            penalty_fee: 1_000_000n,\n            interval_length: 30n * 24n * 60n * 60n * 1000n, // 30 days\n            num_intervals: 12n,\n            is_active: true,\n        };\n\n        console.log(\"Creating service with config:\", serviceConfig);\n\n        const createServiceUnSigned = await createService(lucid, serviceConfig);\n        const createServiceTxSigned = await createServiceUnSigned.sign\n            .withWallet()\n            .complete();\n        const createServiceTxHash = await createServiceTxSigned.submit();\n\n        console.log(`Submitting ...`);\n        await lucid.awaitTx(createServiceTxHash);\n\n        console.log(`Service created successfully: ${createServiceTxHash}`);\n    } catch (error) {\n        console.error(\"Failed to create service:\", error);\n    }\n```\n\n### Update a Service\n\nAlso initiated by the Merchant. This endpoint allows the Merchant to make changes to their initial configurations.\n\n```ts\nimport {\n    LucidEvolution,\n    updateService,\n    UpdateServiceConfig,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n\n    const updateServiceConfig: UpdateServiceConfig = {\n        service_nft_tn: 'SERVICE_NFT_TOKEN_NAME', // Replace with actual token name\n        merchant_nft_tn: 'MERCHANT_TOKEN_UNIT', // Replace with actual unit\n        new_service_fee: 9_500_000n,\n        new_penalty_fee: 1_000_000n,\n        new_interval_length: 10n * 24n * 60n * 60n * 1000n,\n        new_num_intervals: 10n,\n    };\n\n    // Update Service\n    try {\n        const updateServiceUnsigned = await updateService(\n            lucid,\n            updateServiceConfig,\n        );\n        const updateTxSigned = await updateServiceUnsigned.sign.withWallet()\n            .complete();\n        const updateTxHash = await updateTxSigned.submit();\n\n        console.log(`Service updated successfully: ${updateTxHash}`);\n    } catch (error) {\n        console.error(\"Failed to update service:\", error);\n    }\n\n```\n\n### Remove a Service\n\nCan only be initated by the Merchant.\n\nRather than removing the service, this endpoint allows the Merchant to deactivate the Service by setting the isActive field to false.\n\n```ts\nimport {\n    LucidEvolution,\n    removeService,\n    RemoveServiceConfig,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n\n    const removeServiceConfig: RemoveServiceConfig = {\n        service_nft_tn: 'SERVICE_NFT_TOKEN_NAME', // Replace with actual token name\n        merchant_nft_tn: 'MERCHANT_TOKEN_UNIT', // Replace with actual unit\n    };\n\n    // Remove Service\n    try {\n        const removeServiceUnsigned = await removeService(\n            lucid,\n            removeServiceConfig,\n        );\n        const removeServiceSigned = await removeServiceUnsigned.sign\n            .withWallet()\n            .complete();\n        const removeServiceHash = await removeServiceSigned.submit();\n\n        console.log(\n            `Service removed successfully || change isActive to false: ${removeServiceHash}`,\n        );\n    } catch (error) {\n        console.error(\"Failed to remove Service:\", error);\n    }\n\n\n```\n## Account Endpoints\n\nThese endpoints are all initiated by the Subscriber.\n\n### Create a User Account\n\nThe Subscriber creates an Account by setting an email and Phone number.\n\n\n```ts\nimport { createAccount, CreateAccountConfig } from \"@anastasia-labs/payment-subscription-offchain\";\n\n  try {\n        const utxos = await lucid.wallet().getUtxos()\n        const accountConfig: CreateAccountConfig = {\n            selected_out_ref: utxos[0],\n            email_hash: bytesToHex(sha256(\"business@web3.ada\")),\n            phone_hash: bytesToHex(sha256(\"288-481-2686\")),\n        };\n\n        const createAccountUnsigned = await createAccount(lucid, accountConfig);\n        const createAccountSigned = await createAccountUnsigned.sign\n            .withWallet()\n            .complete();\n        const createAccountHash = await createAccountSigned.submit();\n        console.log(`Submitting ...`);\n        await lucid.awaitTx(createAccountHash);\n\n        console.log(`Account created successfully: ${createAccountHash}`);\n    } catch (error) {\n        console.error(\"Failed to create Account:\", error);\n    }\n\n```\n\n### Update an Account\n\nThe endpoint allows the Subscriber to update their account details.\n\n```ts\nimport {\n    LucidEvolution,\n    updateAccount,\n    UpdateAccountConfig,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n\n    const updateAccountConfig: UpdateAccountConfig = {\n        new_email: \"new_business@web3.ada\",\n        new_phone: \"(288) 481-2686-999\",\n        account_nft_tn: 'ACCOUNT_NFT_TOKEN_NAME', // Replace with actual token name\n        subscriber_nft_tn: 'SUBSCRIBER_NFT_TOKEN_NAME', // Replace with actual token name\n    };\n\n    // Update Account\n    try {\n        const updateServiceUnsigned = await updateAccount(\n            lucid,\n            updateAccountConfig,\n        );\n        const updateAccountSigned = await updateServiceUnsigned.sign\n            .withWallet()\n            .complete();\n        const updateAccountHash = await updateAccountSigned.submit();\n\n        console.log(`Account updated successfully: ${updateAccountHash}`);\n    } catch (error) {\n        console.error(\"Failed to update Account:\", error);\n    }\n\n\n```\n\n### Remove an Account\n\nThis endpoint completely removes the Account from the Payment Subscription system.\n\n```ts\nimport {\n    LucidEvolution,\n    removeAccount,\n    RemoveAccountConfig,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n\n    const removeAccountConfig: RemoveAccountConfig = {\n      account_nft_tn: 'ACCOUNT_NFT_TOKEN_NAME', // Replace with actual token name\n      subscriber_nft_tn: 'SUBSCRIBER_NFT_TOKEN_NAME', // Replace with actual token name\n    };\n\n    // Remove Account\n    try {\n        const removeAccountUnsigned = await removeAccount(\n            lucid,\n            removeAccountConfig,\n        );\n        const removeAccountSigned = await removeAccountUnsigned.sign\n            .withWallet()\n            .complete();\n        const removeAccountHash = await removeAccountSigned.submit();\n\n        console.log(`Account removed successfully: ${removeAccountHash}`);\n    } catch (error) {\n        console.error(\"Failed to remove Account:\", error);\n    }\n\n\n```\n\n\n### Initiate a Subscription\n\nThis endpoint allows a Subscriber to Subscribe to a Service. \n\nThey can choose the number of intervals they want to subscribe to. \nEnsure the Subscriber has enough ADA to cover the requested fees by the Merchant.\n\n```ts\nimport { initiateSubscription, InitPaymentConfig, LucidEvolution} from \"@anastasia-labs/payment-subscription-offchain\";\n\n// Configure the subscription parameters\nconst subscriptionConfig: InitPaymentConfig = {\n  service_nft_tn: 'SERVICE_NFT_TOKEN_NAME', // Replace with actual token name\n  account_nft_tn: 'ACCOUNT_NFT_TOKEN_NAME', // Replace with actual token name\n  num_intervals: 3n, // Replace with actual intervals to pay for\n  subscription_start: BigInt(lucid.currentSlot()) + 60n * 1000n,\n\n};\n\n\ntry {\n      const initSubscriptionUnsigned = await initiateSubscription(\n          lucid,\n          paymentConfig,\n      );\n      const initSubscriptionSigned = await initSubscriptionUnsigned.sign\n          .withWallet()\n          .complete();\n      const initSubscriptionHash = await initSubscriptionSigned.submit();\n\n      console.log(\n          `Subscription initiated successfully: ${initSubscriptionHash}`,\n      );\n  } catch (error) {\n      console.error(\"Failed to initiate subscription:\", error);\n  }\n\n```\n\n### Merchant Withdraw Subscription Fees\n\nInitiated by the Merchant, this endpoint allows the Merchant to unlock funds from the Payment Contract equivalent to the number of intervals passed of an active Service.\n\n```ts\nimport { withdrawFees, WithdrawFeesConfig } from \"@anastasia-labs/payment-subscription-offchain\";\n\n// Configure the withdrawal parameters\nconst withdrawConfig: MerchantWithdrawConfig = {\n  service_nft_tn: 'SERVICE_REF_TOKEN', // Replace with actual unit\n  subscriber_nft_tn: 'SUBSCRIBER_TOKEN_UNIT', // Replace with actual unit\n  merchant_nft_tn: 'MERCHANT_TOKEN_UNIT', // Replace with actual unit\n  payment_nft_tn: 'PAYMENT_NFT_TOKEN_NAME', // Replace with actual token name\n  current_time: BigInt(Date.now()),\n\n};\n\n// Withdraw subscription fees\ntry {\n      const merchantWithdrawUnsigned = await merchantWithdraw(\n          lucid,\n          merchantWithdrawConfig,\n      );\n      const merchantWithdrawSigned = await merchantWithdrawUnsigned.sign\n          .withWallet()\n          .complete();\n      const merchantWithdrawTxHash = await merchantWithdrawSigned.submit();\n\n      console.log(`Merchant Withdraw Successful: ${merchantWithdrawTxHash}`);\n  } catch (error) {\n      console.error(\"Failed to withdraw by Merchant:\", error);\n  }\n\n```\n\n### Extend Subscription\n\nThis allows the the Subscriber to update their subscription by extending it to as many intervals as they wish.\n\n```ts\n\nimport {\n    ExtendPaymentConfig,\n    extendSubscription,\n    LucidEvolution,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n\n\n    const extendPaymentConfig: ExtendPaymentConfig = {\n        service_nft_tn: serviceNftTn,\n        subscriber_nft_tn: 'SUBSCRIBER_NFT_TOKEN_NAME', // Replace with actual token name\n        extension_intervals: 1n,\n    };\n\n    // Extend Subscription\n    try {\n        const extendUnsigned = await extendSubscription(\n            lucid,\n            extendPaymentConfig,\n        );\n        const extendSigned = await extendUnsigned.sign\n            .withWallet()\n            .complete();\n        const extendTxHash = await extendSigned.submit();\n\n        console.log(`Service extended successfully: ${extendTxHash}`);\n    } catch (error) {\n        console.error(\"Failed to extend service:\", error);\n    }\n\n```\n\n### Unsubscribe\n\nThis endpoint allows a Subscriber to unsubscribe from a Service.\n\nIt is at this point that the penalty fee is deducted from the subscription_fee to be refunded if the Merchant had set it when creating a Service.\n\n```ts\nimport { unsubscribe, UnsubscribeConfig, LucidEvolution } from \"@anastasia-labs/payment-subscription-offchain\";\n\n\n// Configure the unsubscription parameters\nconst unsubscribeConfig: UnsubscribeConfig = {\n  service_nft_tn: 'SERVICE_NFT_TOKEN_NAME', // Replace with actual token name\n  subscriber_nft_tn: 'SUBSCRIBER_NFT_TOKEN_NAME', // Replace with actual token name\n  current_time: BigInt(Date.now()),\n};\n\n// Unsubscribe from the service\ntry {\n      const unsubscribeUnsigned = await unsubscribe(\n          lucid,\n          unsubscribeConfig,\n      );\n      const unsubscribeSigned = await unsubscribeUnsigned.sign\n          .withWallet()\n          .complete();\n      const unsubscribeHash = await unsubscribeSigned.submit();\n\n      console.log(\n          `Unsubscribed successfully: ${unsubscribeHash}`,\n      );\n  } catch (error) {\n      console.error(\"Failed to unsubscribe:\", error);\n  }\n```\n\n### Merchant Penalty Withdraw\n\nThe Merchant uses this endpoint to claim any **penalty fees** locked in the Payment Contract.\n\n```ts\n\nimport {\n    LucidEvolution,\n    merchantPenaltyWithdraw,\n    WithdrawPenaltyConfig,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n\n    const withdrawPenaltyConfig: WithdrawPenaltyConfig = {\n      service_nft_tn: 'SERVICE_NFT_TOKEN_NAME', // Replace with actual token name\n      merchant_nft_tn: 'MERCHANT_NFT_TOKEN_NAME', // Replace     };\n\n      subscriber_nft_tn: 'SUBSCRIBER_NFT_TOKEN_NAME', // Replace with actual token name\n\n    // Merchant Withdraw\n    try {\n        const penaltyWithdrawUnsigned = await merchantPenaltyWithdraw(\n            lucid,\n            withdrawPenaltyConfig,\n        );\n        const penaltyWithdrawSigned = await penaltyWithdrawUnsigned.sign\n            .withWallet()\n            .complete();\n        const penaltyWithdrawTxHash = await penaltyWithdrawSigned.submit();\n\n        console.log(`Service created successfully: ${penaltyWithdrawTxHash}`);\n    } catch (error) {\n        console.error(\"Failed to create service:\", error);\n    }\n};\n\n\n```\n\n### Subscriber Withdraw\n\nThis endpoint allow the Subscriber to unlock funds from the Payment Contract of an **inactive Service**, if at all there were funds left when the Merchant removed/de-activated the Service.\n\n```ts\n\nimport {\n    Data,\n    LucidEvolution,\n    ServiceDatum,\n    subscriberWithdraw,\n    SubscriberWithdrawConfig,\n} from \"@anastasia-labs/payment-subscription-offchain\";\n   \n    const subscriberWithdrawConfig: SubscriberWithdrawConfig = {\n      service_nft_tn: 'SERVICE_NFT_TOKEN_NAME', // Replace with actual token name\n      subscriber_nft_tn: 'SUBSCRIBER_NFT_TOKEN_NAME', // Replace with actual token name\n    };\n\n    // Subscriber Withdraw\n    try {\n        const subscriberWithdrawUnsigned = await subscriberWithdraw(\n            lucid,\n            subscriberWithdrawConfig,\n        );\n        const subscriberWithdrawSigned = await subscriberWithdrawUnsigned.sign\n            .withWallet()\n            .complete();\n        const subscriberWithdrawTxHash = await subscriberWithdrawSigned.submit();\n\n        console.log(`Service created successfully: ${merchantWithdrawTxHash}`);\n    } catch (error) {\n        console.error(\"Failed to create service:\", error);\n    }\n\n```\n\n## Local Build\n\nIn the main directory\n\n```\npnpm run build\n```\n\n## Test framework\n\nhttps://github.com/vitest-dev/vitest\n\n## Running Tests\n\n```sh\npnpm test\n```\n\n![payment-subscription-offchain](/docs/images/offchain_sdk_tests.gif)\n\nTest results:\n\n![alt text](/docs/images/offchain_tests.png)\n\nEach test case is designed to validate specific aspects of the payment subscription contract,To run only specific tests, do:\n\n```sh\npnpm test test/test-case-function-name.test.ts\n```\n\n","readmeFilename":"README.md"}