@idos-network/client 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,9 +49,12 @@ const profile = loggedInClient.user;
49
49
 
50
50
  // Now we can filer over users credentials (no access to them)
51
51
  const credentials = await loggedInClient.filterCredentials({
52
- credentialLevelOrHigherFilter: {
53
- userLevel: "basic",
54
- requiredAddons: ["email", "liveness"],
52
+ acceptedIssuers: [{ authPublicKey: "ISSUER_AUTH_PUBLIC_KEY" }],
53
+ // Accepted sources per claim; a self-attested ("MANUAL") email is fine here.
54
+ claimsFilter: {
55
+ identity: ["VERIFIED"],
56
+ liveness: ["LIVENESS"],
57
+ email: ["VERIFIED", "MANUAL"],
55
58
  },
56
59
  });
57
60
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Addon, BaseLevel, recordFilter } from "@idos-network/credentials/utils";
1
+ import { Addon, BaseLevel, Claim, ClaimRequirements, ClaimSource, ClaimSources, Claims, recordFilter } from "@idos-network/credentials/utils";
2
2
  import { KwilActionClient, Wallet, signNearMessage } from "@idos-network/kwil-infra";
3
3
  import { AddAttributeInput, AddWalletInput, AddWalletMessageInput, DelegatedWriteGrantBaseParams, GetAccessGrantsGrantedInput, GetWalletsOutput, SharePreliminaryCredentialInput, WalletType, idOSCredential, idOSCredentialListItem, idOSDelegatedWriteGrant, idOSGrant, idOSUser, idOSUserAttribute, idOSWallet, toDelegatedWriteGrantBaseParams } from "@idos-network/kwil-infra/actions";
4
4
  import { KwilSigner } from "@idos-network/kwil-js";
@@ -173,10 +173,13 @@ export declare class idOSClientLoggedIn implements Omit<Properties<idOSClientWit
173
173
  pick: Parameters<typeof recordFilter>[1];
174
174
  omit: Parameters<typeof recordFilter>[2];
175
175
  };
176
+ /** @deprecated The level leaves out self-attested data. Use `claimsFilter` instead. */
176
177
  credentialLevelOrHigherFilter?: {
177
178
  userLevel: BaseLevel;
178
179
  requiredAddons: Addon[];
179
180
  };
181
+ /** Accepted sources per claim, e.g. `{ email: ["VERIFIED", "MANUAL"] }`. See `matchClaims`. */
182
+ claimsFilter?: ClaimRequirements;
180
183
  }): Promise<idOSCredentialListItem[]>;
181
184
  requestAccessGrant(credentialId: string, { consumerEncryptionPublicKey, consumerAuthPublicKey, lockedUntil }: {
182
185
  consumerEncryptionPublicKey: string;
@@ -195,5 +198,5 @@ export declare function createIDOSClient(params: {
195
198
  enclaveOptions: Omit<IframeEnclave["options"], "mode">;
196
199
  }): idOSClientConfiguration<IframeEnclave>;
197
200
  //#endregion
198
- export { type DelegatedWriteGrantBaseParams, type idOSCredential, type idOSCredentialListItem, type idOSDelegatedWriteGrant, type idOSGrant, type idOSUser, type idOSUserAttribute, type idOSWallet, signNearMessage, toDelegatedWriteGrantBaseParams };
201
+ export { type Claim, type ClaimRequirements, type ClaimSource, type ClaimSources, type Claims, type DelegatedWriteGrantBaseParams, type idOSCredential, type idOSCredentialListItem, type idOSDelegatedWriteGrant, type idOSGrant, type idOSUser, type idOSUserAttribute, type idOSWallet, signNearMessage, toDelegatedWriteGrantBaseParams };
199
202
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/enclave/iframe-enclave.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/enclave/iframe-enclave.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{buildEphemeralSignedCredentialContentReference as e,buildPreliminaryIDOSCredential as t,mapPreliminaryToIDOSCredential as n,matchLevelOrHigher as r,recordFilter as i}from"@idos-network/credentials/utils";import{createClientKwilSigner as a,createKgwAuthenticatedBlobGateway as o,createNodeKwilClient as s,createWebKwilClient as c,isMmTokenAuth as l,mmTokenCredentialContentUri as u,signNearMessage as d}from"@idos-network/kwil-infra";import{addAttribute as f,addWallet as p,addWalletMessage as m,addWallets as h,createPreliminaryCredential as ee,dwgMessage as te,getAccessGrantsGrantedCount as ne,getAccessGrantsOwned as re,getAttributes as g,getCredentialOwned as ie,getCredentialShared as _,getCredentials as ae,getGrants as oe,getUser as se,getWallets as ce,hasProfile as v,removeCredential as le,removeWallet as ue,revokeAccessGrant as de,sharePreliminaryCredential as y,toDelegatedWriteGrantBaseParams as b}from"@idos-network/kwil-infra/actions";import{NodeKwil as x}from"@idos-network/kwil-js";import{BlobGateway as S,createBlobContentReference as fe,requireAccessTokenForUkycContent as C,resolveCredentialEncryptedContent as pe}from"@idos-network/utils/blob-gateway";import{base64Decode as w,base64Encode as T,hexEncodeSha256Hash as E,utf8Decode as D}from"@idos-network/utils/codecs";import{LocalStorageStore as me,MemoryStore as O}from"@idos-network/utils/store";import k from"tiny-invariant";import{BaseProvider as he}from"@idos-network/enclave";var A=class extends he{container;iframe;hostUrl;bound=!1;constructor(e){if(super(e),!this.options.container)throw Error(`container is required`);this.container=this.options.container,this.hostUrl=new URL(this.options.url??`https://enclave.idos.network`),this.iframe=document.createElement(`iframe`),this.iframe.id=`idos-enclave-iframe`}async load(){await this.createAndLoadIframe(),await this.requestToEnclave(`load`),await this.reconfigure(),await this.bindMessageListener()}async reset(){throw Error(`Embedding pages cannot reset enclave storage`)}async reconfigure(e={}){super.reconfigure(e),await this.requestToEnclave(`reconfigure`,this.options)}async confirm(e){this.showEnclave();try{return await this.requestToEnclave(`confirm`,e)}catch(e){return console.error(e),!1}finally{this.hideEnclave()}}async filterCredentials(e,t){return await this.requestToEnclave(`filterCredentials`,e,t)}async encrypt(e,t){return this.requestToEnclave(`encrypt`,e,t)}async decrypt(e,t){return this.requestToEnclave(`decrypt`,e,t)}async backupUserEncryptionProfile(){this.showEnclave();try{await this.requestToEnclave(`backupUserEncryptionProfile`)}catch(e){console.error(e)}finally{this.hideEnclave()}}async ensureUserEncryptionProfile(){this.showEnclave();try{return await this.requestToEnclave(`ensureUserEncryptionProfile`)}finally{this.hideEnclave()}}async addAddressMessageToSign(e,t,n){return this.requestToEnclave(`addAddressMessageToSign`,e,t,n)}async removeAddressMessageToSign(e,t,n){return this.requestToEnclave(`removeAddressMessageToSign`,e,t,n)}async addAddressToMpcSecret(e,t,n){return this.requestToEnclave(`addAddressToMpcSecret`,e,t,n)}async removeAddressFromMpcSecret(e,t,n){return this.requestToEnclave(`removeAddressFromMpcSecret`,e,t,n)}async createAndLoadIframe(){let e=document.querySelector(this.container);if(!e)throw Error(`Can't find container with selector ${this.container}`);let t=[`publickey-credentials-get`,`storage-access`],n=[`forms`,`modals`,`popups`,`popups-to-escape-sandbox`,`same-origin`,`scripts`].map(e=>`allow-${e}`),r={"aspect-ratio":`4/1`,"background-color":`transparent`,border:`none`,display:`block`,overflow:`hidden`,width:`100%`};this.iframe.allow=t.join(`; `),this.iframe.referrerPolicy=`origin`,this.iframe.sandbox.add(...n),this.iframe.src=this.hostUrl.toString();for(let[e,t]of Object.entries(r))this.iframe.style.setProperty(e,t);let i;for(;i=document.getElementById(this.iframe.id);)console.log(`reinstalling idOS iframe...`),e.removeChild(i);return e.appendChild(this.iframe),new Promise(e=>this.iframe.addEventListener(`load`,()=>{e()},{once:!0}))}showEnclave(){this.iframe.parentElement.classList.add(`visible`)}hideEnclave(){this.iframe.parentElement.classList.remove(`visible`)}async requestToEnclave(e,...t){return new Promise((n,r)=>{let{port1:i,port2:a}=new MessageChannel;i.onmessage=({data:e})=>{i.close(),e.error?r(e.error):n(e.result)},this.iframe.contentWindow.postMessage({method:e,data:t},this.hostUrl.origin,[a])})}bindMessageListener(){this.bound||window.addEventListener(`message`,this.onMessage.bind(this)),this.bound=!0}async onMessage(e){if(!e||!e.data||typeof e.data!=`object`||e.data.type!==`idOS:signTypedData`||e.origin!==this.hostUrl.origin)return;let t=e.data.payload,n=await this.signTypedData(t.domain,t.types,t.value);await this.requestToEnclave(`signTypedDataResponse`,n)}};function j(){return typeof window<`u`}function ge(e){return e.client instanceof x}function M(e){return j()?new S({url:e,fetchFn:(e,t)=>fetch(e,{...t,credentials:`include`})}):new S({url:e})}function N(e,t){return ge(e.kwilClient)?o({url:e.blobGateway.url,kwilClient:e.kwilClient,signer:t}):l(t)?e.blobGateway.withAccessToken(t.accessToken):e.blobGateway}function P(e,t,n){if(e===`MM`)return u(t,n)}const F="This idOS client is stale: another signer was set or it was logged out. Use the client returned by the latest `withUserSigner()`.",I=new WeakMap,L=new WeakMap,R=new WeakMap,z=new WeakMap,B=new WeakMap,V=new WeakSet;function H(e){return I.get(e)??e}function U(e,t){if(e.signer!==t)throw Error(F)}function W(e,t){let n=H(e),r=t?L.get(n)?.get(t):void 0;if(r)return r;let i=()=>U(n,t),a={get signer(){return i(),n.signer},get client(){return i(),n.client},call:async(...e)=>(i(),n.call(...e)),execute:async(...e)=>(i(),n.execute(...e)),waitForTx:async e=>(i(),n.waitForTx(e)),setSigner:e=>{i(),n.setSigner(e)}};if(I.set(a,n),t){let e=L.get(n)??new WeakMap;e.set(t,a),L.set(n,e)}return a}function G(e){return e&&R.get(e)||e}function K(e,t,n){let r=G(e),i=n?z.get(r)?.get(n):void 0;if(i)return i;let a=new Proxy(r,{get(e,r){if(r===`then`||typeof r==`symbol`)return;let i=Reflect.get(e,r,e);return typeof i==`function`?(...r)=>(U(t,n),i.apply(e,r)):(U(t,n),i)}});if(R.set(a,r),n){let e=z.get(r)??new WeakMap;e.set(n,a),z.set(r,e)}return a}function q(e,t){let n=H(e),r=(B.get(n)??Promise.resolve()).then(t,t);return B.set(n,r.then(()=>void 0,()=>void 0)),r}function J(){return new Proxy({},{get(e,t){if(t!==`signer`&&t!==`then`&&typeof t!=`symbol`){if(t===`client`)throw Error(F);return t===`setSigner`?()=>{throw Error(F)}:async()=>{throw Error(F)}}}})}function _e(e,t){return new Z(e,J(),J(),M(t))}function Y(e,t,n,r,i){let a=H(t);return q(a,async()=>{let t=a.signer;return t!==void 0&&t!==n||(t===n&&(a.setSigner(void 0),V.add(a)),V.has(a)&&(await r.reset(),V.delete(a)),a.signer!==void 0&&a.signer!==n)?_e(e,i):new Z(e,a,r,M(i))})}var X=class{state;chainId;nodeUrl;blobGatewayUrl;enclaveOptions;store;enclaveProvider;constructor(e){this.state=`configuration`,this.chainId=e.chainId,this.nodeUrl=e.nodeUrl,this.blobGatewayUrl=e.blobGatewayUrl,this.enclaveOptions=e.enclaveOptions,this.store=e.store??(j()?new me:new O),this.enclaveProvider=e.enclaveProvider?new e.enclaveProvider({...e.enclaveOptions,store:this.store}):new A(e.enclaveOptions)}async createClient(){return Z.fromConfig(this)}},Z=class e{state;store;kwilClient;enclaveProvider;blobGateway;constructor(e,t,n,r){this.state=`idle`,this.store=e,this.kwilClient=t,this.enclaveProvider=n,this.blobGateway=r}static async fromConfig(t){let n=await(j()?c:s)({nodeUrl:t.nodeUrl,chainId:t.chainId});await t.enclaveProvider.load();let r=t.blobGatewayUrl??t.nodeUrl;return new e(t.store,n,t.enclaveProvider,M(r))}async addressHasProfile(e){return v(this.kwilClient,{address:e}).then(e=>e.has_profile)}async withUserSigner(e){let t=e,[n,r,i,o]=await a(this.store,this.kwilClient,t);if(o===`NEAR`){let e=t;t={signMessage:async t=>({signedMessage:await d(e,t)})}}return q(this.kwilClient,async()=>(this.kwilClient.setSigner(n),new Q(this,t,n,r,i,o,N(this,n))))}async logOut(){return this}},Q=class{state;store;#e;#t;signer;kwilSigner;walletIdentifier;walletPublicKey;walletType;blobGateway;constructor(e,t,n,r,i,a,o){this.state=`with-user-signer`,this.store=e.store,this.#e=e.kwilClient,this.#t=e.enclaveProvider,this.signer=t,this.kwilSigner=n,this.walletIdentifier=r,this.walletPublicKey=i,this.walletType=a,this.blobGateway=o,this.#t.setSigner(this.signer)}get kwilClient(){return W(this.#e,this.kwilSigner)}get enclaveProvider(){return K(this.#t,this.#e,this.kwilSigner)}async logOut(){return Y(this.store,this.#e,this.kwilSigner,this.#t,this.blobGateway.url)}async hasProfile(){return v(this.kwilClient,{address:this.walletIdentifier}).then(e=>e.has_profile)}async createUserEncryptionProfile(e,t){return await q(this.#e,async()=>{U(this.#e,this.kwilSigner),await this.enclaveProvider.reconfigure({mode:`new`,userId:e,walletAddress:this.walletIdentifier,walletPublicKey:this.walletPublicKey,walletType:this.walletType,encryptionPasswordStore:t,expectedUserEncryptionPublicKey:void 0}),U(this.#e,this.kwilSigner)}),U(this.#e,this.kwilSigner),this.enclaveProvider.ensureUserEncryptionProfile()}async logIn(){if(!await this.hasProfile())throw Error(`User does not have a profile`);let e=await se(this.kwilClient);return q(this.#e,async()=>(U(this.#e,this.kwilSigner),await this.enclaveProvider.reconfigure({mode:`existing`,userId:e.id,expectedUserEncryptionPublicKey:e.recipient_encryption_public_key,walletAddress:this.walletIdentifier,walletType:this.walletType,encryptionPasswordStore:e.encryption_password_store,walletPublicKey:this.walletPublicKey}),U(this.#e,this.kwilSigner),new $(this,e)))}},$=class{state;store;#e;#t;signer;kwilSigner;walletIdentifier;walletPublicKey;walletType;user;blobGateway;constructor(e,t){this.state=`logged-in`,this.store=e.store,this.#e=H(e.kwilClient),this.#t=G(e.enclaveProvider),this.signer=e.signer,this.kwilSigner=e.kwilSigner,this.walletIdentifier=e.walletIdentifier,this.walletPublicKey=e.walletPublicKey,this.walletType=e.walletType,this.user=t,this.blobGateway=e.blobGateway}get kwilClient(){return W(this.#e,this.kwilSigner)}get enclaveProvider(){return K(this.#t,this.#e,this.kwilSigner)}async logOut(){return Y(this.store,this.#e,this.kwilSigner,this.#t,this.blobGateway.url)}async requestDWGMessage(e){return te(this.kwilClient,e).then(e=>e.message)}async createCredential(e,r,i){let a=crypto.randomUUID(),o={...await t({publicNotes:e,plaintextContent:r,recipientEncryptionPublicKey:w(this.user.recipient_encryption_public_key),issuerSigningSecretKey:i,contentUri:P(this.walletType,this.kwilSigner,a)}),id:a};C(o.contentUri,this.blobGateway.hasAccessToken);let s=crypto.randomUUID(),c={request_id:s,credential_id:o.id,issuer_auth_public_key:o.issuerAuthPublicKey,encryptor_public_key:o.encryptorPublicKey,content_uri:o.contentUri,content_size:o.contentSize,content_hash:E(r),public_notes:o.publicNotes,public_notes_signature:o.publicNotesSignature,broader_signature:o.broaderSignature};return await ee(this.kwilClient,c),await this.blobGateway.uploadCredentialBlobs({requestId:s,original:o.encryptedContent}),n(o)}async removeCredential(e){let t=await this.getCredentialById(e);k(t,`"idOSCredential" with id ${e} not found`);let n=t.content_uri??null;return C(n,this.blobGateway.hasAccessToken),await le(this.kwilClient,{id:e}),n&&await this.blobGateway.deleteCredentialBlob({credentialId:e}),{id:e}}async getCredentialById(e){return ie(this.kwilClient,{id:e}).then(e=>e[0])}async shareCredential(e){return await y(this.kwilClient,e),e}async getAllCredentials(){return ae(this.kwilClient)}async getAccessGrantsOwned(){return re(this.kwilClient)}async getAttributes(){return g(this.kwilClient)}async createAttribute(e){return await f(this.kwilClient,e),e}async getCredentialContentSha256Hash(e){let t=await this.getCredentialById(e);k(t,`"idOSCredential" with id ${e} not found`);let n=await this.#r(t);return E(n)}async getCredentialContent(e){let t=await this.getCredentialById(e);k(t,`"idOSCredential" with id ${e} not found`);let n=await this.#r(t);return D(n)}async getCredentialWithEncryptedContent(e){let t=await this.getCredentialById(e);return k(t,`"idOSCredential" with id ${e} not found`),this.#n(t)}async getCredentialSharedContent(e){let t=await this.getCredentialShared(e);k(t,`Shared credential with id ${e} not found`);let n=await this.#r(t);return D(n)}async getGrants(e){return{grants:await oe(this.kwilClient,e),totalCount:await this.getGrantsCount()}}async addWallets(e){return await h(this.kwilClient,e),e}async getGrantsCount(){return ne(this.kwilClient,{user_id:null}).then(e=>e.count)}async getCredentialShared(e){return _(this.kwilClient,{id:e}).then(e=>e[0])}async revokeAccessGrant(e){return await de(this.kwilClient,{id:e}),{id:e}}async addWalletMessage(e){return(await m(this.kwilClient,e)).message}async addWallet(e){if(await p(this.kwilClient,e),this.user.encryption_password_store!==`mpc`)return console.log(`MPC is not enabled or the user is not using MPC`),e;if(!e.wallet_type)throw Error(`Wallet type is required for MPC users`);let t=await this.enclaveProvider.addAddressMessageToSign(e.address,e.public_key??void 0,e.wallet_type),n=await this.enclaveProvider.signTypedData(t.domain,t.types,t.value),r=await this.enclaveProvider.addAddressToMpcSecret(this.user.id,t.value,n);return r!==`success`&&console.error(`Failed to add wallet to MPC: ${r}`),e}async getWallets(){return ce(this.kwilClient)}async removeWallet(e){let t=(await this.getWallets()).find(t=>t.id===e);if(!t)throw Error(`Wallet with id ${e} not found`);if(await ue(this.kwilClient,{id:e}),this.user.encryption_password_store!==`mpc`)return console.log(`MPC is not enabled or the user is not using MPC`),{id:e};let n=await this.enclaveProvider.removeAddressMessageToSign(t.address,t.public_key??void 0,t.wallet_type),r=await this.enclaveProvider.signTypedData(n.domain,n.types,n.value),i=await this.enclaveProvider.removeAddressFromMpcSecret(t.user_id,n.value,r);return i!==`success`&&console.error(`Failed to add wallet to MPC: ${i}`),{id:e}}async removeWallets(e){for(let t of e)await this.removeWallet(t);return e}async filterCredentials(e){let t=(await this.getAllCredentials()).filter(e=>!e.original_id&&!!e.public_notes).filter(t=>e.acceptedIssuers?.some(e=>e.authPublicKey===t.issuer_auth_public_key)),n=e.publicNotesFieldFilters,a=e.credentialLevelOrHigherFilter,o=e.privateFieldFilters;if(a&&(t=t.filter(e=>{let t;try{t=JSON.parse(e.public_notes)}catch{throw Error(`Credential ${e.id} has non-JSON public notes.`)}return r(a.userLevel,a.requiredAddons,t.level)})),n&&(Object.keys(n.pick).length>0||Object.keys(n.omit).length>0)&&(t=t.filter(e=>{let t;try{t=JSON.parse(e.public_notes)}catch{throw Error(`Credential ${e.id} has non-JSON public notes.`)}return i(t,n.pick,n.omit)})),o&&(Object.keys(o.pick).length>0||Object.keys(o.omit).length>0)){let e=await Promise.all(t.map(e=>this.getCredentialById(e.id)));k(e.every(e=>e!==void 0),`Some credentials could not be fetched in full form for private field filtering`);let n=await this.enclaveProvider.filterCredentials(await Promise.all(e.map(e=>this.#n(e))),o);t=t.filter(e=>n.some(t=>t.id===e.id))}return t}async requestAccessGrant(t,{consumerEncryptionPublicKey:n,consumerAuthPublicKey:r,lockedUntil:i=0}){let a=await this.getCredentialById(t);k(a,`"idOSCredential" with id ${t} not found`);let o=await this.#r(a),s=E(o);await this.enclaveProvider.ensureUserEncryptionProfile();let{content:c,encryptorPublicKey:l}=await this.enclaveProvider.encrypt(o,w(n)),u=crypto.randomUUID(),d=P(this.walletType,this.kwilSigner,u);C(d,this.blobGateway.hasAccessToken);let f=d?{uri:d,size:c.byteLength}:await fe(c),p=e(``,f.uri),m=/^[0-9a-fA-F]{64}$/.test(r)?r.toLowerCase():r,h={...p,request_id:crypto.randomUUID(),copy_id:u,original_id:a.id,content_uri:f.uri,content_size:f.size,encryptor_public_key:T(l),grantee_wallet_identifier:m,locked_until:i,content_hash:s};return await this.shareCredential(h),await this.blobGateway.uploadCredentialBlobs({requestId:h.request_id,copy:c}),h}async#n(e){return e.content?e:{...e,content:T(await this.#i(e)),content_uri:null,content_size:null}}async#r(e){return await this.enclaveProvider.ensureUserEncryptionProfile(),this.enclaveProvider.decrypt(await this.#i(e),w(e.encryptor_public_key))}async#i(e){return pe(e,this.blobGateway)}};function ve(e){return new X({nodeUrl:e.nodeUrl,blobGatewayUrl:e.blobGatewayUrl,enclaveOptions:e.enclaveOptions})}export{A as IframeEnclave,ve as createIDOSClient,X as idOSClientConfiguration,Z as idOSClientIdle,$ as idOSClientLoggedIn,Q as idOSClientWithUserSigner,d as signNearMessage,b as toDelegatedWriteGrantBaseParams};
1
+ import{buildEphemeralSignedCredentialContentReference as e,buildPreliminaryIDOSCredential as t,mapPreliminaryToIDOSCredential as n,matchClaims as r,matchLevelOrHigher as i,recordFilter as a}from"@idos-network/credentials/utils";import{createClientKwilSigner as o,createKgwAuthenticatedBlobGateway as s,createNodeKwilClient as c,createWebKwilClient as l,isMmTokenAuth as u,mmTokenCredentialContentUri as d,signNearMessage as f}from"@idos-network/kwil-infra";import{addAttribute as p,addWallet as m,addWalletMessage as h,addWallets as ee,createPreliminaryCredential as te,dwgMessage as g,getAccessGrantsGrantedCount as _,getAccessGrantsOwned as ne,getAttributes as re,getCredentialOwned as ie,getCredentialShared as ae,getCredentials as oe,getGrants as v,getUser as se,getWallets as ce,hasProfile as y,removeCredential as b,removeWallet as le,revokeAccessGrant as x,sharePreliminaryCredential as ue,toDelegatedWriteGrantBaseParams as de}from"@idos-network/kwil-infra/actions";import{NodeKwil as fe}from"@idos-network/kwil-js";import{BlobGateway as S,createBlobContentReference as pe,requireAccessTokenForUkycContent as C,resolveCredentialEncryptedContent as me}from"@idos-network/utils/blob-gateway";import{base64Decode as w,base64Encode as T,hexEncodeSha256Hash as E,utf8Decode as D}from"@idos-network/utils/codecs";import{LocalStorageStore as he,MemoryStore as ge}from"@idos-network/utils/store";import O from"tiny-invariant";import{BaseProvider as _e}from"@idos-network/enclave";var k=class extends _e{container;iframe;hostUrl;bound=!1;constructor(e){if(super(e),!this.options.container)throw Error(`container is required`);this.container=this.options.container,this.hostUrl=new URL(this.options.url??`https://enclave.idos.network`),this.iframe=document.createElement(`iframe`),this.iframe.id=`idos-enclave-iframe`}async load(){await this.createAndLoadIframe(),await this.requestToEnclave(`load`),await this.reconfigure(),await this.bindMessageListener()}async reset(){throw Error(`Embedding pages cannot reset enclave storage`)}async reconfigure(e={}){super.reconfigure(e),await this.requestToEnclave(`reconfigure`,this.options)}async confirm(e){this.showEnclave();try{return await this.requestToEnclave(`confirm`,e)}catch(e){return console.error(e),!1}finally{this.hideEnclave()}}async filterCredentials(e,t){return await this.requestToEnclave(`filterCredentials`,e,t)}async encrypt(e,t){return this.requestToEnclave(`encrypt`,e,t)}async decrypt(e,t){return this.requestToEnclave(`decrypt`,e,t)}async backupUserEncryptionProfile(){this.showEnclave();try{await this.requestToEnclave(`backupUserEncryptionProfile`)}catch(e){console.error(e)}finally{this.hideEnclave()}}async ensureUserEncryptionProfile(){this.showEnclave();try{return await this.requestToEnclave(`ensureUserEncryptionProfile`)}finally{this.hideEnclave()}}async addAddressMessageToSign(e,t,n){return this.requestToEnclave(`addAddressMessageToSign`,e,t,n)}async removeAddressMessageToSign(e,t,n){return this.requestToEnclave(`removeAddressMessageToSign`,e,t,n)}async addAddressToMpcSecret(e,t,n){return this.requestToEnclave(`addAddressToMpcSecret`,e,t,n)}async removeAddressFromMpcSecret(e,t,n){return this.requestToEnclave(`removeAddressFromMpcSecret`,e,t,n)}async createAndLoadIframe(){let e=document.querySelector(this.container);if(!e)throw Error(`Can't find container with selector ${this.container}`);let t=[`publickey-credentials-get`,`storage-access`],n=[`forms`,`modals`,`popups`,`popups-to-escape-sandbox`,`same-origin`,`scripts`].map(e=>`allow-${e}`),r={"aspect-ratio":`4/1`,"background-color":`transparent`,border:`none`,display:`block`,overflow:`hidden`,width:`100%`};this.iframe.allow=t.join(`; `),this.iframe.referrerPolicy=`origin`,this.iframe.sandbox.add(...n),this.iframe.src=this.hostUrl.toString();for(let[e,t]of Object.entries(r))this.iframe.style.setProperty(e,t);let i;for(;i=document.getElementById(this.iframe.id);)console.log(`reinstalling idOS iframe...`),e.removeChild(i);return e.appendChild(this.iframe),new Promise(e=>this.iframe.addEventListener(`load`,()=>{e()},{once:!0}))}showEnclave(){this.iframe.parentElement.classList.add(`visible`)}hideEnclave(){this.iframe.parentElement.classList.remove(`visible`)}async requestToEnclave(e,...t){return new Promise((n,r)=>{let{port1:i,port2:a}=new MessageChannel;i.onmessage=({data:e})=>{i.close(),e.error?r(e.error):n(e.result)},this.iframe.contentWindow.postMessage({method:e,data:t},this.hostUrl.origin,[a])})}bindMessageListener(){this.bound||window.addEventListener(`message`,this.onMessage.bind(this)),this.bound=!0}async onMessage(e){if(!e||!e.data||typeof e.data!=`object`||e.data.type!==`idOS:signTypedData`||e.origin!==this.hostUrl.origin)return;let t=e.data.payload,n=await this.signTypedData(t.domain,t.types,t.value);await this.requestToEnclave(`signTypedDataResponse`,n)}};function A(){return typeof window<`u`}function j(e){return e.client instanceof fe}function M(e){return A()?new S({url:e,fetchFn:(e,t)=>fetch(e,{...t,credentials:`include`})}):new S({url:e})}function N(e,t){return j(e.kwilClient)?s({url:e.blobGateway.url,kwilClient:e.kwilClient,signer:t}):u(t)?e.blobGateway.withAccessToken(t.accessToken):e.blobGateway}function P(e,t,n){if(e===`MM`)return d(t,n)}const F="This idOS client is stale: another signer was set or it was logged out. Use the client returned by the latest `withUserSigner()`.",I=new WeakMap,L=new WeakMap,R=new WeakMap,z=new WeakMap,B=new WeakMap,V=new WeakSet;function H(e){return I.get(e)??e}function U(e,t){if(e.signer!==t)throw Error(F)}function W(e,t){let n=H(e),r=t?L.get(n)?.get(t):void 0;if(r)return r;let i=()=>U(n,t),a={get signer(){return i(),n.signer},get client(){return i(),n.client},call:async(...e)=>(i(),n.call(...e)),execute:async(...e)=>(i(),n.execute(...e)),waitForTx:async e=>(i(),n.waitForTx(e)),setSigner:e=>{i(),n.setSigner(e)}};if(I.set(a,n),t){let e=L.get(n)??new WeakMap;e.set(t,a),L.set(n,e)}return a}function G(e){return e&&R.get(e)||e}function K(e,t,n){let r=G(e),i=n?z.get(r)?.get(n):void 0;if(i)return i;let a=new Proxy(r,{get(e,r){if(r===`then`||typeof r==`symbol`)return;let i=Reflect.get(e,r,e);return typeof i==`function`?(...r)=>(U(t,n),i.apply(e,r)):(U(t,n),i)}});if(R.set(a,r),n){let e=z.get(r)??new WeakMap;e.set(n,a),z.set(r,e)}return a}function q(e,t){let n=H(e),r=(B.get(n)??Promise.resolve()).then(t,t);return B.set(n,r.then(()=>void 0,()=>void 0)),r}function J(){return new Proxy({},{get(e,t){if(t!==`signer`&&t!==`then`&&typeof t!=`symbol`){if(t===`client`)throw Error(F);return t===`setSigner`?()=>{throw Error(F)}:async()=>{throw Error(F)}}}})}function ve(e,t){return new Z(e,J(),J(),M(t))}function Y(e,t,n,r,i){let a=H(t);return q(a,async()=>{let t=a.signer;return t!==void 0&&t!==n||(t===n&&(a.setSigner(void 0),V.add(a)),V.has(a)&&(await r.reset(),V.delete(a)),a.signer!==void 0&&a.signer!==n)?ve(e,i):new Z(e,a,r,M(i))})}var X=class{state;chainId;nodeUrl;blobGatewayUrl;enclaveOptions;store;enclaveProvider;constructor(e){this.state=`configuration`,this.chainId=e.chainId,this.nodeUrl=e.nodeUrl,this.blobGatewayUrl=e.blobGatewayUrl,this.enclaveOptions=e.enclaveOptions,this.store=e.store??(A()?new he:new ge),this.enclaveProvider=e.enclaveProvider?new e.enclaveProvider({...e.enclaveOptions,store:this.store}):new k(e.enclaveOptions)}async createClient(){return Z.fromConfig(this)}},Z=class e{state;store;kwilClient;enclaveProvider;blobGateway;constructor(e,t,n,r){this.state=`idle`,this.store=e,this.kwilClient=t,this.enclaveProvider=n,this.blobGateway=r}static async fromConfig(t){let n=await(A()?l:c)({nodeUrl:t.nodeUrl,chainId:t.chainId});await t.enclaveProvider.load();let r=t.blobGatewayUrl??t.nodeUrl;return new e(t.store,n,t.enclaveProvider,M(r))}async addressHasProfile(e){return y(this.kwilClient,{address:e}).then(e=>e.has_profile)}async withUserSigner(e){let t=e,[n,r,i,a]=await o(this.store,this.kwilClient,t);if(a===`NEAR`){let e=t;t={signMessage:async t=>({signedMessage:await f(e,t)})}}return q(this.kwilClient,async()=>(this.kwilClient.setSigner(n),new Q(this,t,n,r,i,a,N(this,n))))}async logOut(){return this}},Q=class{state;store;#e;#t;signer;kwilSigner;walletIdentifier;walletPublicKey;walletType;blobGateway;constructor(e,t,n,r,i,a,o){this.state=`with-user-signer`,this.store=e.store,this.#e=e.kwilClient,this.#t=e.enclaveProvider,this.signer=t,this.kwilSigner=n,this.walletIdentifier=r,this.walletPublicKey=i,this.walletType=a,this.blobGateway=o,this.#t.setSigner(this.signer)}get kwilClient(){return W(this.#e,this.kwilSigner)}get enclaveProvider(){return K(this.#t,this.#e,this.kwilSigner)}async logOut(){return Y(this.store,this.#e,this.kwilSigner,this.#t,this.blobGateway.url)}async hasProfile(){let e=this.walletIdentifier;if(this.walletType===`NEAR`){if(!this.walletPublicKey)throw Error(`NEAR wallet public key is required`);e=this.walletPublicKey}return y(this.kwilClient,{address:e}).then(e=>e.has_profile)}async createUserEncryptionProfile(e,t){return await q(this.#e,async()=>{U(this.#e,this.kwilSigner),await this.enclaveProvider.reconfigure({mode:`new`,userId:e,walletAddress:this.walletIdentifier,walletPublicKey:this.walletPublicKey,walletType:this.walletType,encryptionPasswordStore:t,expectedUserEncryptionPublicKey:void 0}),U(this.#e,this.kwilSigner)}),U(this.#e,this.kwilSigner),this.enclaveProvider.ensureUserEncryptionProfile()}async logIn(){if(!await this.hasProfile())throw Error(`User does not have a profile`);let e=await se(this.kwilClient);return q(this.#e,async()=>(U(this.#e,this.kwilSigner),await this.enclaveProvider.reconfigure({mode:`existing`,userId:e.id,expectedUserEncryptionPublicKey:e.recipient_encryption_public_key,walletAddress:this.walletIdentifier,walletType:this.walletType,encryptionPasswordStore:e.encryption_password_store,walletPublicKey:this.walletPublicKey}),U(this.#e,this.kwilSigner),new $(this,e)))}},$=class{state;store;#e;#t;signer;kwilSigner;walletIdentifier;walletPublicKey;walletType;user;blobGateway;constructor(e,t){this.state=`logged-in`,this.store=e.store,this.#e=H(e.kwilClient),this.#t=G(e.enclaveProvider),this.signer=e.signer,this.kwilSigner=e.kwilSigner,this.walletIdentifier=e.walletIdentifier,this.walletPublicKey=e.walletPublicKey,this.walletType=e.walletType,this.user=t,this.blobGateway=e.blobGateway}get kwilClient(){return W(this.#e,this.kwilSigner)}get enclaveProvider(){return K(this.#t,this.#e,this.kwilSigner)}async logOut(){return Y(this.store,this.#e,this.kwilSigner,this.#t,this.blobGateway.url)}async requestDWGMessage(e){return g(this.kwilClient,e).then(e=>e.message)}async createCredential(e,r,i){let a=crypto.randomUUID(),o={...await t({publicNotes:e,plaintextContent:r,recipientEncryptionPublicKey:w(this.user.recipient_encryption_public_key),issuerSigningSecretKey:i,contentUri:P(this.walletType,this.kwilSigner,a)}),id:a};C(o.contentUri,this.blobGateway.hasAccessToken);let s=crypto.randomUUID(),c={request_id:s,credential_id:o.id,issuer_auth_public_key:o.issuerAuthPublicKey,encryptor_public_key:o.encryptorPublicKey,content_uri:o.contentUri,content_size:o.contentSize,content_hash:E(r),public_notes:o.publicNotes,public_notes_signature:o.publicNotesSignature,broader_signature:o.broaderSignature};return await te(this.kwilClient,c),await this.blobGateway.uploadCredentialBlobs({requestId:s,original:o.encryptedContent}),n(o)}async removeCredential(e){let t=await this.getCredentialById(e);O(t,`"idOSCredential" with id ${e} not found`);let n=t.content_uri??null;return C(n,this.blobGateway.hasAccessToken),await b(this.kwilClient,{id:e}),n&&await this.blobGateway.deleteCredentialBlob({credentialId:e}),{id:e}}async getCredentialById(e){return ie(this.kwilClient,{id:e}).then(e=>e[0])}async shareCredential(e){return await ue(this.kwilClient,e),e}async getAllCredentials(){return oe(this.kwilClient)}async getAccessGrantsOwned(){return ne(this.kwilClient)}async getAttributes(){return re(this.kwilClient)}async createAttribute(e){return await p(this.kwilClient,e),e}async getCredentialContentSha256Hash(e){let t=await this.getCredentialById(e);O(t,`"idOSCredential" with id ${e} not found`);let n=await this.#r(t);return E(n)}async getCredentialContent(e){let t=await this.getCredentialById(e);O(t,`"idOSCredential" with id ${e} not found`);let n=await this.#r(t);return D(n)}async getCredentialWithEncryptedContent(e){let t=await this.getCredentialById(e);return O(t,`"idOSCredential" with id ${e} not found`),this.#n(t)}async getCredentialSharedContent(e){let t=await this.getCredentialShared(e);O(t,`Shared credential with id ${e} not found`);let n=await this.#r(t);return D(n)}async getGrants(e){return{grants:await v(this.kwilClient,e),totalCount:await this.getGrantsCount()}}async addWallets(e){return await ee(this.kwilClient,e),e}async getGrantsCount(){return _(this.kwilClient,{user_id:null}).then(e=>e.count)}async getCredentialShared(e){return ae(this.kwilClient,{id:e}).then(e=>e[0])}async revokeAccessGrant(e){return await x(this.kwilClient,{id:e}),{id:e}}async addWalletMessage(e){return(await h(this.kwilClient,e)).message}async addWallet(e){if(await m(this.kwilClient,e),this.user.encryption_password_store!==`mpc`)return console.log(`MPC is not enabled or the user is not using MPC`),e;if(!e.wallet_type)throw Error(`Wallet type is required for MPC users`);let t=await this.enclaveProvider.addAddressMessageToSign(e.address,e.public_key??void 0,e.wallet_type),n=await this.enclaveProvider.signTypedData(t.domain,t.types,t.value),r=await this.enclaveProvider.addAddressToMpcSecret(this.user.id,t.value,n);return r!==`success`&&console.error(`Failed to add wallet to MPC: ${r}`),e}async getWallets(){return ce(this.kwilClient)}async removeWallet(e){let t=(await this.getWallets()).find(t=>t.id===e);if(!t)throw Error(`Wallet with id ${e} not found`);if(await le(this.kwilClient,{id:e}),this.user.encryption_password_store!==`mpc`)return console.log(`MPC is not enabled or the user is not using MPC`),{id:e};let n=await this.enclaveProvider.removeAddressMessageToSign(t.address,t.public_key??void 0,t.wallet_type),r=await this.enclaveProvider.signTypedData(n.domain,n.types,n.value),i=await this.enclaveProvider.removeAddressFromMpcSecret(t.user_id,n.value,r);return i!==`success`&&console.error(`Failed to add wallet to MPC: ${i}`),{id:e}}async removeWallets(e){for(let t of e)await this.removeWallet(t);return e}async filterCredentials(e){let t=(await this.getAllCredentials()).filter(e=>!e.original_id&&!!e.public_notes).filter(t=>e.acceptedIssuers?.some(e=>e.authPublicKey===t.issuer_auth_public_key)),n=e.publicNotesFieldFilters,o=e.credentialLevelOrHigherFilter,s=e.privateFieldFilters,c=e.claimsFilter;if(c&&(t=t.filter(e=>{let t;try{t=JSON.parse(e.public_notes)}catch{throw Error(`Credential ${e.id} has non-JSON public notes.`)}return r(c,t)})),o&&(t=t.filter(e=>{let t;try{t=JSON.parse(e.public_notes)}catch{throw Error(`Credential ${e.id} has non-JSON public notes.`)}return i(o.userLevel,o.requiredAddons,t.level)})),n&&(Object.keys(n.pick).length>0||Object.keys(n.omit).length>0)&&(t=t.filter(e=>{let t;try{t=JSON.parse(e.public_notes)}catch{throw Error(`Credential ${e.id} has non-JSON public notes.`)}return a(t,n.pick,n.omit)})),s&&(Object.keys(s.pick).length>0||Object.keys(s.omit).length>0)){let e=await Promise.all(t.map(e=>this.getCredentialById(e.id)));O(e.every(e=>e!==void 0),`Some credentials could not be fetched in full form for private field filtering`);let n=await this.enclaveProvider.filterCredentials(await Promise.all(e.map(e=>this.#n(e))),s);t=t.filter(e=>n.some(t=>t.id===e.id))}return t}async requestAccessGrant(t,{consumerEncryptionPublicKey:n,consumerAuthPublicKey:r,lockedUntil:i=0}){let a=await this.getCredentialById(t);O(a,`"idOSCredential" with id ${t} not found`);let o=await this.#r(a),s=E(o);await this.enclaveProvider.ensureUserEncryptionProfile();let{content:c,encryptorPublicKey:l}=await this.enclaveProvider.encrypt(o,w(n)),u=crypto.randomUUID(),d=P(this.walletType,this.kwilSigner,u);C(d,this.blobGateway.hasAccessToken);let f=d?{uri:d,size:c.byteLength}:await pe(c),p=e(``,f.uri),m=/^[0-9a-fA-F]{64}$/.test(r)?r.toLowerCase():r,h={...p,request_id:crypto.randomUUID(),copy_id:u,original_id:a.id,content_uri:f.uri,content_size:f.size,encryptor_public_key:T(l),grantee_wallet_identifier:m,locked_until:i,content_hash:s};return await this.shareCredential(h),await this.blobGateway.uploadCredentialBlobs({requestId:h.request_id,copy:c}),h}async#n(e){return e.content?e:{...e,content:T(await this.#i(e)),content_uri:null,content_size:null}}async#r(e){return await this.enclaveProvider.ensureUserEncryptionProfile(),this.enclaveProvider.decrypt(await this.#i(e),w(e.encryptor_public_key))}async#i(e){return me(e,this.blobGateway)}};function ye(e){return new X({nodeUrl:e.nodeUrl,blobGatewayUrl:e.blobGatewayUrl,enclaveOptions:e.enclaveOptions})}export{k as IframeEnclave,ye as createIDOSClient,X as idOSClientConfiguration,Z as idOSClientIdle,$ as idOSClientLoggedIn,Q as idOSClientWithUserSigner,f as signNearMessage,de as toDelegatedWriteGrantBaseParams};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["createAttribute","requestAddWalletMessage"],"sources":["../src/enclave/iframe-enclave.ts","../src/index.ts"],"sourcesContent":["import type { idOSCredentialRecord as idOSCredential } from \"@idos-network/credentials/types\";\nimport type {\n AddAddressMessageToSign,\n AddAddressSignatureMessage,\n RemoveAddressMessageToSign,\n RemoveAddressSignatureMessage,\n} from \"@idos-network/enclave/mpc\";\n\nimport {\n BaseProvider,\n type EnclaveOptions,\n type PublicEncryptionProfile,\n} from \"@idos-network/enclave\";\n\nimport type { BaseProviderMethodArgs, BaseProviderMethodReturn } from \"./helpers\";\n\nexport interface IframeEnclaveOptions extends EnclaveOptions {\n container: string;\n url?: string;\n throwOnUserCancelUnlock?: boolean;\n}\n\nexport class IframeEnclave extends BaseProvider<IframeEnclaveOptions> {\n private container: string;\n private iframe: HTMLIFrameElement;\n private hostUrl: URL;\n private bound = false;\n\n constructor(options: IframeEnclaveOptions) {\n super(options);\n\n if (!this.options.container) {\n throw new Error(\"container is required\");\n }\n\n this.container = this.options.container;\n this.hostUrl = new URL(this.options.url ?? \"https://enclave.idos.network\");\n this.iframe = document.createElement(\"iframe\");\n this.iframe.id = \"idos-enclave-iframe\";\n }\n\n /** @see parent method */\n async load(): Promise<void> {\n // First we have to create and load the iframe\n await this.createAndLoadIframe();\n\n // Load the enclave from the store (trigger load() method in the iframe)\n await this.requestToEnclave(\"load\");\n\n // Pass current options\n await this.reconfigure();\n\n // Bind the message listener to the iframe (in case iframe -> enclave comm)\n await this.bindMessageListener();\n }\n\n /**\n * Embedding pages cannot reset enclave storage. The iframe rejects `reset`\n * because it deletes every idOS-* key with no origin check.\n */\n async reset(): Promise<void> {\n throw new Error(\"Embedding pages cannot reset enclave storage\");\n }\n\n /** @override parent method to call iframe */\n async reconfigure(options: Omit<IframeEnclaveOptions, \"container\" | \"url\"> = {}): Promise<void> {\n super.reconfigure(options);\n await this.requestToEnclave(\"reconfigure\", this.options);\n }\n\n /** @override parent method to call iframe */\n async confirm(message: string): Promise<boolean> {\n this.showEnclave();\n\n try {\n return await this.requestToEnclave(\"confirm\", message);\n } catch (error) {\n console.error(error);\n return false;\n } finally {\n this.hideEnclave();\n }\n }\n\n /** @override parent method to call iframe */\n async filterCredentials(\n credentials: idOSCredential[],\n privateFieldFilters: { pick: Record<string, unknown[]>; omit: Record<string, unknown[]> },\n ): Promise<idOSCredential[]> {\n return await this.requestToEnclave(\"filterCredentials\", credentials, privateFieldFilters);\n }\n\n /** @override parent method to call iframe */\n async encrypt(\n message: Uint8Array,\n receiverPublicKey: Uint8Array,\n ): Promise<{ content: Uint8Array; encryptorPublicKey: Uint8Array }> {\n return this.requestToEnclave(\"encrypt\", message, receiverPublicKey);\n }\n\n /** @override parent method to call iframe */\n async decrypt(\n message: Uint8Array,\n senderPublicKey: Uint8Array,\n ): Promise<Uint8Array<ArrayBufferLike>> {\n return this.requestToEnclave(\"decrypt\", message, senderPublicKey);\n }\n\n /** @override parent method to call iframe */\n async backupUserEncryptionProfile(): Promise<void> {\n this.showEnclave();\n\n try {\n await this.requestToEnclave(\"backupUserEncryptionProfile\");\n } catch (error) {\n console.error(error);\n } finally {\n this.hideEnclave();\n }\n }\n\n /** @override parent method to call iframe */\n async ensureUserEncryptionProfile(): Promise<PublicEncryptionProfile> {\n this.showEnclave();\n\n try {\n return await this.requestToEnclave(\"ensureUserEncryptionProfile\");\n } finally {\n this.hideEnclave();\n }\n }\n\n async addAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToAddType: string,\n ): Promise<AddAddressMessageToSign> {\n return this.requestToEnclave(\"addAddressMessageToSign\", address, publicKey, addressToAddType);\n }\n\n async removeAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToRemoveType: string,\n ): Promise<RemoveAddressMessageToSign> {\n return this.requestToEnclave(\n \"removeAddressMessageToSign\",\n address,\n publicKey,\n addressToRemoveType,\n );\n }\n\n async addAddressToMpcSecret(\n userId: string,\n message: AddAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.requestToEnclave(\"addAddressToMpcSecret\", userId, message, signature);\n }\n\n async removeAddressFromMpcSecret(\n userId: string,\n message: RemoveAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.requestToEnclave(\"removeAddressFromMpcSecret\", userId, message, signature);\n }\n\n private async createAndLoadIframe(): Promise<void> {\n const container = document.querySelector(this.container);\n\n if (!container) {\n throw new Error(`Can't find container with selector ${this.container}`);\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#directives\n const permissionsPolicies = [\"publickey-credentials-get\", \"storage-access\"];\n\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox\n const liftedSandboxRestrictions = [\n \"forms\",\n \"modals\",\n \"popups\",\n \"popups-to-escape-sandbox\",\n \"same-origin\",\n \"scripts\",\n ].map((toLift) => `allow-${toLift}`);\n\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#referrerpolicy\n const referrerPolicy = \"origin\";\n\n const styles = {\n \"aspect-ratio\": \"4/1\",\n \"background-color\": \"transparent\",\n border: \"none\",\n display: \"block\",\n overflow: \"hidden\",\n width: \"100%\",\n };\n\n this.iframe.allow = permissionsPolicies.join(\"; \");\n this.iframe.referrerPolicy = referrerPolicy;\n this.iframe.sandbox.add(...liftedSandboxRestrictions);\n this.iframe.src = this.hostUrl.toString();\n for (const [k, v] of Object.entries(styles)) {\n this.iframe.style.setProperty(k, v);\n }\n\n let el: HTMLElement | null;\n // oxlint-disable-next-line no-cond-assign -- it's on purpose\n while ((el = document.getElementById(this.iframe.id))) {\n console.log(\"reinstalling idOS iframe...\");\n container.removeChild(el);\n }\n container.appendChild(this.iframe);\n\n return new Promise((resolve) =>\n this.iframe.addEventListener(\n \"load\",\n () => {\n resolve();\n },\n { once: true },\n ),\n );\n }\n\n private showEnclave(): void {\n // oxlint-disable-next-line typescript/no-non-null-assertion -- Make the explosion visible.\n this.iframe.parentElement!.classList.add(\"visible\");\n }\n\n private hideEnclave(): void {\n // oxlint-disable-next-line typescript/no-non-null-assertion -- Make the explosion visible.\n this.iframe.parentElement!.classList.remove(\"visible\");\n }\n\n private async requestToEnclave<TMethod extends keyof BaseProviderMethodArgs>(\n method: TMethod,\n ...args: BaseProviderMethodArgs[TMethod]\n ): Promise<BaseProviderMethodReturn[TMethod]> {\n return new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n\n port1.onmessage = ({ data }) => {\n port1.close();\n // oxlint-disable-next-line no-unused-expressions\n data.error ? reject(data.error) : resolve(data.result);\n };\n\n // oxlint-disable-next-line typescript/no-non-null-assertion -- Make the explosion visible.\n this.iframe.contentWindow!.postMessage(\n {\n method,\n data: args,\n },\n this.hostUrl.origin,\n [port2],\n );\n });\n }\n\n private bindMessageListener(): void {\n if (!this.bound) window.addEventListener(\"message\", this.onMessage.bind(this));\n this.bound = true;\n }\n\n private async onMessage(message: MessageEvent): Promise<void> {\n // We can't be sure about the message and the content\n // so we have to validate it carefully.\n if (!message || !message.data || typeof message.data !== \"object\") return;\n\n if (message.data.type !== \"idOS:signTypedData\" || message.origin !== this.hostUrl.origin)\n return;\n\n const payload = message.data.payload;\n const signature = await this.signTypedData(payload.domain, payload.types, payload.value);\n await this.requestToEnclave(\"signTypedDataResponse\", signature);\n }\n}\n","import type {\n BaseProvider,\n EncryptionPasswordStore,\n PublicEncryptionProfile,\n} from \"@idos-network/enclave\";\n\nimport {\n buildEphemeralSignedCredentialContentReference,\n buildPreliminaryIDOSCredential,\n mapPreliminaryToIDOSCredential,\n matchLevelOrHigher,\n type PreliminaryIDOSCredential,\n recordFilter,\n type BaseLevel,\n type Addon,\n} from \"@idos-network/credentials/utils\";\nimport {\n createClientKwilSigner,\n createKgwAuthenticatedBlobGateway,\n createNodeKwilClient,\n createWebKwilClient,\n isMmTokenAuth,\n type KwilActionClient,\n mmTokenCredentialContentUri,\n signNearMessage,\n type Wallet,\n} from \"@idos-network/kwil-infra\";\nimport {\n type AddAttributeInput,\n type AddWalletInput,\n type AddWalletMessageInput,\n addWallet,\n addWalletMessage as requestAddWalletMessage,\n addWallets,\n addAttribute as createAttribute,\n createPreliminaryCredential,\n type CreatePreliminaryCredentialInput,\n dwgMessage,\n type GetAccessGrantsGrantedInput,\n type GetWalletsOutput,\n getAccessGrantsGrantedCount,\n getAccessGrantsOwned,\n getAttributes,\n getCredentialOwned,\n getCredentialShared,\n getCredentials,\n getGrants,\n getUser,\n getWallets,\n hasProfile,\n type idOSCredential,\n type idOSCredentialListItem,\n type idOSDelegatedWriteGrant,\n type DelegatedWriteGrantBaseParams,\n toDelegatedWriteGrantBaseParams,\n type idOSGrant,\n type idOSUser,\n type idOSUserAttribute,\n type idOSWallet,\n removeCredential,\n removeWallet,\n revokeAccessGrant,\n type SharePreliminaryCredentialInput,\n sharePreliminaryCredential,\n type WalletType,\n} from \"@idos-network/kwil-infra/actions\";\nimport { NodeKwil, type KwilSigner } from \"@idos-network/kwil-js\";\nimport {\n BlobGateway,\n createBlobContentReference,\n requireAccessTokenForUkycContent,\n resolveCredentialEncryptedContent,\n} from \"@idos-network/utils/blob-gateway\";\nimport {\n base64Decode,\n base64Encode,\n hexEncodeSha256Hash,\n utf8Decode,\n} from \"@idos-network/utils/codecs\";\nimport { LocalStorageStore, MemoryStore, type Store } from \"@idos-network/utils/store\";\nimport invariant from \"tiny-invariant\";\n\nimport { IframeEnclave } from \"./enclave/iframe-enclave\";\nexport { IframeEnclave };\n\ntype Properties<T> = {\n // oxlint-disable-next-line typescript/no-restricted-types -- All functions are to be removed.\n [K in keyof T as Exclude<T[K], Function> extends never ? never : K]: T[K];\n};\n\nfunction isBrowserRuntime(): boolean {\n return typeof window !== \"undefined\";\n}\n\nfunction usesNodeKwil(kwilClient: KwilActionClient): boolean {\n return kwilClient.client instanceof NodeKwil;\n}\n\nfunction idleBlobGateway(url: string): BlobGateway {\n if (!isBrowserRuntime()) {\n return new BlobGateway({ url });\n }\n\n return new BlobGateway({\n url,\n // Browser blob reads need the KGW HttpOnly session cookie. That only works if the\n // blob gateway is covered by the cookie's Domain (typically same host as nodeUrl/KGW).\n fetchFn: (input, init) => fetch(input, { ...init, credentials: \"include\" }),\n });\n}\n\nfunction blobGatewayForSigner(idle: idOSClientIdle, kwilSigner: KwilSigner): BlobGateway {\n if (usesNodeKwil(idle.kwilClient)) {\n return createKgwAuthenticatedBlobGateway({\n url: idle.blobGateway.url,\n kwilClient: idle.kwilClient,\n signer: kwilSigner,\n });\n }\n\n return isMmTokenAuth(kwilSigner)\n ? idle.blobGateway.withAccessToken(kwilSigner.accessToken)\n : idle.blobGateway;\n}\n\nfunction contentUriForWallet(\n walletType: WalletType,\n kwilSigner: KwilSigner,\n credentialId: string,\n): string | undefined {\n if (walletType !== \"MM\") {\n return undefined;\n }\n return mmTokenCredentialContentUri(kwilSigner, credentialId);\n}\n\nconst STALE_CLIENT =\n \"This idOS client is stale: another signer was set or it was logged out. Use the client returned by the latest `withUserSigner()`.\";\n\n// Wrappers from one idle client share its Kwil client and enclave. `rawOf` unwraps the\n// guard below; `turns` keeps signer replacement and enclave reconfiguration from interleaving.\nconst rawOf = new WeakMap<KwilActionClient, KwilActionClient>();\nconst boundOf = new WeakMap<KwilActionClient, WeakMap<KwilSigner, KwilActionClient>>();\nconst rawEnclaveOf = new WeakMap<BaseProvider, BaseProvider>();\nconst boundEnclaveOf = new WeakMap<BaseProvider, WeakMap<KwilSigner, BaseProvider>>();\nconst turns = new WeakMap<KwilActionClient, Promise<void>>();\nconst resetPending = new WeakSet<KwilActionClient>();\n\nfunction sharedKwilClient(kwilClient: KwilActionClient): KwilActionClient {\n return rawOf.get(kwilClient) ?? kwilClient;\n}\n\nfunction assertSigner(kwilClient: KwilActionClient, kwilSigner: KwilSigner): void {\n if (kwilClient.signer !== kwilSigner) throw new Error(STALE_CLIENT);\n}\n\n// shortcut: guards call/execute/waitForTx/setSigner only; wrap any new KwilActionClient method here.\nfunction boundKwilClient(kwilClient: KwilActionClient, kwilSigner: KwilSigner): KwilActionClient {\n const raw = sharedKwilClient(kwilClient);\n const cached = kwilSigner ? boundOf.get(raw)?.get(kwilSigner) : undefined;\n if (cached) return cached;\n\n const guard = (): void => assertSigner(raw, kwilSigner);\n const bound = {\n get signer() {\n guard();\n return raw.signer;\n },\n get client() {\n guard();\n return raw.client;\n },\n call: async (...args: Parameters<KwilActionClient[\"call\"]>) => {\n guard();\n return raw.call(...args);\n },\n execute: async (...args: Parameters<KwilActionClient[\"execute\"]>) => {\n guard();\n return raw.execute(...args);\n },\n waitForTx: async (txHash: string) => {\n guard();\n return raw.waitForTx(txHash);\n },\n setSigner: (signer: KwilSigner | undefined) => {\n guard();\n raw.setSigner(signer);\n },\n } as KwilActionClient;\n\n rawOf.set(bound, raw);\n if (kwilSigner) {\n const bySigner = boundOf.get(raw) ?? new WeakMap<KwilSigner, KwilActionClient>();\n bySigner.set(kwilSigner, bound);\n boundOf.set(raw, bySigner);\n }\n return bound;\n}\n\nfunction sharedEnclave(enclave: BaseProvider): BaseProvider {\n return (enclave && rawEnclaveOf.get(enclave)) || enclave;\n}\n\nfunction boundEnclave(\n enclave: BaseProvider,\n kwilClient: KwilActionClient,\n kwilSigner: KwilSigner,\n): BaseProvider {\n const raw = sharedEnclave(enclave);\n const cached = kwilSigner ? boundEnclaveOf.get(raw)?.get(kwilSigner) : undefined;\n if (cached) return cached;\n\n const bound = new Proxy(raw, {\n get(target, prop) {\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n const value = Reflect.get(target, prop, target);\n if (typeof value !== \"function\") {\n assertSigner(kwilClient, kwilSigner);\n return value;\n }\n return (...args: unknown[]) => {\n assertSigner(kwilClient, kwilSigner);\n return value.apply(target, args);\n };\n },\n }) as BaseProvider;\n\n rawEnclaveOf.set(bound, raw);\n if (kwilSigner) {\n const bySigner = boundEnclaveOf.get(raw) ?? new WeakMap<KwilSigner, BaseProvider>();\n bySigner.set(kwilSigner, bound);\n boundEnclaveOf.set(raw, bySigner);\n }\n return bound;\n}\n\nfunction exclusive<T>(kwilClient: KwilActionClient, run: () => Promise<T>): Promise<T> {\n const raw = sharedKwilClient(kwilClient);\n const previous = turns.get(raw) ?? Promise.resolve();\n const result = previous.then(run, run);\n turns.set(\n raw,\n result.then(\n () => undefined,\n () => undefined,\n ),\n );\n return result;\n}\n\n// `setSigner` is synchronous on the real clients. A rejected promise here is not awaited\n// by `withUserSigner` or the enclave constructor, and Node can terminate on it.\nfunction detachedSurface<T extends object>(): T {\n return new Proxy({} as T, {\n get(_target, prop) {\n if (prop === \"signer\") return undefined;\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n if (prop === \"client\") throw new Error(STALE_CLIENT);\n if (prop === \"setSigner\") {\n return () => {\n throw new Error(STALE_CLIENT);\n };\n }\n return async () => {\n throw new Error(STALE_CLIENT);\n };\n },\n });\n}\n\nfunction staleIdle(store: Store, blobUrl: string): idOSClientIdle {\n return new idOSClientIdle(\n store,\n detachedSurface<KwilActionClient>(),\n detachedSurface<BaseProvider>(),\n idleBlobGateway(blobUrl),\n );\n}\n\n// A replaced signer keeps the session. The signer that actually logged out must finish\n// `reset` on a later attempt; success is only returned once that reset completes.\nfunction finishLogOut(\n store: Store,\n kwilClient: KwilActionClient,\n kwilSigner: KwilSigner,\n enclaveProvider: BaseProvider,\n blobUrl: string,\n): Promise<idOSClientIdle> {\n const raw = sharedKwilClient(kwilClient);\n return exclusive(raw, async () => {\n const current = raw.signer;\n if (current !== undefined && current !== kwilSigner) return staleIdle(store, blobUrl);\n\n if (current === kwilSigner) {\n raw.setSigner(undefined);\n resetPending.add(raw);\n }\n\n if (resetPending.has(raw)) {\n await enclaveProvider.reset();\n resetPending.delete(raw);\n }\n\n // A signer installed while `reset` was in progress must not ride back on this idle client.\n if (raw.signer !== undefined && raw.signer !== kwilSigner) return staleIdle(store, blobUrl);\n\n return new idOSClientIdle(store, raw, enclaveProvider, idleBlobGateway(blobUrl));\n });\n}\n\nexport type idOSClient =\n | idOSClientConfiguration\n | idOSClientIdle\n | idOSClientWithUserSigner\n | idOSClientLoggedIn;\n\nexport class idOSClientConfiguration<Provider extends BaseProvider = IframeEnclave> {\n readonly state: \"configuration\";\n readonly chainId?: string;\n readonly nodeUrl: string;\n readonly blobGatewayUrl?: string;\n readonly enclaveOptions: Omit<Provider[\"options\"], \"mode\">;\n readonly store: Store;\n readonly enclaveProvider: BaseProvider;\n\n constructor(params: {\n chainId?: string;\n nodeUrl: string;\n /**\n * Optional blob gateway base URL. Defaults to `nodeUrl`.\n * In the browser this must share KGW's session-cookie Domain\n * (typically the same host), because reads use `credentials: \"include\"`.\n */\n blobGatewayUrl?: string;\n enclaveOptions: Omit<Provider[\"options\"], \"mode\">;\n enclaveProvider?: new (options: Omit<Provider[\"options\"], \"mode\">) => Provider;\n store?: Store;\n }) {\n this.state = \"configuration\";\n this.chainId = params.chainId;\n this.nodeUrl = params.nodeUrl;\n this.blobGatewayUrl = params.blobGatewayUrl;\n this.enclaveOptions = params.enclaveOptions;\n this.store = params.store ?? (isBrowserRuntime() ? new LocalStorageStore() : new MemoryStore());\n\n // TODO: This is a mess because of types...\n if (params.enclaveProvider) {\n this.enclaveProvider = new params.enclaveProvider({\n ...params.enclaveOptions,\n // Some of enclave providers require store to be passed in constructor\n store: this.store,\n });\n } else {\n // @ts-expect-error - In case of missing \"container\" in options, enclave will blow up\n this.enclaveProvider = new IframeEnclave(params.enclaveOptions);\n }\n }\n\n async createClient(): Promise<idOSClientIdle> {\n return idOSClientIdle.fromConfig(this);\n }\n}\n\nexport class idOSClientIdle {\n readonly state: \"idle\";\n readonly store: Store;\n readonly kwilClient: KwilActionClient;\n readonly enclaveProvider: BaseProvider;\n readonly blobGateway: BlobGateway;\n\n constructor(\n store: Store,\n kwilClient: KwilActionClient,\n enclaveProvider: BaseProvider,\n blobGateway: BlobGateway,\n ) {\n this.state = \"idle\";\n this.store = store;\n this.kwilClient = kwilClient;\n this.enclaveProvider = enclaveProvider;\n this.blobGateway = blobGateway;\n }\n\n static async fromConfig(params: idOSClientConfiguration<BaseProvider>): Promise<idOSClientIdle> {\n const createKwilClient = isBrowserRuntime() ? createWebKwilClient : createNodeKwilClient;\n const kwilClient = await createKwilClient({\n nodeUrl: params.nodeUrl,\n chainId: params.chainId,\n });\n\n await params.enclaveProvider.load();\n\n const blobGatewayUrl = params.blobGatewayUrl ?? params.nodeUrl;\n return new idOSClientIdle(\n params.store,\n kwilClient,\n params.enclaveProvider,\n idleBlobGateway(blobGatewayUrl),\n );\n }\n\n async addressHasProfile(address: string): Promise<boolean> {\n return hasProfile(this.kwilClient, { address }).then((res) => res.has_profile);\n }\n\n async withUserSigner(_signer: Wallet): Promise<idOSClientWithUserSigner> {\n let signer = _signer;\n const [kwilSigner, walletIdentifier, walletPublicKey, walletType] =\n await createClientKwilSigner(this.store, this.kwilClient, signer);\n\n if (walletType === \"NEAR\") {\n const originalSigner = signer;\n signer = {\n signMessage: async (message: string) => {\n const signature = await signNearMessage(\n originalSigner as Parameters<typeof signNearMessage>[0],\n message,\n );\n return { signedMessage: signature } as { signedMessage: string };\n },\n } as unknown as Wallet;\n }\n\n return exclusive(this.kwilClient, async () => {\n this.kwilClient.setSigner(kwilSigner);\n return new idOSClientWithUserSigner(\n this,\n signer,\n kwilSigner,\n walletIdentifier,\n walletPublicKey,\n walletType,\n blobGatewayForSigner(this, kwilSigner),\n );\n });\n }\n\n async logOut(): Promise<idOSClientIdle> {\n return this;\n }\n}\n\nexport class idOSClientWithUserSigner implements Omit<Properties<idOSClientIdle>, \"state\"> {\n readonly state: \"with-user-signer\";\n readonly store: Store;\n readonly #kwilClient: KwilActionClient;\n readonly #enclaveProvider: BaseProvider;\n readonly signer: Wallet;\n readonly kwilSigner: KwilSigner;\n readonly walletIdentifier: string;\n readonly walletPublicKey: string | undefined;\n readonly walletType: WalletType;\n readonly blobGateway: BlobGateway;\n\n constructor(\n idOSClientIdle: idOSClientIdle,\n signer: Wallet,\n kwilSigner: KwilSigner,\n walletIdentifier: string,\n walletPublicKey: string | undefined,\n walletType: WalletType,\n blobGateway: BlobGateway,\n ) {\n this.state = \"with-user-signer\";\n this.store = idOSClientIdle.store;\n this.#kwilClient = idOSClientIdle.kwilClient;\n this.#enclaveProvider = idOSClientIdle.enclaveProvider;\n this.signer = signer;\n this.kwilSigner = kwilSigner;\n this.walletIdentifier = walletIdentifier;\n this.walletPublicKey = walletPublicKey;\n this.walletType = walletType;\n this.blobGateway = blobGateway;\n // @ts-expect-error - TODO: Fix this\n this.#enclaveProvider.setSigner(this.signer);\n }\n\n get kwilClient(): KwilActionClient {\n return boundKwilClient(this.#kwilClient, this.kwilSigner);\n }\n\n get enclaveProvider(): BaseProvider {\n return boundEnclave(this.#enclaveProvider, this.#kwilClient, this.kwilSigner);\n }\n\n async logOut(): Promise<idOSClientIdle> {\n return finishLogOut(\n this.store,\n this.#kwilClient,\n this.kwilSigner,\n this.#enclaveProvider,\n this.blobGateway.url,\n );\n }\n\n async hasProfile(): Promise<boolean> {\n return hasProfile(this.kwilClient, { address: this.walletIdentifier }).then(\n (x) => x.has_profile,\n );\n }\n\n async createUserEncryptionProfile(\n userId: string,\n forceEncryptionPasswordStore?: EncryptionPasswordStore,\n ): Promise<PublicEncryptionProfile> {\n await exclusive(this.#kwilClient, async () => {\n assertSigner(this.#kwilClient, this.kwilSigner);\n await this.enclaveProvider.reconfigure({\n mode: \"new\",\n userId,\n walletAddress: this.walletIdentifier,\n walletPublicKey: this.walletPublicKey,\n walletType: this.walletType,\n encryptionPasswordStore: forceEncryptionPasswordStore,\n expectedUserEncryptionPublicKey: undefined,\n });\n assertSigner(this.#kwilClient, this.kwilSigner);\n });\n assertSigner(this.#kwilClient, this.kwilSigner);\n return this.enclaveProvider.ensureUserEncryptionProfile();\n }\n\n async logIn(): Promise<idOSClientLoggedIn> {\n if (!(await this.hasProfile())) throw new Error(\"User does not have a profile\");\n\n const kwilUser = await getUser(this.kwilClient);\n\n return exclusive(this.#kwilClient, async () => {\n assertSigner(this.#kwilClient, this.kwilSigner);\n await this.enclaveProvider.reconfigure({\n mode: \"existing\",\n userId: kwilUser.id,\n expectedUserEncryptionPublicKey: kwilUser.recipient_encryption_public_key,\n walletAddress: this.walletIdentifier,\n walletType: this.walletType,\n encryptionPasswordStore: kwilUser.encryption_password_store,\n walletPublicKey: this.walletPublicKey,\n });\n assertSigner(this.#kwilClient, this.kwilSigner);\n return new idOSClientLoggedIn(this, kwilUser);\n });\n }\n}\n\nexport class idOSClientLoggedIn implements Omit<Properties<idOSClientWithUserSigner>, \"state\"> {\n readonly state: \"logged-in\";\n readonly store: Store;\n readonly #kwilClient: KwilActionClient;\n readonly #enclaveProvider: BaseProvider;\n readonly signer: Wallet;\n readonly kwilSigner: KwilSigner;\n readonly walletIdentifier: string;\n readonly walletPublicKey: string | undefined;\n readonly walletType: WalletType;\n readonly user: idOSUser;\n readonly blobGateway: BlobGateway;\n\n constructor(idOSClientWithUserSigner: idOSClientWithUserSigner, user: idOSUser) {\n this.state = \"logged-in\";\n this.store = idOSClientWithUserSigner.store;\n this.#kwilClient = sharedKwilClient(idOSClientWithUserSigner.kwilClient);\n this.#enclaveProvider = sharedEnclave(idOSClientWithUserSigner.enclaveProvider);\n this.signer = idOSClientWithUserSigner.signer;\n this.kwilSigner = idOSClientWithUserSigner.kwilSigner;\n this.walletIdentifier = idOSClientWithUserSigner.walletIdentifier;\n this.walletPublicKey = idOSClientWithUserSigner.walletPublicKey;\n this.walletType = idOSClientWithUserSigner.walletType;\n this.user = user;\n this.blobGateway = idOSClientWithUserSigner.blobGateway;\n }\n\n get kwilClient(): KwilActionClient {\n return boundKwilClient(this.#kwilClient, this.kwilSigner);\n }\n\n get enclaveProvider(): BaseProvider {\n return boundEnclave(this.#enclaveProvider, this.#kwilClient, this.kwilSigner);\n }\n\n async logOut(): Promise<idOSClientIdle> {\n return finishLogOut(\n this.store,\n this.#kwilClient,\n this.kwilSigner,\n this.#enclaveProvider,\n this.blobGateway.url,\n );\n }\n\n async requestDWGMessage(params: idOSDelegatedWriteGrant): Promise<string> {\n return dwgMessage(this.kwilClient, params).then((res) => res.message);\n }\n\n async createCredential(\n publicNotes: string,\n plaintextContent: Uint8Array<ArrayBufferLike>,\n // In case of credential creation on users behalf, this would be a issuer key\n issuerSigningSecretKey?: Uint8Array,\n ): Promise<Omit<idOSCredential, \"user_id\" | \"content\" | \"inserter_type\" | \"inserter_id\">> {\n const credentialId = crypto.randomUUID();\n const preliminaryCredential: PreliminaryIDOSCredential = {\n ...(await buildPreliminaryIDOSCredential({\n publicNotes,\n plaintextContent,\n recipientEncryptionPublicKey: base64Decode(this.user.recipient_encryption_public_key),\n issuerSigningSecretKey,\n contentUri: contentUriForWallet(this.walletType, this.kwilSigner, credentialId),\n })),\n id: credentialId,\n };\n requireAccessTokenForUkycContent(\n preliminaryCredential.contentUri,\n this.blobGateway.hasAccessToken,\n );\n\n const requestId = crypto.randomUUID();\n\n const payload: CreatePreliminaryCredentialInput = {\n request_id: requestId,\n credential_id: preliminaryCredential.id,\n issuer_auth_public_key: preliminaryCredential.issuerAuthPublicKey,\n encryptor_public_key: preliminaryCredential.encryptorPublicKey,\n content_uri: preliminaryCredential.contentUri,\n content_size: preliminaryCredential.contentSize,\n content_hash: hexEncodeSha256Hash(plaintextContent),\n public_notes: preliminaryCredential.publicNotes,\n public_notes_signature: preliminaryCredential.publicNotesSignature,\n broader_signature: preliminaryCredential.broaderSignature,\n };\n\n await createPreliminaryCredential(this.kwilClient, payload);\n\n await this.blobGateway.uploadCredentialBlobs({\n requestId,\n original: preliminaryCredential.encryptedContent,\n });\n\n return mapPreliminaryToIDOSCredential(preliminaryCredential);\n }\n\n async removeCredential(id: string): Promise<{ id: string }> {\n const credential = await this.getCredentialById(id);\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n\n const contentUri = credential.content_uri ?? null;\n requireAccessTokenForUkycContent(contentUri, this.blobGateway.hasAccessToken);\n\n await removeCredential(this.kwilClient, { id });\n\n if (!contentUri) {\n return { id };\n }\n\n await this.blobGateway.deleteCredentialBlob({ credentialId: id });\n return { id };\n }\n\n async getCredentialById(id: string): Promise<idOSCredential | undefined> {\n return getCredentialOwned(this.kwilClient, { id }).then((res) => res[0]);\n }\n\n async shareCredential(\n credential: SharePreliminaryCredentialInput,\n ): Promise<SharePreliminaryCredentialInput> {\n await sharePreliminaryCredential(this.kwilClient, credential);\n return credential;\n }\n\n async getAllCredentials(): Promise<idOSCredentialListItem[]> {\n return getCredentials(this.kwilClient);\n }\n\n async getAccessGrantsOwned(): Promise<idOSGrant[]> {\n return getAccessGrantsOwned(this.kwilClient);\n }\n\n async getAttributes(): Promise<idOSUserAttribute[]> {\n return getAttributes(this.kwilClient);\n }\n\n async createAttribute(attribute: AddAttributeInput): Promise<AddAttributeInput> {\n await createAttribute(this.kwilClient, attribute);\n return attribute;\n }\n\n async getCredentialContentSha256Hash(id: string): Promise<string> {\n const credential = await this.getCredentialById(id);\n\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n const plaintext = await this.#decryptCredentialContent(credential);\n\n return hexEncodeSha256Hash(plaintext);\n }\n\n async getCredentialContent(id: string): Promise<string> {\n const credential = await this.getCredentialById(id);\n\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n const plaintext = await this.#decryptCredentialContent(credential);\n\n return utf8Decode(plaintext);\n }\n\n async getCredentialWithEncryptedContent(id: string): Promise<idOSCredential> {\n const credential = await this.getCredentialById(id);\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n return this.#credentialWithInlineContent(credential);\n }\n\n async getCredentialSharedContent(id: string): Promise<string> {\n const credential = await this.getCredentialShared(id);\n\n invariant(credential, `Shared credential with id ${id} not found`);\n const plaintext = await this.#decryptCredentialContent(credential);\n\n return utf8Decode(plaintext);\n }\n\n async getGrants(\n params: Partial<GetAccessGrantsGrantedInput>,\n ): Promise<{ grants: idOSGrant[]; totalCount: number }> {\n return {\n grants: await getGrants(this.kwilClient, params),\n totalCount: await this.getGrantsCount(),\n };\n }\n\n async addWallets(params: AddWalletInput[]): Promise<AddWalletInput[]> {\n await addWallets(this.kwilClient, params);\n return params;\n }\n\n async getGrantsCount(): Promise<number> {\n return getAccessGrantsGrantedCount(this.kwilClient, {\n user_id: null,\n }).then((res) => res.count);\n }\n\n async getCredentialShared(id: string): Promise<idOSCredential | undefined> {\n return getCredentialShared(this.kwilClient, { id }).then((res) => res[0]);\n }\n\n async revokeAccessGrant(id: string): Promise<{ id: string }> {\n await revokeAccessGrant(this.kwilClient, { id });\n return { id };\n }\n\n async addWalletMessage(params: AddWalletMessageInput): Promise<string> {\n const result = await requestAddWalletMessage(this.kwilClient, params);\n return result.message;\n }\n\n async addWallet(params: AddWalletInput): Promise<AddWalletInput> {\n await addWallet(this.kwilClient, params);\n\n // we don't need to add the wallet to MPC if the user is not using MPC\n if (this.user.encryption_password_store !== \"mpc\") {\n console.log(\"MPC is not enabled or the user is not using MPC\");\n return params;\n }\n\n if (!params.wallet_type) {\n throw new Error(\"Wallet type is required for MPC users\");\n }\n\n const messageToSign = await this.enclaveProvider.addAddressMessageToSign(\n params.address,\n params.public_key ?? undefined,\n params.wallet_type,\n );\n\n const signature = await this.enclaveProvider.signTypedData(\n messageToSign.domain,\n messageToSign.types,\n messageToSign.value,\n );\n\n const result = await this.enclaveProvider.addAddressToMpcSecret(\n this.user.id,\n messageToSign.value,\n signature,\n );\n\n if (result !== \"success\") {\n console.error(`Failed to add wallet to MPC: ${result}`);\n }\n\n return params;\n }\n\n async getWallets(): Promise<GetWalletsOutput[]> {\n return getWallets(this.kwilClient);\n }\n\n async removeWallet(id: string): Promise<{ id: string }> {\n const wallets = await this.getWallets();\n const wallet = wallets.find((wallet) => wallet.id === id);\n if (!wallet) {\n throw new Error(`Wallet with id ${id} not found`);\n }\n\n await removeWallet(this.kwilClient, { id });\n\n // we don't need to add the wallet to MPC if the user is not using MPC\n if (this.user.encryption_password_store !== \"mpc\") {\n console.log(\"MPC is not enabled or the user is not using MPC\");\n return { id };\n }\n\n const messageToSign = await this.enclaveProvider.removeAddressMessageToSign(\n wallet.address,\n wallet.public_key ?? undefined,\n wallet.wallet_type,\n );\n const signature = await this.enclaveProvider.signTypedData(\n messageToSign.domain,\n messageToSign.types,\n messageToSign.value,\n );\n const result = await this.enclaveProvider.removeAddressFromMpcSecret(\n wallet.user_id,\n messageToSign.value,\n signature,\n );\n if (result !== \"success\") {\n console.error(`Failed to add wallet to MPC: ${result}`);\n }\n\n return { id };\n }\n\n async removeWallets(ids: string[]): Promise<string[]> {\n for (const id of ids) {\n await this.removeWallet(id);\n }\n\n return ids;\n }\n\n async filterCredentials(requirements: {\n acceptedIssuers: {\n authPublicKey: string;\n }[];\n publicNotesFieldFilters?: {\n pick: Parameters<typeof recordFilter>[1];\n omit: Parameters<typeof recordFilter>[2];\n };\n privateFieldFilters?: {\n pick: Parameters<typeof recordFilter>[1];\n omit: Parameters<typeof recordFilter>[2];\n };\n credentialLevelOrHigherFilter?: {\n userLevel: BaseLevel;\n requiredAddons: Addon[];\n };\n }): Promise<idOSCredentialListItem[]> {\n const credentials = await this.getAllCredentials();\n const originalCredentials = credentials.filter(\n (cred) => !cred.original_id && !!cred.public_notes,\n );\n\n // invariant(originalCredentials.length, \"No original credentials found\");\n let result = originalCredentials.filter((cred) => {\n return requirements.acceptedIssuers?.some(\n (issuer) => issuer.authPublicKey === cred.issuer_auth_public_key,\n );\n });\n\n const publicNotesFieldFilters = requirements.publicNotesFieldFilters;\n const credentialLevelOrHigherFilter = requirements.credentialLevelOrHigherFilter;\n const privateFieldFilters = requirements.privateFieldFilters;\n\n if (credentialLevelOrHigherFilter) {\n result = result.filter((credential) => {\n let publicNotes: Record<string, string>;\n\n try {\n publicNotes = JSON.parse(credential.public_notes);\n } catch (_) {\n throw new Error(`Credential ${credential.id} has non-JSON public notes.`);\n }\n\n return matchLevelOrHigher(\n credentialLevelOrHigherFilter.userLevel,\n credentialLevelOrHigherFilter.requiredAddons,\n publicNotes.level,\n );\n });\n }\n\n if (\n publicNotesFieldFilters &&\n (Object.keys(publicNotesFieldFilters.pick).length > 0 ||\n Object.keys(publicNotesFieldFilters.omit).length > 0)\n ) {\n result = result.filter((credential) => {\n let publicNotes: Record<string, string>;\n\n try {\n publicNotes = JSON.parse(credential.public_notes);\n } catch (_) {\n throw new Error(`Credential ${credential.id} has non-JSON public notes.`);\n }\n\n return recordFilter(\n publicNotes,\n publicNotesFieldFilters.pick,\n publicNotesFieldFilters.omit,\n );\n });\n }\n\n // Private field filtering requires decryption and the full idOS credential content\n // it's most \"expensive\", since it requires a roundtrip to the nodes and roundtrip to enclave.\n if (\n privateFieldFilters &&\n (Object.keys(privateFieldFilters.pick).length > 0 ||\n Object.keys(privateFieldFilters.omit).length > 0)\n ) {\n const fullCredentials = await Promise.all(\n result.map((credential) => this.getCredentialById(credential.id)),\n );\n\n // Check for undefined, it will be sign of some internal error\n invariant(\n fullCredentials.every((cred) => cred !== undefined),\n \"Some credentials could not be fetched in full form for private field filtering\",\n );\n\n const matches = await this.enclaveProvider.filterCredentials(\n await Promise.all(\n fullCredentials.map((credential) => this.#credentialWithInlineContent(credential)),\n ),\n privateFieldFilters,\n );\n\n result = result.filter((credential) =>\n matches.some((matchedCredential) => matchedCredential.id === credential.id),\n );\n }\n\n return result;\n }\n\n async requestAccessGrant(\n credentialId: string,\n {\n consumerEncryptionPublicKey,\n consumerAuthPublicKey,\n lockedUntil = 0,\n }: {\n consumerEncryptionPublicKey: string;\n consumerAuthPublicKey: string;\n lockedUntil?: number;\n },\n ): Promise<SharePreliminaryCredentialInput> {\n const credential = await this.getCredentialById(credentialId);\n\n invariant(credential, `\"idOSCredential\" with id ${credentialId} not found`);\n\n const plaintextContent = await this.#decryptCredentialContent(credential);\n const contentHash = hexEncodeSha256Hash(plaintextContent);\n\n await this.enclaveProvider.ensureUserEncryptionProfile();\n\n const { content, encryptorPublicKey } = await this.enclaveProvider.encrypt(\n plaintextContent,\n base64Decode(consumerEncryptionPublicKey),\n );\n\n // User issues the shared copy: sign content_uri with an ephemeral user-side key.\n // Copy issuer_auth_public_key need not match the original credential's issuer.\n const copyId = crypto.randomUUID();\n const ukycContentUri = contentUriForWallet(this.walletType, this.kwilSigner, copyId);\n requireAccessTokenForUkycContent(ukycContentUri, this.blobGateway.hasAccessToken);\n const copyReference = ukycContentUri\n ? { uri: ukycContentUri, size: content.byteLength }\n : await createBlobContentReference(content);\n const signedReference = buildEphemeralSignedCredentialContentReference(\"\", copyReference.uri);\n\n // Integrator-supplied. ed25519 @caller is lowercase hex; after exact grantee\n // matching, uppercase hex would store a grant the consumer cannot read. Other\n // identifier encodings (NEAR, XRPL, Stellar, MM) are case-sensitive, so leave them.\n const granteeWalletIdentifier = /^[0-9a-fA-F]{64}$/.test(consumerAuthPublicKey)\n ? consumerAuthPublicKey.toLowerCase()\n : consumerAuthPublicKey;\n\n const preliminaryCredential: SharePreliminaryCredentialInput = {\n ...signedReference,\n request_id: crypto.randomUUID(),\n copy_id: copyId,\n original_id: credential.id,\n content_uri: copyReference.uri,\n content_size: copyReference.size,\n encryptor_public_key: base64Encode(encryptorPublicKey),\n grantee_wallet_identifier: granteeWalletIdentifier,\n locked_until: lockedUntil,\n content_hash: contentHash,\n };\n\n await this.shareCredential(preliminaryCredential);\n await this.blobGateway.uploadCredentialBlobs({\n requestId: preliminaryCredential.request_id,\n copy: content,\n });\n\n return preliminaryCredential;\n }\n\n async #credentialWithInlineContent(credential: idOSCredential): Promise<idOSCredential> {\n if (credential.content) {\n return credential;\n }\n\n return {\n ...credential,\n content: base64Encode(await this.#getCredentialEncryptedContent(credential)),\n content_uri: null,\n content_size: null,\n };\n }\n\n async #decryptCredentialContent(credential: idOSCredential): Promise<Uint8Array> {\n await this.enclaveProvider.ensureUserEncryptionProfile();\n\n return this.enclaveProvider.decrypt(\n await this.#getCredentialEncryptedContent(credential),\n base64Decode(credential.encryptor_public_key),\n );\n }\n\n async #getCredentialEncryptedContent(credential: idOSCredential): Promise<Uint8Array> {\n return resolveCredentialEncryptedContent(credential, this.blobGateway);\n }\n}\n\nexport type {\n idOSDelegatedWriteGrant,\n DelegatedWriteGrantBaseParams,\n idOSCredential,\n idOSCredentialListItem,\n idOSGrant,\n idOSUser,\n idOSUserAttribute,\n idOSWallet,\n};\n\nexport { signNearMessage, toDelegatedWriteGrantBaseParams };\n\nexport function createIDOSClient(params: {\n nodeUrl: string;\n /**\n * Optional blob gateway base URL. Defaults to `nodeUrl`.\n * In the browser this must share KGW's session-cookie Domain\n * (typically the same host), because reads use `credentials: \"include\"`.\n */\n blobGatewayUrl?: string;\n enclaveOptions: Omit<IframeEnclave[\"options\"], \"mode\">;\n}): idOSClientConfiguration<IframeEnclave> {\n return new idOSClientConfiguration({\n nodeUrl: params.nodeUrl,\n blobGatewayUrl: params.blobGatewayUrl,\n enclaveOptions: params.enclaveOptions,\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["createAttribute","requestAddWalletMessage"],"sources":["../src/enclave/iframe-enclave.ts","../src/index.ts"],"sourcesContent":["import type { idOSCredentialRecord as idOSCredential } from \"@idos-network/credentials/types\";\nimport type {\n AddAddressMessageToSign,\n AddAddressSignatureMessage,\n RemoveAddressMessageToSign,\n RemoveAddressSignatureMessage,\n} from \"@idos-network/enclave/mpc\";\n\nimport {\n BaseProvider,\n type EnclaveOptions,\n type PublicEncryptionProfile,\n} from \"@idos-network/enclave\";\n\nimport type { BaseProviderMethodArgs, BaseProviderMethodReturn } from \"./helpers\";\n\nexport interface IframeEnclaveOptions extends EnclaveOptions {\n container: string;\n url?: string;\n throwOnUserCancelUnlock?: boolean;\n}\n\nexport class IframeEnclave extends BaseProvider<IframeEnclaveOptions> {\n private container: string;\n private iframe: HTMLIFrameElement;\n private hostUrl: URL;\n private bound = false;\n\n constructor(options: IframeEnclaveOptions) {\n super(options);\n\n if (!this.options.container) {\n throw new Error(\"container is required\");\n }\n\n this.container = this.options.container;\n this.hostUrl = new URL(this.options.url ?? \"https://enclave.idos.network\");\n this.iframe = document.createElement(\"iframe\");\n this.iframe.id = \"idos-enclave-iframe\";\n }\n\n /** @see parent method */\n async load(): Promise<void> {\n // First we have to create and load the iframe\n await this.createAndLoadIframe();\n\n // Load the enclave from the store (trigger load() method in the iframe)\n await this.requestToEnclave(\"load\");\n\n // Pass current options\n await this.reconfigure();\n\n // Bind the message listener to the iframe (in case iframe -> enclave comm)\n await this.bindMessageListener();\n }\n\n /**\n * Embedding pages cannot reset enclave storage. The iframe rejects `reset`\n * because it deletes every idOS-* key with no origin check.\n */\n async reset(): Promise<void> {\n throw new Error(\"Embedding pages cannot reset enclave storage\");\n }\n\n /** @override parent method to call iframe */\n async reconfigure(options: Omit<IframeEnclaveOptions, \"container\" | \"url\"> = {}): Promise<void> {\n super.reconfigure(options);\n await this.requestToEnclave(\"reconfigure\", this.options);\n }\n\n /** @override parent method to call iframe */\n async confirm(message: string): Promise<boolean> {\n this.showEnclave();\n\n try {\n return await this.requestToEnclave(\"confirm\", message);\n } catch (error) {\n console.error(error);\n return false;\n } finally {\n this.hideEnclave();\n }\n }\n\n /** @override parent method to call iframe */\n async filterCredentials(\n credentials: idOSCredential[],\n privateFieldFilters: { pick: Record<string, unknown[]>; omit: Record<string, unknown[]> },\n ): Promise<idOSCredential[]> {\n return await this.requestToEnclave(\"filterCredentials\", credentials, privateFieldFilters);\n }\n\n /** @override parent method to call iframe */\n async encrypt(\n message: Uint8Array,\n receiverPublicKey: Uint8Array,\n ): Promise<{ content: Uint8Array; encryptorPublicKey: Uint8Array }> {\n return this.requestToEnclave(\"encrypt\", message, receiverPublicKey);\n }\n\n /** @override parent method to call iframe */\n async decrypt(\n message: Uint8Array,\n senderPublicKey: Uint8Array,\n ): Promise<Uint8Array<ArrayBufferLike>> {\n return this.requestToEnclave(\"decrypt\", message, senderPublicKey);\n }\n\n /** @override parent method to call iframe */\n async backupUserEncryptionProfile(): Promise<void> {\n this.showEnclave();\n\n try {\n await this.requestToEnclave(\"backupUserEncryptionProfile\");\n } catch (error) {\n console.error(error);\n } finally {\n this.hideEnclave();\n }\n }\n\n /** @override parent method to call iframe */\n async ensureUserEncryptionProfile(): Promise<PublicEncryptionProfile> {\n this.showEnclave();\n\n try {\n return await this.requestToEnclave(\"ensureUserEncryptionProfile\");\n } finally {\n this.hideEnclave();\n }\n }\n\n async addAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToAddType: string,\n ): Promise<AddAddressMessageToSign> {\n return this.requestToEnclave(\"addAddressMessageToSign\", address, publicKey, addressToAddType);\n }\n\n async removeAddressMessageToSign(\n address: string,\n publicKey: string | undefined,\n addressToRemoveType: string,\n ): Promise<RemoveAddressMessageToSign> {\n return this.requestToEnclave(\n \"removeAddressMessageToSign\",\n address,\n publicKey,\n addressToRemoveType,\n );\n }\n\n async addAddressToMpcSecret(\n userId: string,\n message: AddAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.requestToEnclave(\"addAddressToMpcSecret\", userId, message, signature);\n }\n\n async removeAddressFromMpcSecret(\n userId: string,\n message: RemoveAddressSignatureMessage,\n signature: string,\n ): Promise<string> {\n return this.requestToEnclave(\"removeAddressFromMpcSecret\", userId, message, signature);\n }\n\n private async createAndLoadIframe(): Promise<void> {\n const container = document.querySelector(this.container);\n\n if (!container) {\n throw new Error(`Can't find container with selector ${this.container}`);\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#directives\n const permissionsPolicies = [\"publickey-credentials-get\", \"storage-access\"];\n\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox\n const liftedSandboxRestrictions = [\n \"forms\",\n \"modals\",\n \"popups\",\n \"popups-to-escape-sandbox\",\n \"same-origin\",\n \"scripts\",\n ].map((toLift) => `allow-${toLift}`);\n\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#referrerpolicy\n const referrerPolicy = \"origin\";\n\n const styles = {\n \"aspect-ratio\": \"4/1\",\n \"background-color\": \"transparent\",\n border: \"none\",\n display: \"block\",\n overflow: \"hidden\",\n width: \"100%\",\n };\n\n this.iframe.allow = permissionsPolicies.join(\"; \");\n this.iframe.referrerPolicy = referrerPolicy;\n this.iframe.sandbox.add(...liftedSandboxRestrictions);\n this.iframe.src = this.hostUrl.toString();\n for (const [k, v] of Object.entries(styles)) {\n this.iframe.style.setProperty(k, v);\n }\n\n let el: HTMLElement | null;\n // oxlint-disable-next-line no-cond-assign -- it's on purpose\n while ((el = document.getElementById(this.iframe.id))) {\n console.log(\"reinstalling idOS iframe...\");\n container.removeChild(el);\n }\n container.appendChild(this.iframe);\n\n return new Promise((resolve) =>\n this.iframe.addEventListener(\n \"load\",\n () => {\n resolve();\n },\n { once: true },\n ),\n );\n }\n\n private showEnclave(): void {\n // oxlint-disable-next-line typescript/no-non-null-assertion -- Make the explosion visible.\n this.iframe.parentElement!.classList.add(\"visible\");\n }\n\n private hideEnclave(): void {\n // oxlint-disable-next-line typescript/no-non-null-assertion -- Make the explosion visible.\n this.iframe.parentElement!.classList.remove(\"visible\");\n }\n\n private async requestToEnclave<TMethod extends keyof BaseProviderMethodArgs>(\n method: TMethod,\n ...args: BaseProviderMethodArgs[TMethod]\n ): Promise<BaseProviderMethodReturn[TMethod]> {\n return new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n\n port1.onmessage = ({ data }) => {\n port1.close();\n // oxlint-disable-next-line no-unused-expressions\n data.error ? reject(data.error) : resolve(data.result);\n };\n\n // oxlint-disable-next-line typescript/no-non-null-assertion -- Make the explosion visible.\n this.iframe.contentWindow!.postMessage(\n {\n method,\n data: args,\n },\n this.hostUrl.origin,\n [port2],\n );\n });\n }\n\n private bindMessageListener(): void {\n if (!this.bound) window.addEventListener(\"message\", this.onMessage.bind(this));\n this.bound = true;\n }\n\n private async onMessage(message: MessageEvent): Promise<void> {\n // We can't be sure about the message and the content\n // so we have to validate it carefully.\n if (!message || !message.data || typeof message.data !== \"object\") return;\n\n if (message.data.type !== \"idOS:signTypedData\" || message.origin !== this.hostUrl.origin)\n return;\n\n const payload = message.data.payload;\n const signature = await this.signTypedData(payload.domain, payload.types, payload.value);\n await this.requestToEnclave(\"signTypedDataResponse\", signature);\n }\n}\n","import type {\n BaseProvider,\n EncryptionPasswordStore,\n PublicEncryptionProfile,\n} from \"@idos-network/enclave\";\n\nimport {\n buildEphemeralSignedCredentialContentReference,\n buildPreliminaryIDOSCredential,\n mapPreliminaryToIDOSCredential,\n matchClaims,\n matchLevelOrHigher,\n type PreliminaryIDOSCredential,\n recordFilter,\n type BaseLevel,\n type Addon,\n type Claim,\n type ClaimRequirements,\n type Claims,\n type ClaimSource,\n type ClaimSources,\n} from \"@idos-network/credentials/utils\";\nimport {\n createClientKwilSigner,\n createKgwAuthenticatedBlobGateway,\n createNodeKwilClient,\n createWebKwilClient,\n isMmTokenAuth,\n type KwilActionClient,\n mmTokenCredentialContentUri,\n signNearMessage,\n type Wallet,\n} from \"@idos-network/kwil-infra\";\nimport {\n type AddAttributeInput,\n type AddWalletInput,\n type AddWalletMessageInput,\n addWallet,\n addWalletMessage as requestAddWalletMessage,\n addWallets,\n addAttribute as createAttribute,\n createPreliminaryCredential,\n type CreatePreliminaryCredentialInput,\n dwgMessage,\n type GetAccessGrantsGrantedInput,\n type GetWalletsOutput,\n getAccessGrantsGrantedCount,\n getAccessGrantsOwned,\n getAttributes,\n getCredentialOwned,\n getCredentialShared,\n getCredentials,\n getGrants,\n getUser,\n getWallets,\n hasProfile,\n type idOSCredential,\n type idOSCredentialListItem,\n type idOSDelegatedWriteGrant,\n type DelegatedWriteGrantBaseParams,\n toDelegatedWriteGrantBaseParams,\n type idOSGrant,\n type idOSUser,\n type idOSUserAttribute,\n type idOSWallet,\n removeCredential,\n removeWallet,\n revokeAccessGrant,\n type SharePreliminaryCredentialInput,\n sharePreliminaryCredential,\n type WalletType,\n} from \"@idos-network/kwil-infra/actions\";\nimport { NodeKwil, type KwilSigner } from \"@idos-network/kwil-js\";\nimport {\n BlobGateway,\n createBlobContentReference,\n requireAccessTokenForUkycContent,\n resolveCredentialEncryptedContent,\n} from \"@idos-network/utils/blob-gateway\";\nimport {\n base64Decode,\n base64Encode,\n hexEncodeSha256Hash,\n utf8Decode,\n} from \"@idos-network/utils/codecs\";\nimport { LocalStorageStore, MemoryStore, type Store } from \"@idos-network/utils/store\";\nimport invariant from \"tiny-invariant\";\n\nimport { IframeEnclave } from \"./enclave/iframe-enclave\";\nexport { IframeEnclave };\n\ntype Properties<T> = {\n // oxlint-disable-next-line typescript/no-restricted-types -- All functions are to be removed.\n [K in keyof T as Exclude<T[K], Function> extends never ? never : K]: T[K];\n};\n\nfunction isBrowserRuntime(): boolean {\n return typeof window !== \"undefined\";\n}\n\nfunction usesNodeKwil(kwilClient: KwilActionClient): boolean {\n return kwilClient.client instanceof NodeKwil;\n}\n\nfunction idleBlobGateway(url: string): BlobGateway {\n if (!isBrowserRuntime()) {\n return new BlobGateway({ url });\n }\n\n return new BlobGateway({\n url,\n // Browser blob reads need the KGW HttpOnly session cookie. That only works if the\n // blob gateway is covered by the cookie's Domain (typically same host as nodeUrl/KGW).\n fetchFn: (input, init) => fetch(input, { ...init, credentials: \"include\" }),\n });\n}\n\nfunction blobGatewayForSigner(idle: idOSClientIdle, kwilSigner: KwilSigner): BlobGateway {\n if (usesNodeKwil(idle.kwilClient)) {\n return createKgwAuthenticatedBlobGateway({\n url: idle.blobGateway.url,\n kwilClient: idle.kwilClient,\n signer: kwilSigner,\n });\n }\n\n return isMmTokenAuth(kwilSigner)\n ? idle.blobGateway.withAccessToken(kwilSigner.accessToken)\n : idle.blobGateway;\n}\n\nfunction contentUriForWallet(\n walletType: WalletType,\n kwilSigner: KwilSigner,\n credentialId: string,\n): string | undefined {\n if (walletType !== \"MM\") {\n return undefined;\n }\n return mmTokenCredentialContentUri(kwilSigner, credentialId);\n}\n\nconst STALE_CLIENT =\n \"This idOS client is stale: another signer was set or it was logged out. Use the client returned by the latest `withUserSigner()`.\";\n\n// Wrappers from one idle client share its Kwil client and enclave. `rawOf` unwraps the\n// guard below; `turns` keeps signer replacement and enclave reconfiguration from interleaving.\nconst rawOf = new WeakMap<KwilActionClient, KwilActionClient>();\nconst boundOf = new WeakMap<KwilActionClient, WeakMap<KwilSigner, KwilActionClient>>();\nconst rawEnclaveOf = new WeakMap<BaseProvider, BaseProvider>();\nconst boundEnclaveOf = new WeakMap<BaseProvider, WeakMap<KwilSigner, BaseProvider>>();\nconst turns = new WeakMap<KwilActionClient, Promise<void>>();\nconst resetPending = new WeakSet<KwilActionClient>();\n\nfunction sharedKwilClient(kwilClient: KwilActionClient): KwilActionClient {\n return rawOf.get(kwilClient) ?? kwilClient;\n}\n\nfunction assertSigner(kwilClient: KwilActionClient, kwilSigner: KwilSigner): void {\n if (kwilClient.signer !== kwilSigner) throw new Error(STALE_CLIENT);\n}\n\n// shortcut: guards call/execute/waitForTx/setSigner only; wrap any new KwilActionClient method here.\nfunction boundKwilClient(kwilClient: KwilActionClient, kwilSigner: KwilSigner): KwilActionClient {\n const raw = sharedKwilClient(kwilClient);\n const cached = kwilSigner ? boundOf.get(raw)?.get(kwilSigner) : undefined;\n if (cached) return cached;\n\n const guard = (): void => assertSigner(raw, kwilSigner);\n const bound = {\n get signer() {\n guard();\n return raw.signer;\n },\n get client() {\n guard();\n return raw.client;\n },\n call: async (...args: Parameters<KwilActionClient[\"call\"]>) => {\n guard();\n return raw.call(...args);\n },\n execute: async (...args: Parameters<KwilActionClient[\"execute\"]>) => {\n guard();\n return raw.execute(...args);\n },\n waitForTx: async (txHash: string) => {\n guard();\n return raw.waitForTx(txHash);\n },\n setSigner: (signer: KwilSigner | undefined) => {\n guard();\n raw.setSigner(signer);\n },\n } as KwilActionClient;\n\n rawOf.set(bound, raw);\n if (kwilSigner) {\n const bySigner = boundOf.get(raw) ?? new WeakMap<KwilSigner, KwilActionClient>();\n bySigner.set(kwilSigner, bound);\n boundOf.set(raw, bySigner);\n }\n return bound;\n}\n\nfunction sharedEnclave(enclave: BaseProvider): BaseProvider {\n return (enclave && rawEnclaveOf.get(enclave)) || enclave;\n}\n\nfunction boundEnclave(\n enclave: BaseProvider,\n kwilClient: KwilActionClient,\n kwilSigner: KwilSigner,\n): BaseProvider {\n const raw = sharedEnclave(enclave);\n const cached = kwilSigner ? boundEnclaveOf.get(raw)?.get(kwilSigner) : undefined;\n if (cached) return cached;\n\n const bound = new Proxy(raw, {\n get(target, prop) {\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n const value = Reflect.get(target, prop, target);\n if (typeof value !== \"function\") {\n assertSigner(kwilClient, kwilSigner);\n return value;\n }\n return (...args: unknown[]) => {\n assertSigner(kwilClient, kwilSigner);\n return value.apply(target, args);\n };\n },\n }) as BaseProvider;\n\n rawEnclaveOf.set(bound, raw);\n if (kwilSigner) {\n const bySigner = boundEnclaveOf.get(raw) ?? new WeakMap<KwilSigner, BaseProvider>();\n bySigner.set(kwilSigner, bound);\n boundEnclaveOf.set(raw, bySigner);\n }\n return bound;\n}\n\nfunction exclusive<T>(kwilClient: KwilActionClient, run: () => Promise<T>): Promise<T> {\n const raw = sharedKwilClient(kwilClient);\n const previous = turns.get(raw) ?? Promise.resolve();\n const result = previous.then(run, run);\n turns.set(\n raw,\n result.then(\n () => undefined,\n () => undefined,\n ),\n );\n return result;\n}\n\n// `setSigner` is synchronous on the real clients. A rejected promise here is not awaited\n// by `withUserSigner` or the enclave constructor, and Node can terminate on it.\nfunction detachedSurface<T extends object>(): T {\n return new Proxy({} as T, {\n get(_target, prop) {\n if (prop === \"signer\") return undefined;\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n if (prop === \"client\") throw new Error(STALE_CLIENT);\n if (prop === \"setSigner\") {\n return () => {\n throw new Error(STALE_CLIENT);\n };\n }\n return async () => {\n throw new Error(STALE_CLIENT);\n };\n },\n });\n}\n\nfunction staleIdle(store: Store, blobUrl: string): idOSClientIdle {\n return new idOSClientIdle(\n store,\n detachedSurface<KwilActionClient>(),\n detachedSurface<BaseProvider>(),\n idleBlobGateway(blobUrl),\n );\n}\n\n// A replaced signer keeps the session. The signer that actually logged out must finish\n// `reset` on a later attempt; success is only returned once that reset completes.\nfunction finishLogOut(\n store: Store,\n kwilClient: KwilActionClient,\n kwilSigner: KwilSigner,\n enclaveProvider: BaseProvider,\n blobUrl: string,\n): Promise<idOSClientIdle> {\n const raw = sharedKwilClient(kwilClient);\n return exclusive(raw, async () => {\n const current = raw.signer;\n if (current !== undefined && current !== kwilSigner) return staleIdle(store, blobUrl);\n\n if (current === kwilSigner) {\n raw.setSigner(undefined);\n resetPending.add(raw);\n }\n\n if (resetPending.has(raw)) {\n await enclaveProvider.reset();\n resetPending.delete(raw);\n }\n\n // A signer installed while `reset` was in progress must not ride back on this idle client.\n if (raw.signer !== undefined && raw.signer !== kwilSigner) return staleIdle(store, blobUrl);\n\n return new idOSClientIdle(store, raw, enclaveProvider, idleBlobGateway(blobUrl));\n });\n}\n\nexport type idOSClient =\n | idOSClientConfiguration\n | idOSClientIdle\n | idOSClientWithUserSigner\n | idOSClientLoggedIn;\n\nexport class idOSClientConfiguration<Provider extends BaseProvider = IframeEnclave> {\n readonly state: \"configuration\";\n readonly chainId?: string;\n readonly nodeUrl: string;\n readonly blobGatewayUrl?: string;\n readonly enclaveOptions: Omit<Provider[\"options\"], \"mode\">;\n readonly store: Store;\n readonly enclaveProvider: BaseProvider;\n\n constructor(params: {\n chainId?: string;\n nodeUrl: string;\n /**\n * Optional blob gateway base URL. Defaults to `nodeUrl`.\n * In the browser this must share KGW's session-cookie Domain\n * (typically the same host), because reads use `credentials: \"include\"`.\n */\n blobGatewayUrl?: string;\n enclaveOptions: Omit<Provider[\"options\"], \"mode\">;\n enclaveProvider?: new (options: Omit<Provider[\"options\"], \"mode\">) => Provider;\n store?: Store;\n }) {\n this.state = \"configuration\";\n this.chainId = params.chainId;\n this.nodeUrl = params.nodeUrl;\n this.blobGatewayUrl = params.blobGatewayUrl;\n this.enclaveOptions = params.enclaveOptions;\n this.store = params.store ?? (isBrowserRuntime() ? new LocalStorageStore() : new MemoryStore());\n\n // TODO: This is a mess because of types...\n if (params.enclaveProvider) {\n this.enclaveProvider = new params.enclaveProvider({\n ...params.enclaveOptions,\n // Some of enclave providers require store to be passed in constructor\n store: this.store,\n });\n } else {\n // @ts-expect-error - In case of missing \"container\" in options, enclave will blow up\n this.enclaveProvider = new IframeEnclave(params.enclaveOptions);\n }\n }\n\n async createClient(): Promise<idOSClientIdle> {\n return idOSClientIdle.fromConfig(this);\n }\n}\n\nexport class idOSClientIdle {\n readonly state: \"idle\";\n readonly store: Store;\n readonly kwilClient: KwilActionClient;\n readonly enclaveProvider: BaseProvider;\n readonly blobGateway: BlobGateway;\n\n constructor(\n store: Store,\n kwilClient: KwilActionClient,\n enclaveProvider: BaseProvider,\n blobGateway: BlobGateway,\n ) {\n this.state = \"idle\";\n this.store = store;\n this.kwilClient = kwilClient;\n this.enclaveProvider = enclaveProvider;\n this.blobGateway = blobGateway;\n }\n\n static async fromConfig(params: idOSClientConfiguration<BaseProvider>): Promise<idOSClientIdle> {\n const createKwilClient = isBrowserRuntime() ? createWebKwilClient : createNodeKwilClient;\n const kwilClient = await createKwilClient({\n nodeUrl: params.nodeUrl,\n chainId: params.chainId,\n });\n\n await params.enclaveProvider.load();\n\n const blobGatewayUrl = params.blobGatewayUrl ?? params.nodeUrl;\n return new idOSClientIdle(\n params.store,\n kwilClient,\n params.enclaveProvider,\n idleBlobGateway(blobGatewayUrl),\n );\n }\n\n async addressHasProfile(address: string): Promise<boolean> {\n return hasProfile(this.kwilClient, { address }).then((res) => res.has_profile);\n }\n\n async withUserSigner(_signer: Wallet): Promise<idOSClientWithUserSigner> {\n let signer = _signer;\n const [kwilSigner, walletIdentifier, walletPublicKey, walletType] =\n await createClientKwilSigner(this.store, this.kwilClient, signer);\n\n if (walletType === \"NEAR\") {\n const originalSigner = signer;\n signer = {\n signMessage: async (message: string) => {\n const signature = await signNearMessage(\n originalSigner as Parameters<typeof signNearMessage>[0],\n message,\n );\n return { signedMessage: signature } as { signedMessage: string };\n },\n } as unknown as Wallet;\n }\n\n return exclusive(this.kwilClient, async () => {\n this.kwilClient.setSigner(kwilSigner);\n return new idOSClientWithUserSigner(\n this,\n signer,\n kwilSigner,\n walletIdentifier,\n walletPublicKey,\n walletType,\n blobGatewayForSigner(this, kwilSigner),\n );\n });\n }\n\n async logOut(): Promise<idOSClientIdle> {\n return this;\n }\n}\n\nexport class idOSClientWithUserSigner implements Omit<Properties<idOSClientIdle>, \"state\"> {\n readonly state: \"with-user-signer\";\n readonly store: Store;\n readonly #kwilClient: KwilActionClient;\n readonly #enclaveProvider: BaseProvider;\n readonly signer: Wallet;\n readonly kwilSigner: KwilSigner;\n readonly walletIdentifier: string;\n readonly walletPublicKey: string | undefined;\n readonly walletType: WalletType;\n readonly blobGateway: BlobGateway;\n\n constructor(\n idOSClientIdle: idOSClientIdle,\n signer: Wallet,\n kwilSigner: KwilSigner,\n walletIdentifier: string,\n walletPublicKey: string | undefined,\n walletType: WalletType,\n blobGateway: BlobGateway,\n ) {\n this.state = \"with-user-signer\";\n this.store = idOSClientIdle.store;\n this.#kwilClient = idOSClientIdle.kwilClient;\n this.#enclaveProvider = idOSClientIdle.enclaveProvider;\n this.signer = signer;\n this.kwilSigner = kwilSigner;\n this.walletIdentifier = walletIdentifier;\n this.walletPublicKey = walletPublicKey;\n this.walletType = walletType;\n this.blobGateway = blobGateway;\n // @ts-expect-error - TODO: Fix this\n this.#enclaveProvider.setSigner(this.signer);\n }\n\n get kwilClient(): KwilActionClient {\n return boundKwilClient(this.#kwilClient, this.kwilSigner);\n }\n\n get enclaveProvider(): BaseProvider {\n return boundEnclave(this.#enclaveProvider, this.#kwilClient, this.kwilSigner);\n }\n\n async logOut(): Promise<idOSClientIdle> {\n return finishLogOut(\n this.store,\n this.#kwilClient,\n this.kwilSigner,\n this.#enclaveProvider,\n this.blobGateway.url,\n );\n }\n\n async hasProfile(): Promise<boolean> {\n // NEAR profiles are keyed by the ed25519 public key. walletIdentifier is the account id.\n let address = this.walletIdentifier;\n if (this.walletType === \"NEAR\") {\n if (!this.walletPublicKey) throw new Error(\"NEAR wallet public key is required\");\n address = this.walletPublicKey;\n }\n return hasProfile(this.kwilClient, { address }).then((x) => x.has_profile);\n }\n\n async createUserEncryptionProfile(\n userId: string,\n forceEncryptionPasswordStore?: EncryptionPasswordStore,\n ): Promise<PublicEncryptionProfile> {\n await exclusive(this.#kwilClient, async () => {\n assertSigner(this.#kwilClient, this.kwilSigner);\n await this.enclaveProvider.reconfigure({\n mode: \"new\",\n userId,\n walletAddress: this.walletIdentifier,\n walletPublicKey: this.walletPublicKey,\n walletType: this.walletType,\n encryptionPasswordStore: forceEncryptionPasswordStore,\n expectedUserEncryptionPublicKey: undefined,\n });\n assertSigner(this.#kwilClient, this.kwilSigner);\n });\n assertSigner(this.#kwilClient, this.kwilSigner);\n return this.enclaveProvider.ensureUserEncryptionProfile();\n }\n\n async logIn(): Promise<idOSClientLoggedIn> {\n if (!(await this.hasProfile())) throw new Error(\"User does not have a profile\");\n\n const kwilUser = await getUser(this.kwilClient);\n\n return exclusive(this.#kwilClient, async () => {\n assertSigner(this.#kwilClient, this.kwilSigner);\n await this.enclaveProvider.reconfigure({\n mode: \"existing\",\n userId: kwilUser.id,\n expectedUserEncryptionPublicKey: kwilUser.recipient_encryption_public_key,\n walletAddress: this.walletIdentifier,\n walletType: this.walletType,\n encryptionPasswordStore: kwilUser.encryption_password_store,\n walletPublicKey: this.walletPublicKey,\n });\n assertSigner(this.#kwilClient, this.kwilSigner);\n return new idOSClientLoggedIn(this, kwilUser);\n });\n }\n}\n\nexport class idOSClientLoggedIn implements Omit<Properties<idOSClientWithUserSigner>, \"state\"> {\n readonly state: \"logged-in\";\n readonly store: Store;\n readonly #kwilClient: KwilActionClient;\n readonly #enclaveProvider: BaseProvider;\n readonly signer: Wallet;\n readonly kwilSigner: KwilSigner;\n readonly walletIdentifier: string;\n readonly walletPublicKey: string | undefined;\n readonly walletType: WalletType;\n readonly user: idOSUser;\n readonly blobGateway: BlobGateway;\n\n constructor(idOSClientWithUserSigner: idOSClientWithUserSigner, user: idOSUser) {\n this.state = \"logged-in\";\n this.store = idOSClientWithUserSigner.store;\n this.#kwilClient = sharedKwilClient(idOSClientWithUserSigner.kwilClient);\n this.#enclaveProvider = sharedEnclave(idOSClientWithUserSigner.enclaveProvider);\n this.signer = idOSClientWithUserSigner.signer;\n this.kwilSigner = idOSClientWithUserSigner.kwilSigner;\n this.walletIdentifier = idOSClientWithUserSigner.walletIdentifier;\n this.walletPublicKey = idOSClientWithUserSigner.walletPublicKey;\n this.walletType = idOSClientWithUserSigner.walletType;\n this.user = user;\n this.blobGateway = idOSClientWithUserSigner.blobGateway;\n }\n\n get kwilClient(): KwilActionClient {\n return boundKwilClient(this.#kwilClient, this.kwilSigner);\n }\n\n get enclaveProvider(): BaseProvider {\n return boundEnclave(this.#enclaveProvider, this.#kwilClient, this.kwilSigner);\n }\n\n async logOut(): Promise<idOSClientIdle> {\n return finishLogOut(\n this.store,\n this.#kwilClient,\n this.kwilSigner,\n this.#enclaveProvider,\n this.blobGateway.url,\n );\n }\n\n async requestDWGMessage(params: idOSDelegatedWriteGrant): Promise<string> {\n return dwgMessage(this.kwilClient, params).then((res) => res.message);\n }\n\n async createCredential(\n publicNotes: string,\n plaintextContent: Uint8Array<ArrayBufferLike>,\n // In case of credential creation on users behalf, this would be a issuer key\n issuerSigningSecretKey?: Uint8Array,\n ): Promise<Omit<idOSCredential, \"user_id\" | \"content\" | \"inserter_type\" | \"inserter_id\">> {\n const credentialId = crypto.randomUUID();\n const preliminaryCredential: PreliminaryIDOSCredential = {\n ...(await buildPreliminaryIDOSCredential({\n publicNotes,\n plaintextContent,\n recipientEncryptionPublicKey: base64Decode(this.user.recipient_encryption_public_key),\n issuerSigningSecretKey,\n contentUri: contentUriForWallet(this.walletType, this.kwilSigner, credentialId),\n })),\n id: credentialId,\n };\n requireAccessTokenForUkycContent(\n preliminaryCredential.contentUri,\n this.blobGateway.hasAccessToken,\n );\n\n const requestId = crypto.randomUUID();\n\n const payload: CreatePreliminaryCredentialInput = {\n request_id: requestId,\n credential_id: preliminaryCredential.id,\n issuer_auth_public_key: preliminaryCredential.issuerAuthPublicKey,\n encryptor_public_key: preliminaryCredential.encryptorPublicKey,\n content_uri: preliminaryCredential.contentUri,\n content_size: preliminaryCredential.contentSize,\n content_hash: hexEncodeSha256Hash(plaintextContent),\n public_notes: preliminaryCredential.publicNotes,\n public_notes_signature: preliminaryCredential.publicNotesSignature,\n broader_signature: preliminaryCredential.broaderSignature,\n };\n\n await createPreliminaryCredential(this.kwilClient, payload);\n\n await this.blobGateway.uploadCredentialBlobs({\n requestId,\n original: preliminaryCredential.encryptedContent,\n });\n\n return mapPreliminaryToIDOSCredential(preliminaryCredential);\n }\n\n async removeCredential(id: string): Promise<{ id: string }> {\n const credential = await this.getCredentialById(id);\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n\n const contentUri = credential.content_uri ?? null;\n requireAccessTokenForUkycContent(contentUri, this.blobGateway.hasAccessToken);\n\n await removeCredential(this.kwilClient, { id });\n\n if (!contentUri) {\n return { id };\n }\n\n await this.blobGateway.deleteCredentialBlob({ credentialId: id });\n return { id };\n }\n\n async getCredentialById(id: string): Promise<idOSCredential | undefined> {\n return getCredentialOwned(this.kwilClient, { id }).then((res) => res[0]);\n }\n\n async shareCredential(\n credential: SharePreliminaryCredentialInput,\n ): Promise<SharePreliminaryCredentialInput> {\n await sharePreliminaryCredential(this.kwilClient, credential);\n return credential;\n }\n\n async getAllCredentials(): Promise<idOSCredentialListItem[]> {\n return getCredentials(this.kwilClient);\n }\n\n async getAccessGrantsOwned(): Promise<idOSGrant[]> {\n return getAccessGrantsOwned(this.kwilClient);\n }\n\n async getAttributes(): Promise<idOSUserAttribute[]> {\n return getAttributes(this.kwilClient);\n }\n\n async createAttribute(attribute: AddAttributeInput): Promise<AddAttributeInput> {\n await createAttribute(this.kwilClient, attribute);\n return attribute;\n }\n\n async getCredentialContentSha256Hash(id: string): Promise<string> {\n const credential = await this.getCredentialById(id);\n\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n const plaintext = await this.#decryptCredentialContent(credential);\n\n return hexEncodeSha256Hash(plaintext);\n }\n\n async getCredentialContent(id: string): Promise<string> {\n const credential = await this.getCredentialById(id);\n\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n const plaintext = await this.#decryptCredentialContent(credential);\n\n return utf8Decode(plaintext);\n }\n\n async getCredentialWithEncryptedContent(id: string): Promise<idOSCredential> {\n const credential = await this.getCredentialById(id);\n invariant(credential, `\"idOSCredential\" with id ${id} not found`);\n return this.#credentialWithInlineContent(credential);\n }\n\n async getCredentialSharedContent(id: string): Promise<string> {\n const credential = await this.getCredentialShared(id);\n\n invariant(credential, `Shared credential with id ${id} not found`);\n const plaintext = await this.#decryptCredentialContent(credential);\n\n return utf8Decode(plaintext);\n }\n\n async getGrants(\n params: Partial<GetAccessGrantsGrantedInput>,\n ): Promise<{ grants: idOSGrant[]; totalCount: number }> {\n return {\n grants: await getGrants(this.kwilClient, params),\n totalCount: await this.getGrantsCount(),\n };\n }\n\n async addWallets(params: AddWalletInput[]): Promise<AddWalletInput[]> {\n await addWallets(this.kwilClient, params);\n return params;\n }\n\n async getGrantsCount(): Promise<number> {\n return getAccessGrantsGrantedCount(this.kwilClient, {\n user_id: null,\n }).then((res) => res.count);\n }\n\n async getCredentialShared(id: string): Promise<idOSCredential | undefined> {\n return getCredentialShared(this.kwilClient, { id }).then((res) => res[0]);\n }\n\n async revokeAccessGrant(id: string): Promise<{ id: string }> {\n await revokeAccessGrant(this.kwilClient, { id });\n return { id };\n }\n\n async addWalletMessage(params: AddWalletMessageInput): Promise<string> {\n const result = await requestAddWalletMessage(this.kwilClient, params);\n return result.message;\n }\n\n async addWallet(params: AddWalletInput): Promise<AddWalletInput> {\n await addWallet(this.kwilClient, params);\n\n // we don't need to add the wallet to MPC if the user is not using MPC\n if (this.user.encryption_password_store !== \"mpc\") {\n console.log(\"MPC is not enabled or the user is not using MPC\");\n return params;\n }\n\n if (!params.wallet_type) {\n throw new Error(\"Wallet type is required for MPC users\");\n }\n\n const messageToSign = await this.enclaveProvider.addAddressMessageToSign(\n params.address,\n params.public_key ?? undefined,\n params.wallet_type,\n );\n\n const signature = await this.enclaveProvider.signTypedData(\n messageToSign.domain,\n messageToSign.types,\n messageToSign.value,\n );\n\n const result = await this.enclaveProvider.addAddressToMpcSecret(\n this.user.id,\n messageToSign.value,\n signature,\n );\n\n if (result !== \"success\") {\n console.error(`Failed to add wallet to MPC: ${result}`);\n }\n\n return params;\n }\n\n async getWallets(): Promise<GetWalletsOutput[]> {\n return getWallets(this.kwilClient);\n }\n\n async removeWallet(id: string): Promise<{ id: string }> {\n const wallets = await this.getWallets();\n const wallet = wallets.find((wallet) => wallet.id === id);\n if (!wallet) {\n throw new Error(`Wallet with id ${id} not found`);\n }\n\n await removeWallet(this.kwilClient, { id });\n\n // we don't need to add the wallet to MPC if the user is not using MPC\n if (this.user.encryption_password_store !== \"mpc\") {\n console.log(\"MPC is not enabled or the user is not using MPC\");\n return { id };\n }\n\n const messageToSign = await this.enclaveProvider.removeAddressMessageToSign(\n wallet.address,\n wallet.public_key ?? undefined,\n wallet.wallet_type,\n );\n const signature = await this.enclaveProvider.signTypedData(\n messageToSign.domain,\n messageToSign.types,\n messageToSign.value,\n );\n const result = await this.enclaveProvider.removeAddressFromMpcSecret(\n wallet.user_id,\n messageToSign.value,\n signature,\n );\n if (result !== \"success\") {\n console.error(`Failed to add wallet to MPC: ${result}`);\n }\n\n return { id };\n }\n\n async removeWallets(ids: string[]): Promise<string[]> {\n for (const id of ids) {\n await this.removeWallet(id);\n }\n\n return ids;\n }\n\n async filterCredentials(requirements: {\n acceptedIssuers: {\n authPublicKey: string;\n }[];\n publicNotesFieldFilters?: {\n pick: Parameters<typeof recordFilter>[1];\n omit: Parameters<typeof recordFilter>[2];\n };\n privateFieldFilters?: {\n pick: Parameters<typeof recordFilter>[1];\n omit: Parameters<typeof recordFilter>[2];\n };\n /** @deprecated The level leaves out self-attested data. Use `claimsFilter` instead. */\n credentialLevelOrHigherFilter?: {\n userLevel: BaseLevel;\n requiredAddons: Addon[];\n };\n /** Accepted sources per claim, e.g. `{ email: [\"VERIFIED\", \"MANUAL\"] }`. See `matchClaims`. */\n claimsFilter?: ClaimRequirements;\n }): Promise<idOSCredentialListItem[]> {\n const credentials = await this.getAllCredentials();\n const originalCredentials = credentials.filter(\n (cred) => !cred.original_id && !!cred.public_notes,\n );\n\n // invariant(originalCredentials.length, \"No original credentials found\");\n let result = originalCredentials.filter((cred) => {\n return requirements.acceptedIssuers?.some(\n (issuer) => issuer.authPublicKey === cred.issuer_auth_public_key,\n );\n });\n\n const publicNotesFieldFilters = requirements.publicNotesFieldFilters;\n const credentialLevelOrHigherFilter = requirements.credentialLevelOrHigherFilter;\n const privateFieldFilters = requirements.privateFieldFilters;\n const claimsFilter = requirements.claimsFilter;\n\n if (claimsFilter) {\n result = result.filter((credential) => {\n let publicNotes: Parameters<typeof matchClaims>[1];\n\n try {\n publicNotes = JSON.parse(credential.public_notes);\n } catch (_) {\n throw new Error(`Credential ${credential.id} has non-JSON public notes.`);\n }\n\n return matchClaims(claimsFilter, publicNotes);\n });\n }\n\n if (credentialLevelOrHigherFilter) {\n result = result.filter((credential) => {\n let publicNotes: Record<string, string>;\n\n try {\n publicNotes = JSON.parse(credential.public_notes);\n } catch (_) {\n throw new Error(`Credential ${credential.id} has non-JSON public notes.`);\n }\n\n return matchLevelOrHigher(\n credentialLevelOrHigherFilter.userLevel,\n credentialLevelOrHigherFilter.requiredAddons,\n publicNotes.level,\n );\n });\n }\n\n if (\n publicNotesFieldFilters &&\n (Object.keys(publicNotesFieldFilters.pick).length > 0 ||\n Object.keys(publicNotesFieldFilters.omit).length > 0)\n ) {\n result = result.filter((credential) => {\n let publicNotes: Record<string, string>;\n\n try {\n publicNotes = JSON.parse(credential.public_notes);\n } catch (_) {\n throw new Error(`Credential ${credential.id} has non-JSON public notes.`);\n }\n\n return recordFilter(\n publicNotes,\n publicNotesFieldFilters.pick,\n publicNotesFieldFilters.omit,\n );\n });\n }\n\n // Private field filtering requires decryption and the full idOS credential content\n // it's most \"expensive\", since it requires a roundtrip to the nodes and roundtrip to enclave.\n if (\n privateFieldFilters &&\n (Object.keys(privateFieldFilters.pick).length > 0 ||\n Object.keys(privateFieldFilters.omit).length > 0)\n ) {\n const fullCredentials = await Promise.all(\n result.map((credential) => this.getCredentialById(credential.id)),\n );\n\n // Check for undefined, it will be sign of some internal error\n invariant(\n fullCredentials.every((cred) => cred !== undefined),\n \"Some credentials could not be fetched in full form for private field filtering\",\n );\n\n const matches = await this.enclaveProvider.filterCredentials(\n await Promise.all(\n fullCredentials.map((credential) => this.#credentialWithInlineContent(credential)),\n ),\n privateFieldFilters,\n );\n\n result = result.filter((credential) =>\n matches.some((matchedCredential) => matchedCredential.id === credential.id),\n );\n }\n\n return result;\n }\n\n async requestAccessGrant(\n credentialId: string,\n {\n consumerEncryptionPublicKey,\n consumerAuthPublicKey,\n lockedUntil = 0,\n }: {\n consumerEncryptionPublicKey: string;\n consumerAuthPublicKey: string;\n lockedUntil?: number;\n },\n ): Promise<SharePreliminaryCredentialInput> {\n const credential = await this.getCredentialById(credentialId);\n\n invariant(credential, `\"idOSCredential\" with id ${credentialId} not found`);\n\n const plaintextContent = await this.#decryptCredentialContent(credential);\n const contentHash = hexEncodeSha256Hash(plaintextContent);\n\n await this.enclaveProvider.ensureUserEncryptionProfile();\n\n const { content, encryptorPublicKey } = await this.enclaveProvider.encrypt(\n plaintextContent,\n base64Decode(consumerEncryptionPublicKey),\n );\n\n // User issues the shared copy: sign content_uri with an ephemeral user-side key.\n // Copy issuer_auth_public_key need not match the original credential's issuer.\n const copyId = crypto.randomUUID();\n const ukycContentUri = contentUriForWallet(this.walletType, this.kwilSigner, copyId);\n requireAccessTokenForUkycContent(ukycContentUri, this.blobGateway.hasAccessToken);\n const copyReference = ukycContentUri\n ? { uri: ukycContentUri, size: content.byteLength }\n : await createBlobContentReference(content);\n const signedReference = buildEphemeralSignedCredentialContentReference(\"\", copyReference.uri);\n\n // Integrator-supplied. ed25519 @caller is lowercase hex; after exact grantee\n // matching, uppercase hex would store a grant the consumer cannot read. Other\n // identifier encodings (NEAR, XRPL, Stellar, MM) are case-sensitive, so leave them.\n const granteeWalletIdentifier = /^[0-9a-fA-F]{64}$/.test(consumerAuthPublicKey)\n ? consumerAuthPublicKey.toLowerCase()\n : consumerAuthPublicKey;\n\n const preliminaryCredential: SharePreliminaryCredentialInput = {\n ...signedReference,\n request_id: crypto.randomUUID(),\n copy_id: copyId,\n original_id: credential.id,\n content_uri: copyReference.uri,\n content_size: copyReference.size,\n encryptor_public_key: base64Encode(encryptorPublicKey),\n grantee_wallet_identifier: granteeWalletIdentifier,\n locked_until: lockedUntil,\n content_hash: contentHash,\n };\n\n await this.shareCredential(preliminaryCredential);\n await this.blobGateway.uploadCredentialBlobs({\n requestId: preliminaryCredential.request_id,\n copy: content,\n });\n\n return preliminaryCredential;\n }\n\n async #credentialWithInlineContent(credential: idOSCredential): Promise<idOSCredential> {\n if (credential.content) {\n return credential;\n }\n\n return {\n ...credential,\n content: base64Encode(await this.#getCredentialEncryptedContent(credential)),\n content_uri: null,\n content_size: null,\n };\n }\n\n async #decryptCredentialContent(credential: idOSCredential): Promise<Uint8Array> {\n await this.enclaveProvider.ensureUserEncryptionProfile();\n\n return this.enclaveProvider.decrypt(\n await this.#getCredentialEncryptedContent(credential),\n base64Decode(credential.encryptor_public_key),\n );\n }\n\n async #getCredentialEncryptedContent(credential: idOSCredential): Promise<Uint8Array> {\n return resolveCredentialEncryptedContent(credential, this.blobGateway);\n }\n}\n\nexport type {\n Claim,\n ClaimRequirements,\n Claims,\n ClaimSource,\n ClaimSources,\n idOSDelegatedWriteGrant,\n DelegatedWriteGrantBaseParams,\n idOSCredential,\n idOSCredentialListItem,\n idOSGrant,\n idOSUser,\n idOSUserAttribute,\n idOSWallet,\n};\n\nexport { signNearMessage, toDelegatedWriteGrantBaseParams };\n\nexport function createIDOSClient(params: {\n nodeUrl: string;\n /**\n * Optional blob gateway base URL. Defaults to `nodeUrl`.\n * In the browser this must share KGW's session-cookie Domain\n * (typically the same host), because reads use `credentials: \"include\"`.\n */\n blobGatewayUrl?: string;\n enclaveOptions: Omit<IframeEnclave[\"options\"], \"mode\">;\n}): idOSClientConfiguration<IframeEnclave> {\n return new idOSClientConfiguration({\n nodeUrl: params.nodeUrl,\n blobGatewayUrl: params.blobGatewayUrl,\n enclaveOptions: params.enclaveOptions,\n });\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idos-network/client",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "idOS Client JavaScript SDK for browser environments",
5
5
  "homepage": "https://idos.network",
6
6
  "license": "MIT",
@@ -28,11 +28,11 @@
28
28
  "access": "public"
29
29
  },
30
30
  "dependencies": {
31
- "@idos-network/credentials": "3.0.0",
32
- "@idos-network/enclave": "3.0.0",
33
- "@idos-network/kwil-infra": "3.0.0",
31
+ "@idos-network/credentials": "3.1.0",
32
+ "@idos-network/enclave": "3.0.1",
33
+ "@idos-network/kwil-infra": "3.0.1",
34
34
  "@idos-network/kwil-js": "0.2.2",
35
- "@idos-network/utils": "3.0.0",
35
+ "@idos-network/utils": "3.0.1",
36
36
  "tiny-invariant": "^1.3.3"
37
37
  },
38
38
  "devDependencies": {
package/src/index.test.ts CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  idOSClientConfiguration,
14
14
  idOSClientIdle,
15
15
  idOSClientLoggedIn,
16
- type idOSClientWithUserSigner,
16
+ idOSClientWithUserSigner,
17
17
  toDelegatedWriteGrantBaseParams,
18
18
  } from "./index.js";
19
19
 
@@ -303,6 +303,70 @@ describe("signer switching on a shared idle client", () => {
303
303
  });
304
304
  });
305
305
 
306
+ describe("hasProfile", () => {
307
+ const nearPublicKey = "ed25519:9esz1ouR3vwBwjnUjjcFB8ETfQb6cnBPtXt8v6QPM2Nf";
308
+
309
+ function clientFor(wallet: {
310
+ walletIdentifier: string;
311
+ walletPublicKey: string | undefined;
312
+ walletType: "NEAR" | "EVM";
313
+ }) {
314
+ const idle = idleClient();
315
+ const kwilSigner = {} as never;
316
+ idle.kwilClient.setSigner(kwilSigner);
317
+ return {
318
+ client: new idOSClientWithUserSigner(
319
+ idle,
320
+ {} as never,
321
+ kwilSigner,
322
+ wallet.walletIdentifier,
323
+ wallet.walletPublicKey,
324
+ wallet.walletType,
325
+ idle.blobGateway,
326
+ ),
327
+ call: idle.kwilClient.call,
328
+ };
329
+ }
330
+
331
+ it("looks up a NEAR profile by public key and an EVM profile by wallet identifier", async () => {
332
+ const near = clientFor({
333
+ walletIdentifier: "alice.near",
334
+ walletPublicKey: nearPublicKey,
335
+ walletType: "NEAR",
336
+ });
337
+
338
+ await expect(near.client.hasProfile()).resolves.toBe(true);
339
+ expect(near.call).toHaveBeenCalledWith(
340
+ { name: "has_profile", inputs: { address: nearPublicKey } },
341
+ undefined,
342
+ );
343
+
344
+ const evmIdentifier = "0x1234567890123456789012345678901234567890";
345
+ const evm = clientFor({
346
+ walletIdentifier: evmIdentifier,
347
+ walletPublicKey: undefined,
348
+ walletType: "EVM",
349
+ });
350
+
351
+ await expect(evm.client.hasProfile()).resolves.toBe(true);
352
+ expect(evm.call).toHaveBeenCalledWith(
353
+ { name: "has_profile", inputs: { address: evmIdentifier } },
354
+ undefined,
355
+ );
356
+ });
357
+
358
+ it("throws when a NEAR signer has no public key", async () => {
359
+ const near = clientFor({
360
+ walletIdentifier: "alice.near",
361
+ walletPublicKey: undefined,
362
+ walletType: "NEAR",
363
+ });
364
+
365
+ await expect(near.client.hasProfile()).rejects.toThrow("NEAR wallet public key is required");
366
+ expect(near.call).not.toHaveBeenCalled();
367
+ });
368
+ });
369
+
306
370
  describe("Node client defaults", () => {
307
371
  it("defaults to MemoryStore outside the browser", () => {
308
372
  class FakeEnclave {
package/src/index.ts CHANGED
@@ -8,11 +8,17 @@ import {
8
8
  buildEphemeralSignedCredentialContentReference,
9
9
  buildPreliminaryIDOSCredential,
10
10
  mapPreliminaryToIDOSCredential,
11
+ matchClaims,
11
12
  matchLevelOrHigher,
12
13
  type PreliminaryIDOSCredential,
13
14
  recordFilter,
14
15
  type BaseLevel,
15
16
  type Addon,
17
+ type Claim,
18
+ type ClaimRequirements,
19
+ type Claims,
20
+ type ClaimSource,
21
+ type ClaimSources,
16
22
  } from "@idos-network/credentials/utils";
17
23
  import {
18
24
  createClientKwilSigner,
@@ -494,9 +500,13 @@ export class idOSClientWithUserSigner implements Omit<Properties<idOSClientIdle>
494
500
  }
495
501
 
496
502
  async hasProfile(): Promise<boolean> {
497
- return hasProfile(this.kwilClient, { address: this.walletIdentifier }).then(
498
- (x) => x.has_profile,
499
- );
503
+ // NEAR profiles are keyed by the ed25519 public key. walletIdentifier is the account id.
504
+ let address = this.walletIdentifier;
505
+ if (this.walletType === "NEAR") {
506
+ if (!this.walletPublicKey) throw new Error("NEAR wallet public key is required");
507
+ address = this.walletPublicKey;
508
+ }
509
+ return hasProfile(this.kwilClient, { address }).then((x) => x.has_profile);
500
510
  }
501
511
 
502
512
  async createUserEncryptionProfile(
@@ -849,10 +859,13 @@ export class idOSClientLoggedIn implements Omit<Properties<idOSClientWithUserSig
849
859
  pick: Parameters<typeof recordFilter>[1];
850
860
  omit: Parameters<typeof recordFilter>[2];
851
861
  };
862
+ /** @deprecated The level leaves out self-attested data. Use `claimsFilter` instead. */
852
863
  credentialLevelOrHigherFilter?: {
853
864
  userLevel: BaseLevel;
854
865
  requiredAddons: Addon[];
855
866
  };
867
+ /** Accepted sources per claim, e.g. `{ email: ["VERIFIED", "MANUAL"] }`. See `matchClaims`. */
868
+ claimsFilter?: ClaimRequirements;
856
869
  }): Promise<idOSCredentialListItem[]> {
857
870
  const credentials = await this.getAllCredentials();
858
871
  const originalCredentials = credentials.filter(
@@ -869,6 +882,21 @@ export class idOSClientLoggedIn implements Omit<Properties<idOSClientWithUserSig
869
882
  const publicNotesFieldFilters = requirements.publicNotesFieldFilters;
870
883
  const credentialLevelOrHigherFilter = requirements.credentialLevelOrHigherFilter;
871
884
  const privateFieldFilters = requirements.privateFieldFilters;
885
+ const claimsFilter = requirements.claimsFilter;
886
+
887
+ if (claimsFilter) {
888
+ result = result.filter((credential) => {
889
+ let publicNotes: Parameters<typeof matchClaims>[1];
890
+
891
+ try {
892
+ publicNotes = JSON.parse(credential.public_notes);
893
+ } catch (_) {
894
+ throw new Error(`Credential ${credential.id} has non-JSON public notes.`);
895
+ }
896
+
897
+ return matchClaims(claimsFilter, publicNotes);
898
+ });
899
+ }
872
900
 
873
901
  if (credentialLevelOrHigherFilter) {
874
902
  result = result.filter((credential) => {
@@ -1035,6 +1063,11 @@ export class idOSClientLoggedIn implements Omit<Properties<idOSClientWithUserSig
1035
1063
  }
1036
1064
 
1037
1065
  export type {
1066
+ Claim,
1067
+ ClaimRequirements,
1068
+ Claims,
1069
+ ClaimSource,
1070
+ ClaimSources,
1038
1071
  idOSDelegatedWriteGrant,
1039
1072
  DelegatedWriteGrantBaseParams,
1040
1073
  idOSCredential,