@mysten/enoki
Advanced tools
Comparing version 0.0.0-experimental-20231121174042 to 0.0.0-experimental-20231122055801
# @mysten/enoki | ||
## 0.0.0-experimental-20231121174042 | ||
## 0.0.0-experimental-20231122055801 | ||
### Patch Changes | ||
- dfa523c77: Key storage off of the API key, and add APIs for transaction block sponsorship | ||
## 0.0.2 | ||
### Patch Changes | ||
- 180616bef: Rewrite the encryption layer | ||
@@ -13,3 +19,3 @@ - 9ac7e2f3d: Introduce Enoki SDK | ||
- Updated dependencies [64d45ba27] | ||
- @mysten/sui.js@0.0.0-experimental-20231121174042 | ||
- @mysten/zklogin@0.0.0-experimental-20231121174042 | ||
- @mysten/sui.js@0.47.0 | ||
- @mysten/zklogin@0.3.7 |
@@ -1,2 +0,2 @@ | ||
import type { CreateZkLoginNonceApiInput, CreateZkLoginNonceApiResponse, CreateZkLoginZkpApiInput, CreateZkLoginZkpApiResponse, GetAppApiInput, GetAppApiResponse, GetZkLoginApiInput, GetZkLoginApiResponse } from './type.js'; | ||
import type { CreateSponsoredTransactionBlockApiInput, CreateSponsoredTransactionBlockApiResponse, CreateZkLoginNonceApiInput, CreateZkLoginNonceApiResponse, CreateZkLoginZkpApiInput, CreateZkLoginZkpApiResponse, GetAppApiInput, GetAppApiResponse, GetZkLoginApiInput, GetZkLoginApiResponse } from './type.js'; | ||
export interface EnokiClientConfig { | ||
@@ -18,2 +18,3 @@ /** The API key for the Enoki app, available in the Enoki Portal. */ | ||
createZkLoginZkp(input: CreateZkLoginZkpApiInput): Promise<CreateZkLoginZkpApiResponse>; | ||
createSponsoredTransactionBlock(input: CreateSponsoredTransactionBlockApiInput): Promise<CreateSponsoredTransactionBlockApiResponse>; | ||
} |
@@ -81,3 +81,3 @@ "use strict"; | ||
createZkLoginZkp(input) { | ||
return __privateMethod(this, _fetch, fetch_fn).call(this, "zklogin/kzp", { | ||
return __privateMethod(this, _fetch, fetch_fn).call(this, "zklogin/zkp", { | ||
method: "POST", | ||
@@ -94,2 +94,14 @@ headers: { | ||
} | ||
createSponsoredTransactionBlock(input) { | ||
return __privateMethod(this, _fetch, fetch_fn).call(this, "transaction-blocks/sponsor", { | ||
method: "POST", | ||
headers: { | ||
[ZKLOGIN_HEADER]: input.jwt | ||
}, | ||
body: JSON.stringify({ | ||
network: input.network, | ||
transactionBlockKindBytes: input.transactionBlockKindBytes | ||
}) | ||
}); | ||
} | ||
} | ||
@@ -96,0 +108,0 @@ _version = new WeakMap(); |
@@ -37,1 +37,13 @@ import type { PublicKey } from '@mysten/sui.js/cryptography'; | ||
} | ||
export interface CreateSponsoredTransactionBlockApiInput { | ||
network?: 'mainnet' | 'testnet'; | ||
jwt: string; | ||
transactionBlockKindBytes: string; | ||
} | ||
export interface CreateSponsoredTransactionBlockApiResponse { | ||
bytes: string; | ||
signature: string; | ||
digest: string; | ||
expireAtTime: number; | ||
expireAfterEpoch: number; | ||
} |
@@ -0,1 +1,3 @@ | ||
import type { ExecuteTransactionBlockParams, SuiClient } from '@mysten/sui.js/client'; | ||
import type { TransactionBlock } from '@mysten/sui.js/transactions'; | ||
import type { ZkLoginSignatureInputs } from '@mysten/sui.js/zklogin'; | ||
@@ -50,2 +52,7 @@ import type { WritableAtom } from 'nanostores'; | ||
getKeypair(): Promise<EnokiKeypair>; | ||
sponsorAndExecuteTransactionBlock({ network, transactionBlock, client, ...options }: { | ||
network?: 'mainnet' | 'testnet'; | ||
transactionBlock: TransactionBlock; | ||
client: SuiClient; | ||
} & Omit<ExecuteTransactionBlockParams, 'signature' | 'transactionBlock'>): Promise<import("@mysten/sui.js/client").SuiTransactionBlockResponse>; | ||
} |
@@ -54,10 +54,11 @@ "use strict"; | ||
var import_stores = require("./stores.js"); | ||
var _enokiClient, _encryption, _encryptionKey, _store, _zkLoginSessionInitialized, _zkLoginSession, _setSession, setSession_fn; | ||
const STORAGE_KEYS = { | ||
STATE: "@enoki/flow/state", | ||
SESSION: "@enoki/flow/session" | ||
}; | ||
var _storageKeys, _enokiClient, _encryption, _encryptionKey, _store, _zkLoginSessionInitialized, _zkLoginSession, _setSession, setSession_fn; | ||
const createStorageKeys = (apiKey) => ({ | ||
STATE: `@enoki/flow/state/${apiKey}`, | ||
SESSION: `@enoki/flow/session/${apiKey}` | ||
}); | ||
class EnokiFlow { | ||
constructor(config) { | ||
__privateAdd(this, _setSession); | ||
__privateAdd(this, _storageKeys, void 0); | ||
__privateAdd(this, _enokiClient, void 0); | ||
@@ -76,5 +77,6 @@ __privateAdd(this, _encryption, void 0); | ||
__privateSet(this, _store, config.store ?? (0, import_stores.createSessionStorage)()); | ||
__privateSet(this, _storageKeys, createStorageKeys(config.apiKey)); | ||
let storedState = null; | ||
try { | ||
const rawStoredValue = __privateGet(this, _store).get(STORAGE_KEYS.STATE); | ||
const rawStoredValue = __privateGet(this, _store).get(__privateGet(this, _storageKeys).STATE); | ||
if (rawStoredValue) { | ||
@@ -89,3 +91,3 @@ storedState = JSON.parse(rawStoredValue); | ||
(0, import_nanostores.onSet)(this.$zkLoginState, ({ newValue }) => { | ||
__privateGet(this, _store).set(STORAGE_KEYS.STATE, JSON.stringify(newValue)); | ||
__privateGet(this, _store).set(__privateGet(this, _storageKeys).STATE, JSON.stringify(newValue)); | ||
}); | ||
@@ -175,3 +177,3 @@ } | ||
try { | ||
const storedValue = __privateGet(this, _store).get(STORAGE_KEYS.SESSION); | ||
const storedValue = __privateGet(this, _store).get(__privateGet(this, _storageKeys).SESSION); | ||
if (!storedValue) | ||
@@ -194,3 +196,3 @@ return null; | ||
this.$zkLoginState.set({}); | ||
__privateGet(this, _store).delete(STORAGE_KEYS.STATE); | ||
__privateGet(this, _store).delete(__privateGet(this, _storageKeys).STATE); | ||
await __privateMethod(this, _setSession, setSession_fn).call(this, null); | ||
@@ -225,4 +227,4 @@ } | ||
async getKeypair() { | ||
await this.getProof(); | ||
const zkp = await this.getSession(); | ||
await this.getProof(); | ||
const { address } = this.$zkLoginState.get(); | ||
@@ -242,3 +244,35 @@ if (!address || !zkp || !zkp.proof) { | ||
} | ||
async sponsorAndExecuteTransactionBlock({ | ||
network, | ||
transactionBlock, | ||
client, | ||
...options | ||
}) { | ||
const session = await this.getSession(); | ||
const keypair = await this.getKeypair(); | ||
const transactionBlockKindBytes = await transactionBlock.build({ | ||
onlyTransactionKind: true, | ||
client, | ||
// Theses limits will get verified during the final transaction construction, so we can safely ignore them here: | ||
limits: { | ||
maxGasObjects: Infinity, | ||
maxPureArgumentSize: Infinity, | ||
maxTxGas: Infinity, | ||
maxTxSizeBytes: Infinity | ||
} | ||
}); | ||
const { bytes, signature: sponsorSignature } = await __privateGet(this, _enokiClient).createSponsoredTransactionBlock({ | ||
jwt: session.jwt, | ||
network, | ||
transactionBlockKindBytes: (0, import_utils.toB64)(transactionBlockKindBytes) | ||
}); | ||
const userSignature = await keypair.signTransactionBlock((0, import_utils.fromB64)(bytes)); | ||
return client.executeTransactionBlock({ | ||
transactionBlock: bytes, | ||
signature: [userSignature.signature, sponsorSignature], | ||
...options | ||
}); | ||
} | ||
} | ||
_storageKeys = new WeakMap(); | ||
_enokiClient = new WeakMap(); | ||
@@ -257,5 +291,5 @@ _encryption = new WeakMap(); | ||
); | ||
__privateGet(this, _store).set(STORAGE_KEYS.SESSION, storedValue); | ||
__privateGet(this, _store).set(__privateGet(this, _storageKeys).SESSION, storedValue); | ||
} else { | ||
__privateGet(this, _store).delete(STORAGE_KEYS.SESSION); | ||
__privateGet(this, _store).delete(__privateGet(this, _storageKeys).SESSION); | ||
} | ||
@@ -262,0 +296,0 @@ __privateSet(this, _zkLoginSession, newValue); |
@@ -10,1 +10,2 @@ import type { ReactNode } from 'react'; | ||
export declare function useZkLogin(): import("./EnokiFlow.js").ZkLoginState; | ||
export declare function useAuthCallback(): boolean; |
@@ -22,2 +22,3 @@ "use strict"; | ||
EnokiFlowProvider: () => EnokiFlowProvider, | ||
useAuthCallback: () => useAuthCallback, | ||
useEnokiFlow: () => useEnokiFlow, | ||
@@ -47,2 +48,26 @@ useZkLogin: () => useZkLogin | ||
} | ||
function useAuthCallback() { | ||
const flow = useEnokiFlow(); | ||
const [handled, setHandled] = (0, import_react2.useState)(false); | ||
const [hash, setHash] = (0, import_react2.useState)(null); | ||
(0, import_react2.useEffect)(() => { | ||
const listener = () => setHash(window.location.hash.slice(1).trim()); | ||
listener(); | ||
window.addEventListener("hashchange", listener); | ||
return () => window.removeEventListener("hashchange", listener); | ||
}, []); | ||
(0, import_react2.useEffect)(() => { | ||
if (!hash) | ||
return; | ||
(async () => { | ||
try { | ||
await flow.handleAuthCallback(hash); | ||
window.location.hash = ""; | ||
} finally { | ||
setHandled(true); | ||
} | ||
})(); | ||
}, [hash, flow]); | ||
return handled; | ||
} | ||
//# sourceMappingURL=react.js.map |
@@ -1,2 +0,2 @@ | ||
import type { CreateZkLoginNonceApiInput, CreateZkLoginNonceApiResponse, CreateZkLoginZkpApiInput, CreateZkLoginZkpApiResponse, GetAppApiInput, GetAppApiResponse, GetZkLoginApiInput, GetZkLoginApiResponse } from './type.js'; | ||
import type { CreateSponsoredTransactionBlockApiInput, CreateSponsoredTransactionBlockApiResponse, CreateZkLoginNonceApiInput, CreateZkLoginNonceApiResponse, CreateZkLoginZkpApiInput, CreateZkLoginZkpApiResponse, GetAppApiInput, GetAppApiResponse, GetZkLoginApiInput, GetZkLoginApiResponse } from './type.js'; | ||
export interface EnokiClientConfig { | ||
@@ -18,2 +18,3 @@ /** The API key for the Enoki app, available in the Enoki Portal. */ | ||
createZkLoginZkp(input: CreateZkLoginZkpApiInput): Promise<CreateZkLoginZkpApiResponse>; | ||
createSponsoredTransactionBlock(input: CreateSponsoredTransactionBlockApiInput): Promise<CreateSponsoredTransactionBlockApiResponse>; | ||
} |
@@ -58,3 +58,3 @@ var __accessCheck = (obj, member, msg) => { | ||
createZkLoginZkp(input) { | ||
return __privateMethod(this, _fetch, fetch_fn).call(this, "zklogin/kzp", { | ||
return __privateMethod(this, _fetch, fetch_fn).call(this, "zklogin/zkp", { | ||
method: "POST", | ||
@@ -71,2 +71,14 @@ headers: { | ||
} | ||
createSponsoredTransactionBlock(input) { | ||
return __privateMethod(this, _fetch, fetch_fn).call(this, "transaction-blocks/sponsor", { | ||
method: "POST", | ||
headers: { | ||
[ZKLOGIN_HEADER]: input.jwt | ||
}, | ||
body: JSON.stringify({ | ||
network: input.network, | ||
transactionBlockKindBytes: input.transactionBlockKindBytes | ||
}) | ||
}); | ||
} | ||
} | ||
@@ -73,0 +85,0 @@ _version = new WeakMap(); |
@@ -37,1 +37,13 @@ import type { PublicKey } from '@mysten/sui.js/cryptography'; | ||
} | ||
export interface CreateSponsoredTransactionBlockApiInput { | ||
network?: 'mainnet' | 'testnet'; | ||
jwt: string; | ||
transactionBlockKindBytes: string; | ||
} | ||
export interface CreateSponsoredTransactionBlockApiResponse { | ||
bytes: string; | ||
signature: string; | ||
digest: string; | ||
expireAtTime: number; | ||
expireAfterEpoch: number; | ||
} |
@@ -0,1 +1,3 @@ | ||
import type { ExecuteTransactionBlockParams, SuiClient } from '@mysten/sui.js/client'; | ||
import type { TransactionBlock } from '@mysten/sui.js/transactions'; | ||
import type { ZkLoginSignatureInputs } from '@mysten/sui.js/zklogin'; | ||
@@ -50,2 +52,7 @@ import type { WritableAtom } from 'nanostores'; | ||
getKeypair(): Promise<EnokiKeypair>; | ||
sponsorAndExecuteTransactionBlock({ network, transactionBlock, client, ...options }: { | ||
network?: 'mainnet' | 'testnet'; | ||
transactionBlock: TransactionBlock; | ||
client: SuiClient; | ||
} & Omit<ExecuteTransactionBlockParams, 'signature' | 'transactionBlock'>): Promise<import("@mysten/sui.js/client").SuiTransactionBlockResponse>; | ||
} |
@@ -23,5 +23,5 @@ var __accessCheck = (obj, member, msg) => { | ||
}; | ||
var _enokiClient, _encryption, _encryptionKey, _store, _zkLoginSessionInitialized, _zkLoginSession, _setSession, setSession_fn; | ||
var _storageKeys, _enokiClient, _encryption, _encryptionKey, _store, _zkLoginSessionInitialized, _zkLoginSession, _setSession, setSession_fn; | ||
import { Ed25519Keypair } from "@mysten/sui.js/keypairs/ed25519"; | ||
import { fromB64 } from "@mysten/sui.js/utils"; | ||
import { fromB64, toB64 } from "@mysten/sui.js/utils"; | ||
import { decodeJwt } from "jose"; | ||
@@ -33,9 +33,10 @@ import { atom, onSet } from "nanostores"; | ||
import { createSessionStorage } from "./stores.js"; | ||
const STORAGE_KEYS = { | ||
STATE: "@enoki/flow/state", | ||
SESSION: "@enoki/flow/session" | ||
}; | ||
const createStorageKeys = (apiKey) => ({ | ||
STATE: `@enoki/flow/state/${apiKey}`, | ||
SESSION: `@enoki/flow/session/${apiKey}` | ||
}); | ||
class EnokiFlow { | ||
constructor(config) { | ||
__privateAdd(this, _setSession); | ||
__privateAdd(this, _storageKeys, void 0); | ||
__privateAdd(this, _enokiClient, void 0); | ||
@@ -54,5 +55,6 @@ __privateAdd(this, _encryption, void 0); | ||
__privateSet(this, _store, config.store ?? createSessionStorage()); | ||
__privateSet(this, _storageKeys, createStorageKeys(config.apiKey)); | ||
let storedState = null; | ||
try { | ||
const rawStoredValue = __privateGet(this, _store).get(STORAGE_KEYS.STATE); | ||
const rawStoredValue = __privateGet(this, _store).get(__privateGet(this, _storageKeys).STATE); | ||
if (rawStoredValue) { | ||
@@ -67,3 +69,3 @@ storedState = JSON.parse(rawStoredValue); | ||
onSet(this.$zkLoginState, ({ newValue }) => { | ||
__privateGet(this, _store).set(STORAGE_KEYS.STATE, JSON.stringify(newValue)); | ||
__privateGet(this, _store).set(__privateGet(this, _storageKeys).STATE, JSON.stringify(newValue)); | ||
}); | ||
@@ -153,3 +155,3 @@ } | ||
try { | ||
const storedValue = __privateGet(this, _store).get(STORAGE_KEYS.SESSION); | ||
const storedValue = __privateGet(this, _store).get(__privateGet(this, _storageKeys).SESSION); | ||
if (!storedValue) | ||
@@ -172,3 +174,3 @@ return null; | ||
this.$zkLoginState.set({}); | ||
__privateGet(this, _store).delete(STORAGE_KEYS.STATE); | ||
__privateGet(this, _store).delete(__privateGet(this, _storageKeys).STATE); | ||
await __privateMethod(this, _setSession, setSession_fn).call(this, null); | ||
@@ -203,4 +205,4 @@ } | ||
async getKeypair() { | ||
await this.getProof(); | ||
const zkp = await this.getSession(); | ||
await this.getProof(); | ||
const { address } = this.$zkLoginState.get(); | ||
@@ -220,3 +222,35 @@ if (!address || !zkp || !zkp.proof) { | ||
} | ||
async sponsorAndExecuteTransactionBlock({ | ||
network, | ||
transactionBlock, | ||
client, | ||
...options | ||
}) { | ||
const session = await this.getSession(); | ||
const keypair = await this.getKeypair(); | ||
const transactionBlockKindBytes = await transactionBlock.build({ | ||
onlyTransactionKind: true, | ||
client, | ||
// Theses limits will get verified during the final transaction construction, so we can safely ignore them here: | ||
limits: { | ||
maxGasObjects: Infinity, | ||
maxPureArgumentSize: Infinity, | ||
maxTxGas: Infinity, | ||
maxTxSizeBytes: Infinity | ||
} | ||
}); | ||
const { bytes, signature: sponsorSignature } = await __privateGet(this, _enokiClient).createSponsoredTransactionBlock({ | ||
jwt: session.jwt, | ||
network, | ||
transactionBlockKindBytes: toB64(transactionBlockKindBytes) | ||
}); | ||
const userSignature = await keypair.signTransactionBlock(fromB64(bytes)); | ||
return client.executeTransactionBlock({ | ||
transactionBlock: bytes, | ||
signature: [userSignature.signature, sponsorSignature], | ||
...options | ||
}); | ||
} | ||
} | ||
_storageKeys = new WeakMap(); | ||
_enokiClient = new WeakMap(); | ||
@@ -235,5 +269,5 @@ _encryption = new WeakMap(); | ||
); | ||
__privateGet(this, _store).set(STORAGE_KEYS.SESSION, storedValue); | ||
__privateGet(this, _store).set(__privateGet(this, _storageKeys).SESSION, storedValue); | ||
} else { | ||
__privateGet(this, _store).delete(STORAGE_KEYS.SESSION); | ||
__privateGet(this, _store).delete(__privateGet(this, _storageKeys).SESSION); | ||
} | ||
@@ -240,0 +274,0 @@ __privateSet(this, _zkLoginSession, newValue); |
@@ -10,1 +10,2 @@ import type { ReactNode } from 'react'; | ||
export declare function useZkLogin(): import("./EnokiFlow.js").ZkLoginState; | ||
export declare function useAuthCallback(): boolean; |
import { jsx } from "react/jsx-runtime"; | ||
import { useStore } from "@nanostores/react"; | ||
import { createContext, useContext, useState } from "react"; | ||
import { createContext, useContext, useEffect, useState } from "react"; | ||
import { EnokiFlow } from "./EnokiFlow.js"; | ||
@@ -21,4 +21,29 @@ const EnokiFlowContext = createContext(null); | ||
} | ||
function useAuthCallback() { | ||
const flow = useEnokiFlow(); | ||
const [handled, setHandled] = useState(false); | ||
const [hash, setHash] = useState(null); | ||
useEffect(() => { | ||
const listener = () => setHash(window.location.hash.slice(1).trim()); | ||
listener(); | ||
window.addEventListener("hashchange", listener); | ||
return () => window.removeEventListener("hashchange", listener); | ||
}, []); | ||
useEffect(() => { | ||
if (!hash) | ||
return; | ||
(async () => { | ||
try { | ||
await flow.handleAuthCallback(hash); | ||
window.location.hash = ""; | ||
} finally { | ||
setHandled(true); | ||
} | ||
})(); | ||
}, [hash, flow]); | ||
return handled; | ||
} | ||
export { | ||
EnokiFlowProvider, | ||
useAuthCallback, | ||
useEnokiFlow, | ||
@@ -25,0 +50,0 @@ useZkLogin |
{ | ||
"name": "@mysten/enoki", | ||
"version": "0.0.0-experimental-20231121174042", | ||
"version": "0.0.0-experimental-20231122055801", | ||
"description": "TODO: Description", | ||
@@ -24,4 +24,3 @@ "license": "Apache-2.0", | ||
"dist", | ||
"react", | ||
"src" | ||
"react" | ||
], | ||
@@ -39,5 +38,9 @@ "repository": { | ||
"@types/react": "^18.2.15", | ||
"@types/react-dom": "^18.2.7", | ||
"@vitejs/plugin-react-swc": "^3.3.2", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"tsx": "^3.12.7", | ||
"typescript": "^5.1.6", | ||
"vite": "^4.4.4", | ||
"@mysten/build-scripts": "0.0.0" | ||
@@ -49,4 +52,4 @@ }, | ||
"nanostores": "^0.9.3", | ||
"@mysten/sui.js": "0.0.0-experimental-20231121174042", | ||
"@mysten/zklogin": "0.0.0-experimental-20231121174042" | ||
"@mysten/sui.js": "0.47.0", | ||
"@mysten/zklogin": "0.3.7" | ||
}, | ||
@@ -68,2 +71,3 @@ "peerDependencies": { | ||
"build": "build-package", | ||
"demo": "vite ./demo", | ||
"prettier:check": "prettier -c --ignore-unknown .", | ||
@@ -70,0 +74,0 @@ "prettier:fix": "prettier -w --ignore-unknown .", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
247297
10
57
1906
+ Added@mysten/sui.js@0.47.0(transitive)
+ Added@mysten/zklogin@0.3.7(transitive)
- Removed@mysten/sui.js@0.0.0-experimental-20231121174042(transitive)
- Removed@mysten/zklogin@0.0.0-experimental-20231121174042(transitive)
Updated@mysten/sui.js@0.47.0
Updated@mysten/zklogin@0.3.7