@mysten/sui.js
Advanced tools
Comparing version 0.0.0-experimental-20240425163027 to 0.0.0-experimental-20240508033635
# @mysten/sui.js | ||
## 0.0.0-experimental-20240425163027 | ||
## 0.0.0-experimental-20240508033635 | ||
### Minor Changes | ||
- 774bfb41a8: Add MultiSigSigner class to simplify multisig signing | ||
## 0.52.0 | ||
### Minor Changes | ||
- 929db4976a: Add normalizeSuiNSName and isValidSuiNSName utils, and add a format option to SuiClient.resolveNameServiceNames | ||
@@ -8,0 +14,0 @@ |
@@ -28,10 +28,2 @@ import type { MultiSigStruct } from '../multisig/publickey.js'; | ||
serializedSignature: string; | ||
signatureScheme: "MultiSig"; | ||
multisig: MultiSigStruct; | ||
bytes: Uint8Array; | ||
zkLogin?: undefined; | ||
signature?: undefined; | ||
publicKey?: undefined; | ||
} | { | ||
serializedSignature: string; | ||
signatureScheme: "ZkLogin"; | ||
@@ -59,4 +51,9 @@ zkLogin: { | ||
signature: Uint8Array; | ||
multisig?: undefined; | ||
bytes?: undefined; | ||
publicKey: Uint8Array; | ||
} | { | ||
serializedSignature: string; | ||
signatureScheme: "MultiSig"; | ||
multisig: MultiSigStruct; | ||
bytes: Uint8Array; | ||
signature?: undefined; | ||
publicKey?: undefined; | ||
@@ -70,3 +67,2 @@ } | { | ||
multisig?: undefined; | ||
zkLogin?: undefined; | ||
}; |
@@ -27,5 +27,3 @@ "use strict"; | ||
var import_bcs2 = require("../bcs/index.js"); | ||
var import_address = require("../zklogin/address.js"); | ||
var import_jwt_utils = require("../zklogin/jwt-utils.js"); | ||
var import_signature = require("../zklogin/signature.js"); | ||
var import_publickey = require("../zklogin/publickey.js"); | ||
var import_signature_scheme = require("./signature-scheme.js"); | ||
@@ -60,20 +58,3 @@ function toSerializedSignature({ | ||
case "ZkLogin": | ||
const signatureBytes = bytes.slice(1); | ||
const { inputs, maxEpoch, userSignature } = (0, import_signature.parseZkLoginSignature)(signatureBytes); | ||
const { issBase64Details, addressSeed } = inputs; | ||
const iss = (0, import_jwt_utils.extractClaimValue)(issBase64Details, "iss"); | ||
const address = (0, import_address.computeZkLoginAddressFromSeed)(BigInt(addressSeed), iss); | ||
return { | ||
serializedSignature, | ||
signatureScheme, | ||
zkLogin: { | ||
inputs, | ||
maxEpoch, | ||
userSignature, | ||
iss, | ||
address, | ||
addressSeed: BigInt(addressSeed) | ||
}, | ||
signature: bytes | ||
}; | ||
return (0, import_publickey.parseSerializedZkLoginSignature)(serializedSignature); | ||
case "ED25519": | ||
@@ -80,0 +61,0 @@ case "Secp256k1": |
@@ -37,3 +37,3 @@ import type { TypedDocumentNode } from '@graphql-typed-document-node/core'; | ||
} | ||
export declare class SuiGraphQLClient<Queries extends Record<string, GraphQLDocument>> { | ||
export declare class SuiGraphQLClient<Queries extends Record<string, GraphQLDocument> = {}> { | ||
#private; | ||
@@ -40,0 +40,0 @@ constructor({ url, fetch: fetchFn, headers, queries, }: SuiGraphQLClientOptions<Queries>); |
@@ -0,2 +1,3 @@ | ||
export { MultiSigSigner } from './signer.js'; | ||
export * from './publickey.js'; | ||
export declare function publicKeyFromSuiBytes(publicKey: string | Uint8Array): import("../cryptography/publickey.js").PublicKey; |
@@ -22,2 +22,3 @@ "use strict"; | ||
__export(multisig_exports, { | ||
MultiSigSigner: () => import_signer.MultiSigSigner, | ||
publicKeyFromSuiBytes: () => publicKeyFromSuiBytes | ||
@@ -29,2 +30,3 @@ }); | ||
var import_verify = require("../verify/index.js"); | ||
var import_signer = require("./signer.js"); | ||
__reExport(multisig_exports, require("./publickey.js"), module.exports); | ||
@@ -31,0 +33,0 @@ function publicKeyFromSuiBytes(publicKey) { |
@@ -0,4 +1,7 @@ | ||
import type { Signer } from '../cryptography/keypair.js'; | ||
import { PublicKey } from '../cryptography/publickey.js'; | ||
import type { SignatureScheme } from '../cryptography/signature-scheme.js'; | ||
import type { SerializedSignature } from '../cryptography/signature.js'; | ||
import type { SuiGraphQLClient } from '../graphql/client.js'; | ||
import { MultiSigSigner } from './signer.js'; | ||
type CompressedSignature = { | ||
@@ -57,3 +60,5 @@ ED25519: number[]; | ||
*/ | ||
value: string | Uint8Array | MultiSigPublicKeyStruct); | ||
value: string | Uint8Array | MultiSigPublicKeyStruct, options?: { | ||
client?: SuiGraphQLClient; | ||
}); | ||
/** | ||
@@ -81,2 +86,4 @@ * A static method to create a new MultiSig publickey instance from a set of public keys and their associated weights pairs and threshold. | ||
}[]; | ||
getThreshold(): number; | ||
getSigner(signers: Signer[]): MultiSigSigner; | ||
/** | ||
@@ -103,3 +110,5 @@ * Return the Sui address associated with this MultiSig public key | ||
*/ | ||
export declare function parsePartialSignatures(multisig: MultiSigStruct): ParsedPartialMultiSigSignature[]; | ||
export declare function parsePartialSignatures(multisig: MultiSigStruct, options?: { | ||
client?: SuiGraphQLClient; | ||
}): ParsedPartialMultiSigSignature[]; | ||
export {}; |
@@ -37,2 +37,3 @@ "use strict"; | ||
var import_publickey2 = require("../zklogin/publickey.js"); | ||
var import_signer = require("./signer.js"); | ||
const MAX_SIGNER_IN_MULTISIG = 10; | ||
@@ -44,3 +45,3 @@ const MIN_SIGNER_IN_MULTISIG = 1; | ||
*/ | ||
constructor(value) { | ||
constructor(value, options = {}) { | ||
super(); | ||
@@ -72,3 +73,3 @@ if (typeof value === "string") { | ||
return { | ||
publicKey: (0, import_verify.publicKeyFromRawBytes)(scheme, Uint8Array.from(bytes)), | ||
publicKey: (0, import_verify.publicKeyFromRawBytes)(scheme, Uint8Array.from(bytes), options), | ||
weight | ||
@@ -121,2 +122,8 @@ }; | ||
} | ||
getThreshold() { | ||
return this.multisigPublicKey.threshold; | ||
} | ||
getSigner(signers) { | ||
return new import_signer.MultiSigSigner(this, signers); | ||
} | ||
/** | ||
@@ -149,6 +156,7 @@ * Return the Sui address associated with this MultiSig public key | ||
async verify(message, multisigSignature) { | ||
const { signatureScheme, multisig } = (0, import_signature.parseSerializedSignature)(multisigSignature); | ||
if (signatureScheme !== "MultiSig") { | ||
const parsed = (0, import_signature.parseSerializedSignature)(multisigSignature); | ||
if (parsed.signatureScheme !== "MultiSig") { | ||
throw new Error("Invalid signature scheme"); | ||
} | ||
const { multisig } = parsed; | ||
let signatureWeight = 0; | ||
@@ -223,3 +231,3 @@ if (!(0, import_publickey.bytesEqual)( | ||
} | ||
function parsePartialSignatures(multisig) { | ||
function parsePartialSignatures(multisig, options = {}) { | ||
let res = new Array(multisig.sigs.length); | ||
@@ -234,3 +242,3 @@ for (let i = 0; i < multisig.sigs.length; i++) { | ||
} | ||
const publicKey = (0, import_verify.publicKeyFromRawBytes)(signatureScheme, pkBytes); | ||
const publicKey = (0, import_verify.publicKeyFromRawBytes)(signatureScheme, pkBytes, options); | ||
res[i] = { | ||
@@ -237,0 +245,0 @@ signatureScheme, |
import type { PublicKey, SerializedSignature, SignatureScheme } from '../cryptography/index.js'; | ||
import type { SuiGraphQLClient } from '../graphql/client.js'; | ||
export declare function verifySignature(bytes: Uint8Array, signature: SerializedSignature): Promise<PublicKey>; | ||
export declare function verifyPersonalMessage(message: Uint8Array, signature: SerializedSignature): Promise<PublicKey>; | ||
export declare function verifyPersonalMessage(message: Uint8Array, signature: SerializedSignature, options?: { | ||
client?: SuiGraphQLClient; | ||
}): Promise<PublicKey>; | ||
export declare function verifyTransactionBlock(transactionBlock: Uint8Array, signature: SerializedSignature): Promise<PublicKey>; | ||
export declare function publicKeyFromRawBytes(signatureScheme: SignatureScheme, bytes: Uint8Array): PublicKey; | ||
export declare function publicKeyFromRawBytes(signatureScheme: SignatureScheme, bytes: Uint8Array, options?: { | ||
client?: SuiGraphQLClient; | ||
}): PublicKey; |
@@ -40,4 +40,4 @@ "use strict"; | ||
} | ||
async function verifyPersonalMessage(message, signature) { | ||
const parsedSignature = parseSignature(signature); | ||
async function verifyPersonalMessage(message, signature, options = {}) { | ||
const parsedSignature = parseSignature(signature, options); | ||
if (!await parsedSignature.publicKey.verifyPersonalMessage( | ||
@@ -61,3 +61,3 @@ message, | ||
} | ||
function parseSignature(signature) { | ||
function parseSignature(signature, options = {}) { | ||
const parsedSignature = (0, import_cryptography.parseSerializedSignature)(signature); | ||
@@ -70,8 +70,6 @@ if (parsedSignature.signatureScheme === "MultiSig") { | ||
} | ||
if (parsedSignature.signatureScheme === "ZkLogin") { | ||
throw new Error("ZkLogin is not supported yet"); | ||
} | ||
const publicKey = publicKeyFromRawBytes( | ||
parsedSignature.signatureScheme, | ||
parsedSignature.publicKey | ||
parsedSignature.publicKey, | ||
options | ||
); | ||
@@ -83,3 +81,3 @@ return { | ||
} | ||
function publicKeyFromRawBytes(signatureScheme, bytes) { | ||
function publicKeyFromRawBytes(signatureScheme, bytes, options = {}) { | ||
switch (signatureScheme) { | ||
@@ -95,3 +93,3 @@ case "ED25519": | ||
case "ZkLogin": | ||
return new import_publickey5.ZkLoginPublicIdentifier(bytes); | ||
return new import_publickey5.ZkLoginPublicIdentifier(bytes, options); | ||
default: | ||
@@ -98,0 +96,0 @@ throw new Error(`Unsupported signature scheme ${signatureScheme}`); |
@@ -1,2 +0,2 @@ | ||
export declare const PACKAGE_VERSION = "0.0.0-experimental-20240425163027"; | ||
export declare const TARGETED_RPC_VERSION = "1.24.0"; | ||
export declare const PACKAGE_VERSION = "0.0.0-experimental-20240508033635"; | ||
export declare const TARGETED_RPC_VERSION = "1.25.0"; |
@@ -25,4 +25,4 @@ "use strict"; | ||
module.exports = __toCommonJS(version_exports); | ||
const PACKAGE_VERSION = "0.0.0-experimental-20240425163027"; | ||
const TARGETED_RPC_VERSION = "1.24.0"; | ||
const PACKAGE_VERSION = "0.0.0-experimental-20240508033635"; | ||
const TARGETED_RPC_VERSION = "1.25.0"; | ||
//# sourceMappingURL=version.js.map |
import { PublicKey } from '../cryptography/publickey.js'; | ||
import type { PublicKeyInitData } from '../cryptography/publickey.js'; | ||
import type { SerializedSignature } from '../cryptography/signature.js'; | ||
import { SuiGraphQLClient } from '../graphql/client.js'; | ||
/** | ||
@@ -8,3 +9,3 @@ * A zkLogin public identifier | ||
export declare class ZkLoginPublicIdentifier extends PublicKey { | ||
private data; | ||
#private; | ||
/** | ||
@@ -14,3 +15,5 @@ * Create a new ZkLoginPublicIdentifier object | ||
*/ | ||
constructor(value: PublicKeyInitData); | ||
constructor(value: PublicKeyInitData, { client }?: { | ||
client?: SuiGraphQLClient; | ||
}); | ||
/** | ||
@@ -31,4 +34,40 @@ * Checks if two zkLogin public identifiers are equal | ||
*/ | ||
verify(_message: Uint8Array, _signature: Uint8Array | SerializedSignature): Promise<boolean>; | ||
verify(_message: Uint8Array, _signature: Uint8Array | string): Promise<boolean>; | ||
/** | ||
* Verifies that the signature is valid for for the provided PersonalMessage | ||
*/ | ||
verifyPersonalMessage(message: Uint8Array, signature: Uint8Array | SerializedSignature): Promise<boolean>; | ||
/** | ||
* Verifies that the signature is valid for for the provided TransactionBlock | ||
*/ | ||
verifyTransactionBlock(transactionBlock: Uint8Array, signature: Uint8Array | SerializedSignature): Promise<boolean>; | ||
} | ||
export declare function toZkLoginPublicIdentifier(addressSeed: bigint, iss: string): ZkLoginPublicIdentifier; | ||
export declare function toZkLoginPublicIdentifier(addressSeed: bigint, iss: string, options?: { | ||
client?: SuiGraphQLClient; | ||
}): ZkLoginPublicIdentifier; | ||
export declare function parseSerializedZkLoginSignature(signature: Uint8Array | SerializedSignature): { | ||
serializedSignature: string; | ||
signatureScheme: "ZkLogin"; | ||
zkLogin: { | ||
inputs: { | ||
proofPoints: { | ||
a: string[]; | ||
b: string[][]; | ||
c: string[]; | ||
}; | ||
issBase64Details: { | ||
value: string; | ||
indexMod4: number; | ||
}; | ||
headerBase64: string; | ||
addressSeed: string; | ||
}; | ||
maxEpoch: string; | ||
userSignature: number[]; | ||
iss: string; | ||
address: string; | ||
addressSeed: bigint; | ||
}; | ||
signature: Uint8Array; | ||
publicKey: Uint8Array; | ||
}; |
@@ -19,5 +19,24 @@ "use strict"; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var __accessCheck = (obj, member, msg) => { | ||
if (!member.has(obj)) | ||
throw TypeError("Cannot " + msg); | ||
}; | ||
var __privateGet = (obj, member, getter) => { | ||
__accessCheck(obj, member, "read from private field"); | ||
return getter ? getter.call(obj) : member.get(obj); | ||
}; | ||
var __privateAdd = (obj, member, value) => { | ||
if (member.has(obj)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
}; | ||
var __privateSet = (obj, member, value, setter) => { | ||
__accessCheck(obj, member, "write to private field"); | ||
setter ? setter.call(obj, value) : member.set(obj, value); | ||
return value; | ||
}; | ||
var publickey_exports = {}; | ||
__export(publickey_exports, { | ||
ZkLoginPublicIdentifier: () => ZkLoginPublicIdentifier, | ||
parseSerializedZkLoginSignature: () => parseSerializedZkLoginSignature, | ||
toZkLoginPublicIdentifier: () => toZkLoginPublicIdentifier | ||
@@ -29,3 +48,8 @@ }); | ||
var import_signature_scheme = require("../cryptography/signature-scheme.js"); | ||
var import_client = require("../graphql/client.js"); | ||
var import__ = require("../graphql/schemas/2024-01/index.js"); | ||
var import_jwt_utils = require("./jwt-utils.js"); | ||
var import_signature = require("./signature.js"); | ||
var import_utils = require("./utils.js"); | ||
var _data, _client; | ||
class ZkLoginPublicIdentifier extends import_publickey.PublicKey { | ||
@@ -36,10 +60,13 @@ /** | ||
*/ | ||
constructor(value) { | ||
constructor(value, { client } = {}) { | ||
super(); | ||
__privateAdd(this, _data, void 0); | ||
__privateAdd(this, _client, void 0); | ||
__privateSet(this, _client, client); | ||
if (typeof value === "string") { | ||
this.data = (0, import_bcs.fromB64)(value); | ||
__privateSet(this, _data, (0, import_bcs.fromB64)(value)); | ||
} else if (value instanceof Uint8Array) { | ||
this.data = value; | ||
__privateSet(this, _data, value); | ||
} else { | ||
this.data = Uint8Array.from(value); | ||
__privateSet(this, _data, Uint8Array.from(value)); | ||
} | ||
@@ -57,3 +84,3 @@ } | ||
toRawBytes() { | ||
return this.data; | ||
return __privateGet(this, _data); | ||
} | ||
@@ -72,4 +99,32 @@ /** | ||
} | ||
/** | ||
* Verifies that the signature is valid for for the provided PersonalMessage | ||
*/ | ||
verifyPersonalMessage(message, signature) { | ||
const parsedSignature = parseSerializedZkLoginSignature(signature); | ||
return graphqlVerifyZkLoginSignature({ | ||
address: parsedSignature.zkLogin.address, | ||
bytes: (0, import_bcs.toB64)(message), | ||
signature: parsedSignature.serializedSignature, | ||
intentScope: "PERSONAL_MESSAGE", | ||
client: __privateGet(this, _client) | ||
}); | ||
} | ||
/** | ||
* Verifies that the signature is valid for for the provided TransactionBlock | ||
*/ | ||
verifyTransactionBlock(transactionBlock, signature) { | ||
const parsedSignature = parseSerializedZkLoginSignature(signature); | ||
return graphqlVerifyZkLoginSignature({ | ||
address: parsedSignature.zkLogin.address, | ||
bytes: (0, import_bcs.toB64)(transactionBlock), | ||
signature: parsedSignature.serializedSignature, | ||
intentScope: "TRANSACTION_DATA", | ||
client: __privateGet(this, _client) | ||
}); | ||
} | ||
} | ||
function toZkLoginPublicIdentifier(addressSeed, iss) { | ||
_data = new WeakMap(); | ||
_client = new WeakMap(); | ||
function toZkLoginPublicIdentifier(addressSeed, iss, options) { | ||
const addressSeedBytesBigEndian = (0, import_utils.toPaddedBigEndianBytes)(addressSeed, 32); | ||
@@ -81,4 +136,68 @@ const issBytes = new TextEncoder().encode(iss); | ||
tmp.set(addressSeedBytesBigEndian, 1 + issBytes.length); | ||
return new ZkLoginPublicIdentifier(tmp); | ||
return new ZkLoginPublicIdentifier(tmp, options); | ||
} | ||
const VerifyZkLoginSignatureQuery = (0, import__.graphql)(` | ||
query Zklogin( | ||
$bytes: Base64! | ||
$signature: Base64! | ||
$intentScope: ZkLoginIntentScope! | ||
$author: SuiAddress! | ||
) { | ||
verifyZkloginSignature( | ||
bytes: $bytes | ||
signature: $signature | ||
intentScope: $intentScope | ||
author: $author | ||
) { | ||
success | ||
errors | ||
} | ||
} | ||
`); | ||
async function graphqlVerifyZkLoginSignature({ | ||
address, | ||
bytes, | ||
signature, | ||
intentScope, | ||
client = new import_client.SuiGraphQLClient({ | ||
url: "https://sui-mainnet.mystenlabs.com/graphql" | ||
}) | ||
}) { | ||
const resp = await client.query({ | ||
query: VerifyZkLoginSignatureQuery, | ||
variables: { | ||
bytes, | ||
signature, | ||
intentScope, | ||
author: address | ||
} | ||
}); | ||
return resp.data?.verifyZkloginSignature.success === true && resp.data?.verifyZkloginSignature.errors.length === 0; | ||
} | ||
function parseSerializedZkLoginSignature(signature) { | ||
const bytes = typeof signature === "string" ? (0, import_bcs.fromB64)(signature) : signature; | ||
if (bytes[0] !== import_signature_scheme.SIGNATURE_SCHEME_TO_FLAG.ZkLogin) { | ||
throw new Error("Invalid signature scheme"); | ||
} | ||
const signatureBytes = bytes.slice(1); | ||
const { inputs, maxEpoch, userSignature } = (0, import_signature.parseZkLoginSignature)(signatureBytes); | ||
const { issBase64Details, addressSeed } = inputs; | ||
const iss = (0, import_jwt_utils.extractClaimValue)(issBase64Details, "iss"); | ||
const publicIdentifer = toZkLoginPublicIdentifier(BigInt(addressSeed), iss); | ||
const address = publicIdentifer.toSuiAddress(); | ||
return { | ||
serializedSignature: (0, import_bcs.toB64)(bytes), | ||
signatureScheme: "ZkLogin", | ||
zkLogin: { | ||
inputs, | ||
maxEpoch, | ||
userSignature, | ||
iss, | ||
address, | ||
addressSeed: BigInt(addressSeed) | ||
}, | ||
signature: bytes, | ||
publicKey: publicIdentifer.toRawBytes() | ||
}; | ||
} | ||
//# sourceMappingURL=publickey.js.map |
@@ -28,10 +28,2 @@ import type { MultiSigStruct } from '../multisig/publickey.js'; | ||
serializedSignature: string; | ||
signatureScheme: "MultiSig"; | ||
multisig: MultiSigStruct; | ||
bytes: Uint8Array; | ||
zkLogin?: undefined; | ||
signature?: undefined; | ||
publicKey?: undefined; | ||
} | { | ||
serializedSignature: string; | ||
signatureScheme: "ZkLogin"; | ||
@@ -59,4 +51,9 @@ zkLogin: { | ||
signature: Uint8Array; | ||
multisig?: undefined; | ||
bytes?: undefined; | ||
publicKey: Uint8Array; | ||
} | { | ||
serializedSignature: string; | ||
signatureScheme: "MultiSig"; | ||
multisig: MultiSigStruct; | ||
bytes: Uint8Array; | ||
signature?: undefined; | ||
publicKey?: undefined; | ||
@@ -70,3 +67,2 @@ } | { | ||
multisig?: undefined; | ||
zkLogin?: undefined; | ||
}; |
import { fromB64, toB64 } from "@mysten/bcs"; | ||
import { bcs } from "../bcs/index.js"; | ||
import { computeZkLoginAddressFromSeed } from "../zklogin/address.js"; | ||
import { extractClaimValue } from "../zklogin/jwt-utils.js"; | ||
import { parseZkLoginSignature } from "../zklogin/signature.js"; | ||
import { parseSerializedZkLoginSignature } from "../zklogin/publickey.js"; | ||
import { | ||
@@ -39,20 +37,3 @@ SIGNATURE_FLAG_TO_SCHEME, | ||
case "ZkLogin": | ||
const signatureBytes = bytes.slice(1); | ||
const { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes); | ||
const { issBase64Details, addressSeed } = inputs; | ||
const iss = extractClaimValue(issBase64Details, "iss"); | ||
const address = computeZkLoginAddressFromSeed(BigInt(addressSeed), iss); | ||
return { | ||
serializedSignature, | ||
signatureScheme, | ||
zkLogin: { | ||
inputs, | ||
maxEpoch, | ||
userSignature, | ||
iss, | ||
address, | ||
addressSeed: BigInt(addressSeed) | ||
}, | ||
signature: bytes | ||
}; | ||
return parseSerializedZkLoginSignature(serializedSignature); | ||
case "ED25519": | ||
@@ -59,0 +40,0 @@ case "Secp256k1": |
@@ -37,3 +37,3 @@ import type { TypedDocumentNode } from '@graphql-typed-document-node/core'; | ||
} | ||
export declare class SuiGraphQLClient<Queries extends Record<string, GraphQLDocument>> { | ||
export declare class SuiGraphQLClient<Queries extends Record<string, GraphQLDocument> = {}> { | ||
#private; | ||
@@ -40,0 +40,0 @@ constructor({ url, fetch: fetchFn, headers, queries, }: SuiGraphQLClientOptions<Queries>); |
@@ -0,2 +1,3 @@ | ||
export { MultiSigSigner } from './signer.js'; | ||
export * from './publickey.js'; | ||
export declare function publicKeyFromSuiBytes(publicKey: string | Uint8Array): import("../cryptography/publickey.js").PublicKey; |
import { fromB64 } from "@mysten/bcs"; | ||
import { SIGNATURE_FLAG_TO_SCHEME } from "../cryptography/index.js"; | ||
import { publicKeyFromRawBytes } from "../verify/index.js"; | ||
import { MultiSigSigner } from "./signer.js"; | ||
export * from "./publickey.js"; | ||
@@ -14,4 +15,5 @@ function publicKeyFromSuiBytes(publicKey) { | ||
export { | ||
MultiSigSigner, | ||
publicKeyFromSuiBytes | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -0,4 +1,7 @@ | ||
import type { Signer } from '../cryptography/keypair.js'; | ||
import { PublicKey } from '../cryptography/publickey.js'; | ||
import type { SignatureScheme } from '../cryptography/signature-scheme.js'; | ||
import type { SerializedSignature } from '../cryptography/signature.js'; | ||
import type { SuiGraphQLClient } from '../graphql/client.js'; | ||
import { MultiSigSigner } from './signer.js'; | ||
type CompressedSignature = { | ||
@@ -57,3 +60,5 @@ ED25519: number[]; | ||
*/ | ||
value: string | Uint8Array | MultiSigPublicKeyStruct); | ||
value: string | Uint8Array | MultiSigPublicKeyStruct, options?: { | ||
client?: SuiGraphQLClient; | ||
}); | ||
/** | ||
@@ -81,2 +86,4 @@ * A static method to create a new MultiSig publickey instance from a set of public keys and their associated weights pairs and threshold. | ||
}[]; | ||
getThreshold(): number; | ||
getSigner(signers: Signer[]): MultiSigSigner; | ||
/** | ||
@@ -103,3 +110,5 @@ * Return the Sui address associated with this MultiSig public key | ||
*/ | ||
export declare function parsePartialSignatures(multisig: MultiSigStruct): ParsedPartialMultiSigSignature[]; | ||
export declare function parsePartialSignatures(multisig: MultiSigStruct, options?: { | ||
client?: SuiGraphQLClient; | ||
}): ParsedPartialMultiSigSignature[]; | ||
export {}; |
@@ -14,2 +14,3 @@ import { fromB64, toB64 } from "@mysten/bcs"; | ||
import { toZkLoginPublicIdentifier } from "../zklogin/publickey.js"; | ||
import { MultiSigSigner } from "./signer.js"; | ||
const MAX_SIGNER_IN_MULTISIG = 10; | ||
@@ -21,3 +22,3 @@ const MIN_SIGNER_IN_MULTISIG = 1; | ||
*/ | ||
constructor(value) { | ||
constructor(value, options = {}) { | ||
super(); | ||
@@ -49,3 +50,3 @@ if (typeof value === "string") { | ||
return { | ||
publicKey: publicKeyFromRawBytes(scheme, Uint8Array.from(bytes)), | ||
publicKey: publicKeyFromRawBytes(scheme, Uint8Array.from(bytes), options), | ||
weight | ||
@@ -98,2 +99,8 @@ }; | ||
} | ||
getThreshold() { | ||
return this.multisigPublicKey.threshold; | ||
} | ||
getSigner(signers) { | ||
return new MultiSigSigner(this, signers); | ||
} | ||
/** | ||
@@ -126,6 +133,7 @@ * Return the Sui address associated with this MultiSig public key | ||
async verify(message, multisigSignature) { | ||
const { signatureScheme, multisig } = parseSerializedSignature(multisigSignature); | ||
if (signatureScheme !== "MultiSig") { | ||
const parsed = parseSerializedSignature(multisigSignature); | ||
if (parsed.signatureScheme !== "MultiSig") { | ||
throw new Error("Invalid signature scheme"); | ||
} | ||
const { multisig } = parsed; | ||
let signatureWeight = 0; | ||
@@ -200,3 +208,3 @@ if (!bytesEqual( | ||
} | ||
function parsePartialSignatures(multisig) { | ||
function parsePartialSignatures(multisig, options = {}) { | ||
let res = new Array(multisig.sigs.length); | ||
@@ -211,3 +219,3 @@ for (let i = 0; i < multisig.sigs.length; i++) { | ||
} | ||
const publicKey = publicKeyFromRawBytes(signatureScheme, pkBytes); | ||
const publicKey = publicKeyFromRawBytes(signatureScheme, pkBytes, options); | ||
res[i] = { | ||
@@ -214,0 +222,0 @@ signatureScheme, |
import type { PublicKey, SerializedSignature, SignatureScheme } from '../cryptography/index.js'; | ||
import type { SuiGraphQLClient } from '../graphql/client.js'; | ||
export declare function verifySignature(bytes: Uint8Array, signature: SerializedSignature): Promise<PublicKey>; | ||
export declare function verifyPersonalMessage(message: Uint8Array, signature: SerializedSignature): Promise<PublicKey>; | ||
export declare function verifyPersonalMessage(message: Uint8Array, signature: SerializedSignature, options?: { | ||
client?: SuiGraphQLClient; | ||
}): Promise<PublicKey>; | ||
export declare function verifyTransactionBlock(transactionBlock: Uint8Array, signature: SerializedSignature): Promise<PublicKey>; | ||
export declare function publicKeyFromRawBytes(signatureScheme: SignatureScheme, bytes: Uint8Array): PublicKey; | ||
export declare function publicKeyFromRawBytes(signatureScheme: SignatureScheme, bytes: Uint8Array, options?: { | ||
client?: SuiGraphQLClient; | ||
}): PublicKey; |
@@ -14,4 +14,4 @@ import { parseSerializedSignature } from "../cryptography/index.js"; | ||
} | ||
async function verifyPersonalMessage(message, signature) { | ||
const parsedSignature = parseSignature(signature); | ||
async function verifyPersonalMessage(message, signature, options = {}) { | ||
const parsedSignature = parseSignature(signature, options); | ||
if (!await parsedSignature.publicKey.verifyPersonalMessage( | ||
@@ -35,3 +35,3 @@ message, | ||
} | ||
function parseSignature(signature) { | ||
function parseSignature(signature, options = {}) { | ||
const parsedSignature = parseSerializedSignature(signature); | ||
@@ -44,8 +44,6 @@ if (parsedSignature.signatureScheme === "MultiSig") { | ||
} | ||
if (parsedSignature.signatureScheme === "ZkLogin") { | ||
throw new Error("ZkLogin is not supported yet"); | ||
} | ||
const publicKey = publicKeyFromRawBytes( | ||
parsedSignature.signatureScheme, | ||
parsedSignature.publicKey | ||
parsedSignature.publicKey, | ||
options | ||
); | ||
@@ -57,3 +55,3 @@ return { | ||
} | ||
function publicKeyFromRawBytes(signatureScheme, bytes) { | ||
function publicKeyFromRawBytes(signatureScheme, bytes, options = {}) { | ||
switch (signatureScheme) { | ||
@@ -69,3 +67,3 @@ case "ED25519": | ||
case "ZkLogin": | ||
return new ZkLoginPublicIdentifier(bytes); | ||
return new ZkLoginPublicIdentifier(bytes, options); | ||
default: | ||
@@ -72,0 +70,0 @@ throw new Error(`Unsupported signature scheme ${signatureScheme}`); |
@@ -1,2 +0,2 @@ | ||
export declare const PACKAGE_VERSION = "0.0.0-experimental-20240425163027"; | ||
export declare const TARGETED_RPC_VERSION = "1.24.0"; | ||
export declare const PACKAGE_VERSION = "0.0.0-experimental-20240508033635"; | ||
export declare const TARGETED_RPC_VERSION = "1.25.0"; |
@@ -1,3 +0,3 @@ | ||
const PACKAGE_VERSION = "0.0.0-experimental-20240425163027"; | ||
const TARGETED_RPC_VERSION = "1.24.0"; | ||
const PACKAGE_VERSION = "0.0.0-experimental-20240508033635"; | ||
const TARGETED_RPC_VERSION = "1.25.0"; | ||
export { | ||
@@ -4,0 +4,0 @@ PACKAGE_VERSION, |
import { PublicKey } from '../cryptography/publickey.js'; | ||
import type { PublicKeyInitData } from '../cryptography/publickey.js'; | ||
import type { SerializedSignature } from '../cryptography/signature.js'; | ||
import { SuiGraphQLClient } from '../graphql/client.js'; | ||
/** | ||
@@ -8,3 +9,3 @@ * A zkLogin public identifier | ||
export declare class ZkLoginPublicIdentifier extends PublicKey { | ||
private data; | ||
#private; | ||
/** | ||
@@ -14,3 +15,5 @@ * Create a new ZkLoginPublicIdentifier object | ||
*/ | ||
constructor(value: PublicKeyInitData); | ||
constructor(value: PublicKeyInitData, { client }?: { | ||
client?: SuiGraphQLClient; | ||
}); | ||
/** | ||
@@ -31,4 +34,40 @@ * Checks if two zkLogin public identifiers are equal | ||
*/ | ||
verify(_message: Uint8Array, _signature: Uint8Array | SerializedSignature): Promise<boolean>; | ||
verify(_message: Uint8Array, _signature: Uint8Array | string): Promise<boolean>; | ||
/** | ||
* Verifies that the signature is valid for for the provided PersonalMessage | ||
*/ | ||
verifyPersonalMessage(message: Uint8Array, signature: Uint8Array | SerializedSignature): Promise<boolean>; | ||
/** | ||
* Verifies that the signature is valid for for the provided TransactionBlock | ||
*/ | ||
verifyTransactionBlock(transactionBlock: Uint8Array, signature: Uint8Array | SerializedSignature): Promise<boolean>; | ||
} | ||
export declare function toZkLoginPublicIdentifier(addressSeed: bigint, iss: string): ZkLoginPublicIdentifier; | ||
export declare function toZkLoginPublicIdentifier(addressSeed: bigint, iss: string, options?: { | ||
client?: SuiGraphQLClient; | ||
}): ZkLoginPublicIdentifier; | ||
export declare function parseSerializedZkLoginSignature(signature: Uint8Array | SerializedSignature): { | ||
serializedSignature: string; | ||
signatureScheme: "ZkLogin"; | ||
zkLogin: { | ||
inputs: { | ||
proofPoints: { | ||
a: string[]; | ||
b: string[][]; | ||
c: string[]; | ||
}; | ||
issBase64Details: { | ||
value: string; | ||
indexMod4: number; | ||
}; | ||
headerBase64: string; | ||
addressSeed: string; | ||
}; | ||
maxEpoch: string; | ||
userSignature: number[]; | ||
iss: string; | ||
address: string; | ||
addressSeed: bigint; | ||
}; | ||
signature: Uint8Array; | ||
publicKey: Uint8Array; | ||
}; |
@@ -1,4 +0,27 @@ | ||
import { fromB64 } from "@mysten/bcs"; | ||
var __accessCheck = (obj, member, msg) => { | ||
if (!member.has(obj)) | ||
throw TypeError("Cannot " + msg); | ||
}; | ||
var __privateGet = (obj, member, getter) => { | ||
__accessCheck(obj, member, "read from private field"); | ||
return getter ? getter.call(obj) : member.get(obj); | ||
}; | ||
var __privateAdd = (obj, member, value) => { | ||
if (member.has(obj)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
}; | ||
var __privateSet = (obj, member, value, setter) => { | ||
__accessCheck(obj, member, "write to private field"); | ||
setter ? setter.call(obj, value) : member.set(obj, value); | ||
return value; | ||
}; | ||
var _data, _client; | ||
import { fromB64, toB64 } from "@mysten/bcs"; | ||
import { PublicKey } from "../cryptography/publickey.js"; | ||
import { SIGNATURE_SCHEME_TO_FLAG } from "../cryptography/signature-scheme.js"; | ||
import { SuiGraphQLClient } from "../graphql/client.js"; | ||
import { graphql } from "../graphql/schemas/2024-01/index.js"; | ||
import { extractClaimValue } from "./jwt-utils.js"; | ||
import { parseZkLoginSignature } from "./signature.js"; | ||
import { toPaddedBigEndianBytes } from "./utils.js"; | ||
@@ -10,10 +33,13 @@ class ZkLoginPublicIdentifier extends PublicKey { | ||
*/ | ||
constructor(value) { | ||
constructor(value, { client } = {}) { | ||
super(); | ||
__privateAdd(this, _data, void 0); | ||
__privateAdd(this, _client, void 0); | ||
__privateSet(this, _client, client); | ||
if (typeof value === "string") { | ||
this.data = fromB64(value); | ||
__privateSet(this, _data, fromB64(value)); | ||
} else if (value instanceof Uint8Array) { | ||
this.data = value; | ||
__privateSet(this, _data, value); | ||
} else { | ||
this.data = Uint8Array.from(value); | ||
__privateSet(this, _data, Uint8Array.from(value)); | ||
} | ||
@@ -31,3 +57,3 @@ } | ||
toRawBytes() { | ||
return this.data; | ||
return __privateGet(this, _data); | ||
} | ||
@@ -46,4 +72,32 @@ /** | ||
} | ||
/** | ||
* Verifies that the signature is valid for for the provided PersonalMessage | ||
*/ | ||
verifyPersonalMessage(message, signature) { | ||
const parsedSignature = parseSerializedZkLoginSignature(signature); | ||
return graphqlVerifyZkLoginSignature({ | ||
address: parsedSignature.zkLogin.address, | ||
bytes: toB64(message), | ||
signature: parsedSignature.serializedSignature, | ||
intentScope: "PERSONAL_MESSAGE", | ||
client: __privateGet(this, _client) | ||
}); | ||
} | ||
/** | ||
* Verifies that the signature is valid for for the provided TransactionBlock | ||
*/ | ||
verifyTransactionBlock(transactionBlock, signature) { | ||
const parsedSignature = parseSerializedZkLoginSignature(signature); | ||
return graphqlVerifyZkLoginSignature({ | ||
address: parsedSignature.zkLogin.address, | ||
bytes: toB64(transactionBlock), | ||
signature: parsedSignature.serializedSignature, | ||
intentScope: "TRANSACTION_DATA", | ||
client: __privateGet(this, _client) | ||
}); | ||
} | ||
} | ||
function toZkLoginPublicIdentifier(addressSeed, iss) { | ||
_data = new WeakMap(); | ||
_client = new WeakMap(); | ||
function toZkLoginPublicIdentifier(addressSeed, iss, options) { | ||
const addressSeedBytesBigEndian = toPaddedBigEndianBytes(addressSeed, 32); | ||
@@ -55,8 +109,73 @@ const issBytes = new TextEncoder().encode(iss); | ||
tmp.set(addressSeedBytesBigEndian, 1 + issBytes.length); | ||
return new ZkLoginPublicIdentifier(tmp); | ||
return new ZkLoginPublicIdentifier(tmp, options); | ||
} | ||
const VerifyZkLoginSignatureQuery = graphql(` | ||
query Zklogin( | ||
$bytes: Base64! | ||
$signature: Base64! | ||
$intentScope: ZkLoginIntentScope! | ||
$author: SuiAddress! | ||
) { | ||
verifyZkloginSignature( | ||
bytes: $bytes | ||
signature: $signature | ||
intentScope: $intentScope | ||
author: $author | ||
) { | ||
success | ||
errors | ||
} | ||
} | ||
`); | ||
async function graphqlVerifyZkLoginSignature({ | ||
address, | ||
bytes, | ||
signature, | ||
intentScope, | ||
client = new SuiGraphQLClient({ | ||
url: "https://sui-mainnet.mystenlabs.com/graphql" | ||
}) | ||
}) { | ||
const resp = await client.query({ | ||
query: VerifyZkLoginSignatureQuery, | ||
variables: { | ||
bytes, | ||
signature, | ||
intentScope, | ||
author: address | ||
} | ||
}); | ||
return resp.data?.verifyZkloginSignature.success === true && resp.data?.verifyZkloginSignature.errors.length === 0; | ||
} | ||
function parseSerializedZkLoginSignature(signature) { | ||
const bytes = typeof signature === "string" ? fromB64(signature) : signature; | ||
if (bytes[0] !== SIGNATURE_SCHEME_TO_FLAG.ZkLogin) { | ||
throw new Error("Invalid signature scheme"); | ||
} | ||
const signatureBytes = bytes.slice(1); | ||
const { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes); | ||
const { issBase64Details, addressSeed } = inputs; | ||
const iss = extractClaimValue(issBase64Details, "iss"); | ||
const publicIdentifer = toZkLoginPublicIdentifier(BigInt(addressSeed), iss); | ||
const address = publicIdentifer.toSuiAddress(); | ||
return { | ||
serializedSignature: toB64(bytes), | ||
signatureScheme: "ZkLogin", | ||
zkLogin: { | ||
inputs, | ||
maxEpoch, | ||
userSignature, | ||
iss, | ||
address, | ||
addressSeed: BigInt(addressSeed) | ||
}, | ||
signature: bytes, | ||
publicKey: publicIdentifer.toRawBytes() | ||
}; | ||
} | ||
export { | ||
ZkLoginPublicIdentifier, | ||
parseSerializedZkLoginSignature, | ||
toZkLoginPublicIdentifier | ||
}; | ||
//# sourceMappingURL=publickey.js.map |
@@ -6,3 +6,3 @@ { | ||
"homepage": "https://sdk.mystenlabs.com", | ||
"version": "0.0.0-experimental-20240425163027", | ||
"version": "0.0.0-experimental-20240508033635", | ||
"license": "Apache-2.0", | ||
@@ -9,0 +9,0 @@ "sideEffects": false, |
@@ -8,5 +8,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
import type { MultiSigStruct } from '../multisig/publickey.js'; | ||
import { computeZkLoginAddressFromSeed } from '../zklogin/address.js'; | ||
import { extractClaimValue } from '../zklogin/jwt-utils.js'; | ||
import { parseZkLoginSignature } from '../zklogin/signature.js'; | ||
import { parseSerializedZkLoginSignature } from '../zklogin/publickey.js'; | ||
import type { PublicKey } from './publickey.js'; | ||
@@ -76,21 +74,3 @@ import type { SignatureScheme } from './signature-scheme.js'; | ||
case 'ZkLogin': | ||
const signatureBytes = bytes.slice(1); | ||
const { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes); | ||
const { issBase64Details, addressSeed } = inputs; | ||
const iss = extractClaimValue<string>(issBase64Details, 'iss'); | ||
const address = computeZkLoginAddressFromSeed(BigInt(addressSeed), iss); | ||
return { | ||
serializedSignature, | ||
signatureScheme, | ||
zkLogin: { | ||
inputs, | ||
maxEpoch, | ||
userSignature, | ||
iss, | ||
address, | ||
addressSeed: BigInt(addressSeed), | ||
}, | ||
signature: bytes, | ||
}; | ||
return parseSerializedZkLoginSignature(serializedSignature); | ||
case 'ED25519': | ||
@@ -97,0 +77,0 @@ case 'Secp256k1': |
@@ -52,3 +52,4 @@ // Copyright (c) Mysten Labs, Inc. | ||
export class SuiGraphQLClient<Queries extends Record<string, GraphQLDocument>> { | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
export class SuiGraphQLClient<Queries extends Record<string, GraphQLDocument> = {}> { | ||
#url: string; | ||
@@ -55,0 +56,0 @@ #queries: Queries; |
@@ -9,2 +9,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
export { MultiSigSigner } from './signer.js'; | ||
export * from './publickey.js'; | ||
@@ -11,0 +12,0 @@ |
@@ -9,2 +9,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
import { bcs } from '../bcs/index.js'; | ||
import type { Signer } from '../cryptography/keypair.js'; | ||
import { bytesEqual, PublicKey } from '../cryptography/publickey.js'; | ||
@@ -18,2 +19,3 @@ import { | ||
import type { SerializedSignature } from '../cryptography/signature.js'; | ||
import type { SuiGraphQLClient } from '../graphql/client.js'; | ||
import { normalizeSuiAddress } from '../utils/sui-types.js'; | ||
@@ -23,2 +25,3 @@ // eslint-disable-next-line import/no-cycle | ||
import { toZkLoginPublicIdentifier } from '../zklogin/publickey.js'; | ||
import { MultiSigSigner } from './signer.js'; | ||
@@ -80,2 +83,3 @@ type CompressedSignature = | ||
value: string | Uint8Array | MultiSigPublicKeyStruct, | ||
options: { client?: SuiGraphQLClient } = {}, | ||
) { | ||
@@ -115,3 +119,3 @@ super(); | ||
return { | ||
publicKey: publicKeyFromRawBytes(scheme, Uint8Array.from(bytes)), | ||
publicKey: publicKeyFromRawBytes(scheme, Uint8Array.from(bytes), options), | ||
weight, | ||
@@ -177,2 +181,10 @@ }; | ||
getThreshold() { | ||
return this.multisigPublicKey.threshold; | ||
} | ||
getSigner(signers: Signer[]) { | ||
return new MultiSigSigner(this, signers); | ||
} | ||
/** | ||
@@ -211,8 +223,10 @@ * Return the Sui address associated with this MultiSig public key | ||
// Multisig verification only supports serialized signature | ||
const { signatureScheme, multisig } = parseSerializedSignature(multisigSignature); | ||
const parsed = parseSerializedSignature(multisigSignature); | ||
if (signatureScheme !== 'MultiSig') { | ||
if (parsed.signatureScheme !== 'MultiSig') { | ||
throw new Error('Invalid signature scheme'); | ||
} | ||
const { multisig } = parsed; | ||
let signatureWeight = 0; | ||
@@ -307,3 +321,6 @@ | ||
*/ | ||
export function parsePartialSignatures(multisig: MultiSigStruct): ParsedPartialMultiSigSignature[] { | ||
export function parsePartialSignatures( | ||
multisig: MultiSigStruct, | ||
options: { client?: SuiGraphQLClient } = {}, | ||
): ParsedPartialMultiSigSignature[] { | ||
let res: ParsedPartialMultiSigSignature[] = new Array(multisig.sigs.length); | ||
@@ -323,3 +340,3 @@ for (let i = 0; i < multisig.sigs.length; i++) { | ||
const publicKey = publicKeyFromRawBytes(signatureScheme, pkBytes); | ||
const publicKey = publicKeyFromRawBytes(signatureScheme, pkBytes, options); | ||
@@ -326,0 +343,0 @@ res[i] = { |
@@ -6,2 +6,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
import { parseSerializedSignature } from '../cryptography/index.js'; | ||
import type { SuiGraphQLClient } from '../graphql/client.js'; | ||
import { Ed25519PublicKey } from '../keypairs/ed25519/publickey.js'; | ||
@@ -30,4 +31,5 @@ import { Secp256k1PublicKey } from '../keypairs/secp256k1/publickey.js'; | ||
signature: SerializedSignature, | ||
options: { client?: SuiGraphQLClient } = {}, | ||
): Promise<PublicKey> { | ||
const parsedSignature = parseSignature(signature); | ||
const parsedSignature = parseSignature(signature, options); | ||
@@ -64,3 +66,6 @@ if ( | ||
function parseSignature(signature: SerializedSignature) { | ||
function parseSignature( | ||
signature: SerializedSignature, | ||
options: { client?: SuiGraphQLClient } = {}, | ||
) { | ||
const parsedSignature = parseSerializedSignature(signature); | ||
@@ -75,9 +80,6 @@ | ||
if (parsedSignature.signatureScheme === 'ZkLogin') { | ||
throw new Error('ZkLogin is not supported yet'); | ||
} | ||
const publicKey = publicKeyFromRawBytes( | ||
parsedSignature.signatureScheme, | ||
parsedSignature.publicKey, | ||
options, | ||
); | ||
@@ -93,2 +95,3 @@ return { | ||
bytes: Uint8Array, | ||
options: { client?: SuiGraphQLClient } = {}, | ||
): PublicKey { | ||
@@ -105,3 +108,3 @@ switch (signatureScheme) { | ||
case 'ZkLogin': | ||
return new ZkLoginPublicIdentifier(bytes); | ||
return new ZkLoginPublicIdentifier(bytes, options); | ||
default: | ||
@@ -108,0 +111,0 @@ throw new Error(`Unsupported signature scheme ${signatureScheme}`); |
@@ -6,3 +6,3 @@ // Copyright (c) Mysten Labs, Inc. | ||
export const PACKAGE_VERSION = '0.0.0-experimental-20240425163027'; | ||
export const TARGETED_RPC_VERSION = '1.24.0'; | ||
export const PACKAGE_VERSION = '0.0.0-experimental-20240508033635'; | ||
export const TARGETED_RPC_VERSION = '1.25.0'; |
// Copyright (c) Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
import { fromB64 } from '@mysten/bcs'; | ||
import { fromB64, toB64 } from '@mysten/bcs'; | ||
@@ -10,2 +10,6 @@ import { PublicKey } from '../cryptography/publickey.js'; | ||
import type { SerializedSignature } from '../cryptography/signature.js'; | ||
import { SuiGraphQLClient } from '../graphql/client.js'; | ||
import { graphql } from '../graphql/schemas/2024-01/index.js'; | ||
import { extractClaimValue } from './jwt-utils.js'; | ||
import { parseZkLoginSignature } from './signature.js'; | ||
import { toPaddedBigEndianBytes } from './utils.js'; | ||
@@ -17,3 +21,4 @@ | ||
export class ZkLoginPublicIdentifier extends PublicKey { | ||
private data: Uint8Array; | ||
#data: Uint8Array; | ||
#client?: SuiGraphQLClient; | ||
@@ -24,11 +29,13 @@ /** | ||
*/ | ||
constructor(value: PublicKeyInitData) { | ||
constructor(value: PublicKeyInitData, { client }: { client?: SuiGraphQLClient } = {}) { | ||
super(); | ||
this.#client = client; | ||
if (typeof value === 'string') { | ||
this.data = fromB64(value); | ||
this.#data = fromB64(value); | ||
} else if (value instanceof Uint8Array) { | ||
this.data = value; | ||
this.#data = value; | ||
} else { | ||
this.data = Uint8Array.from(value); | ||
this.#data = Uint8Array.from(value); | ||
} | ||
@@ -48,3 +55,3 @@ } | ||
toRawBytes(): Uint8Array { | ||
return this.data; | ||
return this.#data; | ||
} | ||
@@ -62,8 +69,39 @@ | ||
*/ | ||
async verify( | ||
_message: Uint8Array, | ||
_signature: Uint8Array | SerializedSignature, | ||
): Promise<boolean> { | ||
async verify(_message: Uint8Array, _signature: Uint8Array | string): Promise<boolean> { | ||
throw Error('does not support'); | ||
} | ||
/** | ||
* Verifies that the signature is valid for for the provided PersonalMessage | ||
*/ | ||
verifyPersonalMessage( | ||
message: Uint8Array, | ||
signature: Uint8Array | SerializedSignature, | ||
): Promise<boolean> { | ||
const parsedSignature = parseSerializedZkLoginSignature(signature); | ||
return graphqlVerifyZkLoginSignature({ | ||
address: parsedSignature.zkLogin!.address, | ||
bytes: toB64(message), | ||
signature: parsedSignature.serializedSignature, | ||
intentScope: 'PERSONAL_MESSAGE', | ||
client: this.#client, | ||
}); | ||
} | ||
/** | ||
* Verifies that the signature is valid for for the provided TransactionBlock | ||
*/ | ||
verifyTransactionBlock( | ||
transactionBlock: Uint8Array, | ||
signature: Uint8Array | SerializedSignature, | ||
): Promise<boolean> { | ||
const parsedSignature = parseSerializedZkLoginSignature(signature); | ||
return graphqlVerifyZkLoginSignature({ | ||
address: parsedSignature.zkLogin!.address, | ||
bytes: toB64(transactionBlock), | ||
signature: parsedSignature.serializedSignature, | ||
intentScope: 'TRANSACTION_DATA', | ||
client: this.#client, | ||
}); | ||
} | ||
} | ||
@@ -75,2 +113,3 @@ | ||
iss: string, | ||
options?: { client?: SuiGraphQLClient }, | ||
): ZkLoginPublicIdentifier { | ||
@@ -84,3 +123,82 @@ // Consists of iss_bytes_len || iss_bytes || padded_32_byte_address_seed. | ||
tmp.set(addressSeedBytesBigEndian, 1 + issBytes.length); | ||
return new ZkLoginPublicIdentifier(tmp); | ||
return new ZkLoginPublicIdentifier(tmp, options); | ||
} | ||
const VerifyZkLoginSignatureQuery = graphql(` | ||
query Zklogin( | ||
$bytes: Base64! | ||
$signature: Base64! | ||
$intentScope: ZkLoginIntentScope! | ||
$author: SuiAddress! | ||
) { | ||
verifyZkloginSignature( | ||
bytes: $bytes | ||
signature: $signature | ||
intentScope: $intentScope | ||
author: $author | ||
) { | ||
success | ||
errors | ||
} | ||
} | ||
`); | ||
async function graphqlVerifyZkLoginSignature({ | ||
address, | ||
bytes, | ||
signature, | ||
intentScope, | ||
client = new SuiGraphQLClient({ | ||
url: 'https://sui-mainnet.mystenlabs.com/graphql', | ||
}), | ||
}: { | ||
address: string; | ||
bytes: string; | ||
signature: string; | ||
intentScope: 'PERSONAL_MESSAGE' | 'TRANSACTION_DATA'; | ||
client?: SuiGraphQLClient; | ||
}) { | ||
const resp = await client.query({ | ||
query: VerifyZkLoginSignatureQuery, | ||
variables: { | ||
bytes, | ||
signature, | ||
intentScope, | ||
author: address, | ||
}, | ||
}); | ||
return ( | ||
resp.data?.verifyZkloginSignature.success === true && | ||
resp.data?.verifyZkloginSignature.errors.length === 0 | ||
); | ||
} | ||
export function parseSerializedZkLoginSignature(signature: Uint8Array | SerializedSignature) { | ||
const bytes = typeof signature === 'string' ? fromB64(signature) : signature; | ||
if (bytes[0] !== SIGNATURE_SCHEME_TO_FLAG.ZkLogin) { | ||
throw new Error('Invalid signature scheme'); | ||
} | ||
const signatureBytes = bytes.slice(1); | ||
const { inputs, maxEpoch, userSignature } = parseZkLoginSignature(signatureBytes); | ||
const { issBase64Details, addressSeed } = inputs; | ||
const iss = extractClaimValue<string>(issBase64Details, 'iss'); | ||
const publicIdentifer = toZkLoginPublicIdentifier(BigInt(addressSeed), iss); | ||
const address = publicIdentifer.toSuiAddress(); | ||
return { | ||
serializedSignature: toB64(bytes), | ||
signatureScheme: 'ZkLogin' as const, | ||
zkLogin: { | ||
inputs, | ||
maxEpoch, | ||
userSignature, | ||
iss, | ||
address, | ||
addressSeed: BigInt(addressSeed), | ||
}, | ||
signature: bytes, | ||
publicKey: publicIdentifer.toRawBytes(), | ||
}; | ||
} |
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 too big to display
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 too big to display
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 too big to display
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
502
3115311
58628