{"_id":"@civic/solana-derived-pass","_rev":"25-cac7f2079d17f4692715f7fb03947d5c","name":"@civic/solana-derived-pass","dist-tags":{"latest":"0.0.3"},"versions":{"0.0.1":{"name":"@civic/solana-derived-pass","version":"0.0.1","author":{"name":"Daniel Kelleher","email":"daniel@civic.com"},"_id":"@civic/solana-derived-pass@0.0.1","maintainers":[{"name":"godfreybafana","email":"godfrey.bafana@double-eye.com"},{"name":"frits-double-eye","email":"frits@double-eye.com"},{"name":"chriteixeira","email":"chriteixeira@gmail.com"},{"name":"daneel","email":"daneel@civic.com"},{"name":"leolangen","email":"leo@civic.com"},{"name":"mitchcivic","email":"mitch@civic.com"},{"name":"dankelleher","email":"dankelleher@yahoo.com"},{"name":"jonthepilot","email":"jonathan@civic.com"},{"name":"rado0x54","email":"web@riedel-it.de"},{"name":"araptarchis","email":"alexis.raptarchis@googlemail.com"},{"name":"civicfinance","email":"camille@civic.com"},{"name":"kevinhcolgan","email":"kevin@civic.com"},{"name":"flippiescholtz","email":"flippie@civic.com"},{"name":"tyronemichael","email":"tyronemichael@gmail.com"},{"name":"lucmir","email":"luccmir@gmail.com"},{"name":"william-identity","email":"william@identity.org"}],"dist":{"shasum":"df6912915cc1c47f94fd5ec35afcc43cf8ce7e68","tarball":"https://registry.npmjs.org/@civic/solana-derived-pass/-/solana-derived-pass-0.0.1.tgz","fileCount":50,"integrity":"sha512-x9OPpEFRssBjOarh2QqhX1AUjw4oOfIU+WASk5oNsoxjaIITCOgXo+fIdFOvWlr6X+1abg1klb6mWrqJWfjO/g==","signatures":[{"sig":"MEUCICzGsXWIZRPfVWwAB51OYOtWN/Txxp2PrA6o9+bgFIkgAiEAi2LtV1s49/f5lvPT2yALr3esoPO1ICjXNL24AQ74L4s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":333531,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJitxFkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqp8Q/+MXzofGnur2ML4ocXnZK2lA5U9ytq5A0nQeGVW7P3lQbg3FSk\r\niJzDu3/un4asrXoxqWXT6IoA5laTd4HZbVUnOe667B2Dha9ZfQBDovZYDr8K\r\nzexbPHlkOOXcCtLRw/ry/cuaNuVQvE0dE/k2YL6tQiOTlDihAhqFyPEZskcj\r\n5GbN5EgjZUNx5WHIABo3dSu/q97nHWLbBxTQ4kbR5MryDVVSc26oc3ytF3Jc\r\nF1k77yc90DsxzE9K3f1tMv6u/uWvc2qPn2FtzDUihrx4H9AwdWkJRrD70Lai\r\nOcoU9F/nPtJiBoy8tfw/zIO0Sr7gIkvYSPcSzZpo+1zeHM2OFNI/miYqrz47\r\nGDUaEAwQ7TEdCCQrOe5S9T93KpqKVbzjMtBV5q1bOR25R51DV9MdvJIW/tf5\r\nw/HVNVJ0E81rqbf8RV4Sv98Dz07g6d8KWujoQQWiRYEoLRS9H4DrO1fa/iyO\r\nwSL8mfSdLyGawWpi+wfOWxQbrSRVd3bz8g3ja5SR/vVQS55zxe+CYXmH0pCN\r\nsNKNjGMyhro1FDsEGXrpTacpTbxsoZtetNdc6vs26vuM72Srs4tSBe0Jijdb\r\ndfNP3IZvH81k7gXxqy0SOxef3zH1K+EHEWD3MhI0KHznsQ/jfMVmRj/UsZQv\r\nNasjgN0jacbHxk0FhPu00D6W0jFY9d9bCwE=\r\n=McSU\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","scripts":{"lint":"prettier */*.js \"*/**/*{.js,.ts}\" --check","test":"anchor test","build":"yarn clean && anchor build && yarn compile","clean":"rimraf -rf ./dist","compile":"tsc -p tsconfig.json","lint:fix":"prettier */*.js \"*/**/*{.js,.ts}\" -w"},"_npmUser":{"name":"dankelleher","email":"dankelleher@yahoo.com"},"description":"A Civic-Pass derivation library for Solana","directories":{},"dependencies":{"ramda":"^0.28.0","@project-serum/anchor":"^0.24.2","@identity.com/solana-gateway-ts":"^0.8.2"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.4","mocha":"^10.0.0","sinon":"^14.0.0","rimraf":"^3.0.2","prettier":"^2.6.2","ts-mocha":"^10.0.0","typescript":"^4.3.5","@types/chai":"^4.3.0","@types/bn.js":"^5.1.0","@types/mocha":"^9.1.1","@types/ramda":"^0.28.12","chai-as-promised":"^7.1.1","@types/chai-as-promised":"^7.1.5","@project-serum/anchor-cli":"^0.24.2","@identity.com/solana-gatekeeper-lib":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/solana-derived-pass_0.0.1_1656164708308_0.69079625172099","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@civic/solana-derived-pass","version":"0.0.2","author":{"name":"Daniel Kelleher","email":"daniel@civic.com"},"_id":"@civic/solana-derived-pass@0.0.2","maintainers":[{"name":"godfreybafana","email":"godfrey.bafana@double-eye.com"},{"name":"frits-double-eye","email":"frits@double-eye.com"},{"name":"chriteixeira","email":"chriteixeira@gmail.com"},{"name":"daneel","email":"daneel@civic.com"},{"name":"leolangen","email":"leo@civic.com"},{"name":"mitchcivic","email":"mitch@civic.com"},{"name":"dankelleher","email":"dankelleher@yahoo.com"},{"name":"jonthepilot","email":"jonathan@civic.com"},{"name":"rado0x54","email":"web@riedel-it.de"},{"name":"araptarchis","email":"alexis.raptarchis@googlemail.com"},{"name":"civicfinance","email":"camille@civic.com"},{"name":"kevinhcolgan","email":"kevin@civic.com"},{"name":"flippiescholtz","email":"flippie@civic.com"},{"name":"tyronemichael","email":"tyronemichael@gmail.com"},{"name":"lucmir","email":"luccmir@gmail.com"},{"name":"william-identity","email":"william@identity.org"}],"dist":{"shasum":"cedc7070f2360ff81d759bfb4ee0db1503f82f2a","tarball":"https://registry.npmjs.org/@civic/solana-derived-pass/-/solana-derived-pass-0.0.2.tgz","fileCount":50,"integrity":"sha512-PcyI2lFLvOQ/0s1o9hC9kmkoBC3cbrYn9nBQnO2A1Sd3VEBnE2tuXSfWiDURR8IN6CLfZIYMcUwegYGnFy7mIg==","signatures":[{"sig":"MEQCIEe5wK5mEtgQZXVgtjPZauFpDv4B7xt00ylwW98lHndvAiAtLFa5MzT+nbe+IJJttIDCKUeoGXScRAAgSskPWZ8sPQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":333569,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJitxHpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqHaw/8CvBYLwq7mHKzf1QyEtqjh5rrQBa+y8RpaFEEsh4piPswg33q\r\nJFoPBFzGxvH10FvbYRhm68lFWNulvBirocdWleEnJTigUu1rdoS3WeKtG5ha\r\n4bZ5STDVi5RKQF14nQPf5Qy/9DVHkvxaEd2hPcFJAZXKMJUr7oMUs9Kmz5v7\r\n7Zd33cUsrLcEfjm4fSD+hoJfQU3kPRhYG1+lbCb/Am2zwiMMAYRb5bpm108E\r\nrd2L6XbQERwsNPyKOdfk40J5xPQFMgxumVQi6QxUoRy+Lddb+3e1lnirppFt\r\n/kC1+TQATzPno+eaaUIvtDk0bD+9tbLNbpqJT1MyDJn8GczoUxTp5scejAxJ\r\nX9NER11tyB/LErfEBA+Iv7bORN+sBRF3xFv2kBOFO8aAFns/xH1BlOgtRFUY\r\nPi199+W950suPYN48mLHuteme0WPE8x1sKS1mZjvRJoBg8dee2qKXe0tkD7c\r\nBK2X+4GvAwEXurmVCczVxcyQdEns6lL5xPRuMinAd3oE6D7qe/Dwqv+j33iJ\r\nCxwXi09V80JM4DUeNKiNEBzdq3JxwGDiCLVBEmwMD0jXz4Woz4ZLG8IYzk6Z\r\ngFAXvm6qisVpg08jXi1nRjB5QILFMZLoEef2NJXqu+zPNpXhBxVTNtoJbQEC\r\nw4HCpS58nGxoxJ7MRLJ+CGMACh62Y4JNCfU=\r\n=lSFB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/src/index.js","scripts":{"lint":"prettier */*.js \"*/**/*{.js,.ts}\" --check","test":"anchor test","build":"yarn clean && anchor build && yarn compile","clean":"rimraf -rf ./dist","compile":"tsc -p tsconfig.json","prepare":"yarn build","lint:fix":"prettier */*.js \"*/**/*{.js,.ts}\" -w"},"_npmUser":{"name":"dankelleher","email":"dankelleher@yahoo.com"},"description":"A Civic-Pass derivation library for Solana","directories":{},"dependencies":{"ramda":"^0.28.0","@project-serum/anchor":"^0.24.2","@identity.com/solana-gateway-ts":"^0.8.2"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.4","mocha":"^10.0.0","sinon":"^14.0.0","rimraf":"^3.0.2","prettier":"^2.6.2","ts-mocha":"^10.0.0","typescript":"^4.3.5","@types/chai":"^4.3.0","@types/bn.js":"^5.1.0","@types/mocha":"^9.1.1","@types/ramda":"^0.28.12","chai-as-promised":"^7.1.1","@types/chai-as-promised":"^7.1.5","@project-serum/anchor-cli":"^0.24.2","@identity.com/solana-gatekeeper-lib":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/solana-derived-pass_0.0.2_1656164840940_0.858607634432069","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"@civic/solana-derived-pass","version":"0.0.3","author":{"name":"Daniel Kelleher","email":"daniel@civic.com"},"_id":"@civic/solana-derived-pass@0.0.3","maintainers":[{"name":"godfreybafana","email":"godfrey.bafana@double-eye.com"},{"name":"frits-double-eye","email":"frits@double-eye.com"},{"name":"chriteixeira","email":"chriteixeira@gmail.com"},{"name":"daneel","email":"daneel@civic.com"},{"name":"leolangen","email":"leo@civic.com"},{"name":"mitchcivic","email":"mitch@civic.com"},{"name":"dankelleher","email":"dankelleher@yahoo.com"},{"name":"jonthepilot","email":"jonathan@civic.com"},{"name":"rado0x54","email":"web@riedel-it.de"},{"name":"araptarchis","email":"alexis.raptarchis@googlemail.com"},{"name":"civicfinance","email":"camille@civic.com"},{"name":"kevinhcolgan","email":"kevin@civic.com"},{"name":"flippiescholtz","email":"flippie@civic.com"},{"name":"tyronemichael","email":"tyronemichael@gmail.com"},{"name":"lucmir","email":"luccmir@gmail.com"},{"name":"william-identity","email":"william@identity.org"}],"dist":{"shasum":"c2392457b8e0ef1330f7bdecd1f6b6f070bd9be4","tarball":"https://registry.npmjs.org/@civic/solana-derived-pass/-/solana-derived-pass-0.0.3.tgz","fileCount":50,"integrity":"sha512-qGL35bJB6eZZ0JgNUu5NqIfUEU6PSmWSResNVM05bVN06OABJryFWgGcRk61Z5vVj8jicXjHTkhnfZLNsuxjfA==","signatures":[{"sig":"MEYCIQCNB63bBDzpR2B54ng/QWzE3Czn9t9DPPTuILt9HN2DOQIhAKk6eJZWIY56CuMK9dnP5Z0rgw/fwRd6J7maSEKKLHgo","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":333569,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJitxpAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrCpRAAjmXAA2HkcGfdAP9R5WWiSed6jNcSCX2E8gzannkZZit1z00H\r\nLbIH7TSwDgTyAQfKD6Ro7zxgwkSwauNqNINqsCTytU/+a076heFBIcUTC7Xc\r\ni8y+OS2ZQkKXEpWuputkgQ4ND6Y3+tyVWff5Rb71iQKsYCI02F7QKeUrob6c\r\n/Hn305EDQbZMoz8Doi4mhJKwCW1zfF0fGPs95pNJq7bkob95eW2wiPHi6BBx\r\nZPnVZZjGef6hyUGEkI4wwznM2S7naLoBSfcdMKA9H2WqNssQCQd+9sLKwcwd\r\nIjhm2rWS5iNrPmj3Oz+0oPg5PIuzZo+J+rAaBIj3GFRDJPw5B7KjB5hfBg7H\r\nXi02skIQqrfyflw6Coi6CIOl+Iw8FUNOLSwzGOK5X1nJzxY9vvqu1qJFWs/u\r\nyrytqIkdgmrN73SM5x/UMNHibEJ0DD65wRQLj+E2tp3GssmcAW+o7UqIRMb1\r\n58TQ0buWwO1a+eT004BmdYJ3in3vAXckY6AfQhwaSZedhZ2CE1/Ber9gzLoc\r\n23rdsU72hzQ5SuHKWas8TjLj3tgsGTirwDId2lJgV/mVe+Ewj+NP4+fpUcGp\r\nKRfJq+UiYZYmOtYIJp9jlFs+87+MxM33C+2gf/xiFEZZMsGvD0zV2Z7UxNsL\r\nLw6L3VU5NlF2sCsrDhuTi47TcmpCFwvPOac=\r\n=CnGt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/src/index.js","scripts":{"lint":"prettier */*.js \"*/**/*{.js,.ts}\" --check","test":"anchor test","build":"yarn clean && anchor build && yarn compile","clean":"rimraf -rf ./dist","compile":"tsc -p tsconfig.json","prepare":"yarn build","lint:fix":"prettier */*.js \"*/**/*{.js,.ts}\" -w"},"_npmUser":{"name":"dankelleher","email":"dankelleher@yahoo.com"},"description":"A Civic-Pass derivation library for Solana","directories":{},"dependencies":{"ramda":"^0.28.0","@project-serum/anchor":"^0.24.2","@identity.com/solana-gateway-ts":"^0.8.2"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.4","mocha":"^10.0.0","sinon":"^14.0.0","rimraf":"^3.0.2","prettier":"^2.6.2","ts-mocha":"^10.0.0","typescript":"^4.3.5","@types/chai":"^4.3.0","@types/bn.js":"^5.1.0","@types/mocha":"^9.1.1","@types/ramda":"^0.28.12","chai-as-promised":"^7.1.1","@types/chai-as-promised":"^7.1.5","@project-serum/anchor-cli":"^0.24.2","@identity.com/solana-gatekeeper-lib":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/solana-derived-pass_0.0.3_1656166976291_0.8884016488418349","host":"s3://npm-registry-packages"}}},"time":{"created":"2022-06-25T13:45:08.233Z","modified":"2026-05-10T06:05:31.392Z","0.0.1":"2022-06-25T13:45:08.473Z","0.0.2":"2022-06-25T13:47:21.099Z","0.0.3":"2022-06-25T14:22:56.437Z"},"author":{"name":"Daniel Kelleher","email":"daniel@civic.com"},"description":"A Civic-Pass derivation library for Solana","maintainers":[{"email":"dankelleher@yahoo.com","name":"dankelleher"},{"email":"jonathan@civic.com","name":"jonthepilot"},{"email":"camille@civic.com","name":"civicfinance"},{"email":"kevin@civic.com","name":"kevinhcolgan"},{"email":"flippie@civic.com","name":"flippiescholtz"},{"email":"luccmir@gmail.com","name":"lucmir"},{"email":"chriteixeira@gmail.com","name":"chriteixeira"},{"email":"web@riedel-it.de","name":"rado0x54"}],"readme":"# Gateway Derive\n\nAn extension to the Identity.com [Gateway solution](https://github.com/identity-com/gateway-whitepaper/blob/main/gateway-whitepaper.pdf) that allows one pass type (a.k.a. gatekeeper network) to be derived from another.\n\n## Summary\n\nThe core idea here is as follows:\n\n- There is an equivalence between a Gatekeeper Network and a Pass Type. \nAll passes issued from the same gatekeeper network are treated as equivalent during on-chain validation.\n- It may be necessary to validate that a user has more than one pass.\nFor example, if one pass verifies that a user meets the requirement of being over 18, and another verifies\nthat they are not in a blocked country, then a smart contract may wish to verify that the user meets both requirements.\n- No authority is necessary to issue a pass based *solely* on the possession of constituent passes.\n\nThis smart contract allows for the generation of _derived pass types_,\nthat are issued if a caller presents a wallet with active passes from each of the _constituent pass types_.\n\nDerived Pass issuance is \"self-serve\" i.e. the recipient of the pass is the only signer needed.\nThis makes it ideal for integrating with dApps.\n\n![Design](./design.png)\n\n## Definitions\n\n- A Derived Pass Type is a gatekeeper network, from the point of view of the Gateway Program, but unlike a standard\ngatekeeper network, it is a [PDA](https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses),\nowned by the GatewayDerive program. \n- A Constituent Pass Type is a gatekeeper network. This can be a standard gatekeeper network, or a derived one.\n- The gatekeeper for a derived pass is also a PDA, owned by the GatewayDerive program.\nIn essence, this means that the program is the gatekeeper for the derived pass, and is the only entity that can issue tokens on it.\n\n## Fees\n\nConstituent pass issuers can register a Fee for use of a constituent pass in a derived pass issuance.\n\nFees are paid from the derived pass recipient to the gatekeeper(s) that issued the constituent passes.\nFees are registered per gatekeeper network + gatekeeper.\n\nNote: SOL only is supported at present, with plans to support SPL-Tokens in the future.\n\n## Limitations\n\nThis program is limited in what it can do, and care should be taken that it is not used in a way that is not intended.\n\n- After issuance, the validity of the derived pass type is *independent* of the validity of the constituent passes.\nThis means, a constituent pass can be revoked or frozen, and the derived pass will still be considered valid.\nThe solution to this is to set an expiry time on the derived pass\n- The current implementation supports \"AND\" only logic, when evaluating constituent passes.\nA potential improvement would be to allow derived passes that contain \"OR\" or \"NOT\", logic, allowing for alternative\npasses (in jurisdiction A OR in jurisdiction B, for example), or blacklists (does not possess token X).\n\n## Usage\n\nThis application uses [Anchor](https://github.com/project-serum/anchor).\nTo create an Anchor provider from a Solana wallet and connection, do the following:\n\n```ts\nimport * as anchor from \"@project-serum/anchor\";\nimport { Connection } from \"@solana/web3.js\";\n\nconst connection = new Connection(...);\n\n// If running locally via a script (most typical during derived pass creation),\n// this can be obtained from a Keypair using:\nconst wallet = new anchor.Wallet(keypair);\n\n// if using solana-wallet-adapter (e.g. during issuance on a dApp),\n// this will be the wallet provided by the adapter\nconst wallet = useWallet();\n\nconst provider = new anchor.AnchorProvider({\n  connection,\n  wallet,\n  opts: anchor.AnchorProvider.defaultOptions(),\n});\n```\n\n### Create a new derived pass\n\nThe provider is an authority keypair, used once during creation of the derived pass.\n\n```ts\nimport { DerivedPassService } from \"@civic/solana-derived-pass\";\n\nconst service = await DerivedPassService.build(provider);\n\nconst [txSignature, derivedPass] = await service.derivePass([\n  new PublicKey(\"...\"), // pass 1\n  new PublicKey(\"...\"), // pass 2\n]);\n```\n\nKeep the authority public key, and derived pass public key, and add it to the dApp.\n\n### Issuing a pass\n\n```ts\nimport { DerivedPassService } from \"@civic/solana-derived-pass\";\n\nconst service = await DerivedPassService.build(provider);\nconst [txSignature, gatewayToken] = await service.issue(authority, derivedPass);\n```\n\n### Setting a fee\n\nCreate an anchor provider with the gatekeeper wallet.\n\n```ts\nimport { DerivedPassService } from \"@civic/solana-derived-pass\";\n\nconst gatekeeperService = await DerivedPassService.build(provider);\nconst fee = 100_000_000 // 0.1 SOL \nconst txSignature = await gatekeeperService.setFee(gatekeeperNetwork, fee);\n```\n\nFees can be changed after being set:\n\n```ts\nconst new_fee = 200_000_000 // 0.2 SOL \nconst txSignature = await gatekeeperService.setFee(gatekeeperNetwork, fee);\n```\n\nor removed:\n\n```ts\nconst txSignature = await gatekeeperService.unsetFee(gatekeeperNetwork);\n```\n\nA fee can also be set for refresh (see expiry below)\n\n```ts\nconst txSignature = await gatekeeperService.setFee(gatekeeperNetwork, issueFee, refreshFee);\n```\n\n### Creating a pass with expiry\n\n```ts\nimport { DerivedPassService } from \"@civic/solana-derived-pass\";\n\nconst service = await DerivedPassService.build(provider);\n\nconst [txSignature, derivedPass] = await service.derivePass([\n  new PublicKey(\"...\"), // pass 1\n  new PublicKey(\"...\"), // pass 2\n], {\n  expireDuration: 60 * 60 * 24 // expires after one day\n});\n```\n\n### Creating a pass that can be expired on use\n\nIf you want the pass to require refresh after every use,\nthen you can use the `expireOnUse` option.\n\nThis is useful for component passes that have short expiry, so that the\nstate of the component pass is checked automatically on every use.\n\nNote: For the expireOnUse function to be executed, \nthe integrating program must also call the expireToken instruction on the gateway program via CPI.\nExpireOnUse does not happen automatically.\n\n```ts\nimport { DerivedPassService } from \"@civic/solana-derived-pass\";\n\nconst service = await DerivedPassService.build(provider);\n\nconst [txSignature, derivedPass] = await service.derivePass([\n  new PublicKey(\"...\"), // pass 1\n  new PublicKey(\"...\"), // pass 2\n], {\n  expireOnUse: true\n});\n```\n\nYou may also want a single-use pass. For this, use the option:\n\n```ts\nrefreshDisabled: true\n```\n\nalongside the `expireOnUse` feature.\n","readmeFilename":"README.md"}