@mysten/sui 1.19.0 → 1.21.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/bcs/index.d.ts +1 -0
  3. package/dist/cjs/bcs/index.js +3 -1
  4. package/dist/cjs/bcs/index.js.map +2 -2
  5. package/dist/cjs/bcs/pure.d.ts +22 -0
  6. package/dist/cjs/bcs/pure.js +59 -0
  7. package/dist/cjs/bcs/pure.js.map +7 -0
  8. package/dist/cjs/keypairs/passkey/index.d.ts +1 -1
  9. package/dist/cjs/keypairs/passkey/index.js +2 -1
  10. package/dist/cjs/keypairs/passkey/index.js.map +2 -2
  11. package/dist/cjs/keypairs/passkey/keypair.d.ts +58 -4
  12. package/dist/cjs/keypairs/passkey/keypair.js +87 -4
  13. package/dist/cjs/keypairs/passkey/keypair.js.map +2 -2
  14. package/dist/cjs/keypairs/passkey/types.d.ts +12 -0
  15. package/dist/cjs/keypairs/passkey/types.js +17 -0
  16. package/dist/cjs/keypairs/passkey/types.js.map +7 -0
  17. package/dist/cjs/transactions/pure.d.ts +1 -9
  18. package/dist/cjs/transactions/pure.js +6 -36
  19. package/dist/cjs/transactions/pure.js.map +2 -2
  20. package/dist/cjs/version.d.ts +2 -2
  21. package/dist/cjs/version.js +2 -2
  22. package/dist/cjs/version.js.map +1 -1
  23. package/dist/esm/bcs/index.d.ts +1 -0
  24. package/dist/esm/bcs/index.js +5 -1
  25. package/dist/esm/bcs/index.js.map +2 -2
  26. package/dist/esm/bcs/pure.d.ts +22 -0
  27. package/dist/esm/bcs/pure.js +39 -0
  28. package/dist/esm/bcs/pure.js.map +7 -0
  29. package/dist/esm/keypairs/passkey/index.d.ts +1 -1
  30. package/dist/esm/keypairs/passkey/index.js +3 -2
  31. package/dist/esm/keypairs/passkey/index.js.map +2 -2
  32. package/dist/esm/keypairs/passkey/keypair.d.ts +58 -4
  33. package/dist/esm/keypairs/passkey/keypair.js +87 -4
  34. package/dist/esm/keypairs/passkey/keypair.js.map +2 -2
  35. package/dist/esm/keypairs/passkey/types.d.ts +12 -0
  36. package/dist/esm/keypairs/passkey/types.js +1 -0
  37. package/dist/esm/keypairs/passkey/types.js.map +7 -0
  38. package/dist/esm/transactions/pure.d.ts +1 -9
  39. package/dist/esm/transactions/pure.js +6 -36
  40. package/dist/esm/transactions/pure.js.map +2 -2
  41. package/dist/esm/version.d.ts +2 -2
  42. package/dist/esm/version.js +2 -2
  43. package/dist/esm/version.js.map +1 -1
  44. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  45. package/dist/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +1 -2
  47. package/src/bcs/index.ts +5 -0
  48. package/src/bcs/pure.ts +91 -0
  49. package/src/keypairs/passkey/index.ts +1 -1
  50. package/src/keypairs/passkey/keypair.ts +105 -8
  51. package/src/keypairs/passkey/types.ts +16 -0
  52. package/src/transactions/pure.ts +8 -76
  53. package/src/version.ts +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/transactions/pure.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isSerializedBcs } from '@mysten/bcs';\nimport type { BcsType, SerializedBcs } from '@mysten/bcs';\n\nimport { bcs } from '../bcs/index.js';\nimport type { Argument } from './data/internal.js';\n\nexport function createPure<T>(makePure: (value: SerializedBcs<any, any> | Uint8Array) => T) {\n\tfunction pure<T extends PureTypeName>(\n\t\ttype: T extends PureTypeName ? ValidPureTypeName<T> : T,\n\t\tvalue: ShapeFromPureTypeName<T>,\n\t): T;\n\n\tfunction pure(\n\t\t/**\n\t\t * The pure value, serialized to BCS. If this is a Uint8Array, then the value\n\t\t * is assumed to be raw bytes, and will be used directly.\n\t\t */\n\t\tvalue: SerializedBcs<any, any> | Uint8Array,\n\t): T;\n\n\tfunction pure(\n\t\ttypeOrSerializedValue?: PureTypeName | SerializedBcs<any, any> | Uint8Array,\n\t\tvalue?: unknown,\n\t): T {\n\t\tif (typeof typeOrSerializedValue === 'string') {\n\t\t\treturn makePure(schemaFromName(typeOrSerializedValue).serialize(value as never));\n\t\t}\n\n\t\tif (typeOrSerializedValue instanceof Uint8Array || isSerializedBcs(typeOrSerializedValue)) {\n\t\t\treturn makePure(typeOrSerializedValue);\n\t\t}\n\n\t\tthrow new Error('tx.pure must be called either a bcs type name, or a serialized bcs value');\n\t}\n\n\tpure.u8 = (value: number) => makePure(bcs.U8.serialize(value));\n\tpure.u16 = (value: number) => makePure(bcs.U16.serialize(value));\n\tpure.u32 = (value: number) => makePure(bcs.U32.serialize(value));\n\tpure.u64 = (value: bigint | number | string) => makePure(bcs.U64.serialize(value));\n\tpure.u128 = (value: bigint | number | string) => makePure(bcs.U128.serialize(value));\n\tpure.u256 = (value: bigint | number | string) => makePure(bcs.U256.serialize(value));\n\tpure.bool = (value: boolean) => makePure(bcs.Bool.serialize(value));\n\tpure.string = (value: string) => makePure(bcs.String.serialize(value));\n\tpure.address = (value: string) => makePure(bcs.Address.serialize(value));\n\tpure.id = pure.address;\n\tpure.vector = <Type extends PureTypeName>(\n\t\ttype: T extends PureTypeName ? ValidPureTypeName<Type> : Type,\n\t\tvalue: Iterable<ShapeFromPureTypeName<Type>> & { length: number },\n\t) => {\n\t\treturn makePure(bcs.vector(schemaFromName(type as BasePureType)).serialize(value as never));\n\t};\n\tpure.option = <Type extends PureTypeName>(\n\t\ttype: T extends PureTypeName ? ValidPureTypeName<Type> : Type,\n\t\tvalue: ShapeFromPureTypeName<Type> | null | undefined,\n\t) => {\n\t\treturn makePure(bcs.option(schemaFromName(type)).serialize(value as never));\n\t};\n\n\treturn pure;\n}\n\nexport type BasePureType =\n\t| 'u8'\n\t| 'u16'\n\t| 'u32'\n\t| 'u64'\n\t| 'u128'\n\t| 'u256'\n\t| 'bool'\n\t| 'id'\n\t| 'string'\n\t| 'address';\n\nexport type PureTypeName = BasePureType | `vector<${string}>` | `option<${string}>`;\nexport type ValidPureTypeName<T extends string> = T extends BasePureType\n\t? PureTypeName\n\t: T extends `vector<${infer U}>`\n\t\t? ValidPureTypeName<U>\n\t\t: T extends `option<${infer U}>`\n\t\t\t? ValidPureTypeName<U>\n\t\t\t: PureTypeValidationError<T>;\n\ntype ShapeFromPureTypeName<T extends PureTypeName> = T extends BasePureType\n\t? Parameters<ReturnType<typeof createPure<Argument>>[T]>[0]\n\t: T extends `vector<${infer U extends PureTypeName}>`\n\t\t? ShapeFromPureTypeName<U>[]\n\t\t: T extends `option<${infer U extends PureTypeName}>`\n\t\t\t? ShapeFromPureTypeName<U> | null\n\t\t\t: never;\n\ntype PureTypeValidationError<T extends string> = T & {\n\terror: `Invalid Pure type name: ${T}`;\n};\n\nfunction schemaFromName<T extends PureTypeName>(\n\tname: T extends PureTypeName ? ValidPureTypeName<T> : T,\n): BcsType<ShapeFromPureTypeName<T>> {\n\tswitch (name) {\n\t\tcase 'u8':\n\t\t\treturn bcs.u8() as never;\n\t\tcase 'u16':\n\t\t\treturn bcs.u16() as never;\n\t\tcase 'u32':\n\t\t\treturn bcs.u32() as never;\n\t\tcase 'u64':\n\t\t\treturn bcs.u64() as never;\n\t\tcase 'u128':\n\t\t\treturn bcs.u128() as never;\n\t\tcase 'u256':\n\t\t\treturn bcs.u256() as never;\n\t\tcase 'bool':\n\t\t\treturn bcs.bool() as never;\n\t\tcase 'string':\n\t\t\treturn bcs.string() as never;\n\t\tcase 'id':\n\t\tcase 'address':\n\t\t\treturn bcs.Address as never;\n\t}\n\n\tconst generic = name.match(/^(vector|option)<(.+)>$/);\n\tif (generic) {\n\t\tconst [kind, inner] = generic.slice(1);\n\t\tif (kind === 'vector') {\n\t\t\treturn bcs.vector(schemaFromName(inner as PureTypeName)) as never;\n\t\t} else {\n\t\t\treturn bcs.option(schemaFromName(inner as PureTypeName)) as never;\n\t\t}\n\t}\n\n\tthrow new Error(`Invalid Pure type name: ${name}`);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAgC;AAGhC,IAAAA,cAAoB;AAGb,SAAS,WAAc,UAA8D;AAc3F,WAAS,KACR,uBACA,OACI;AACJ,QAAI,OAAO,0BAA0B,UAAU;AAC9C,aAAO,SAAS,eAAe,qBAAqB,EAAE,UAAU,KAAc,CAAC;AAAA,IAChF;AAEA,QAAI,iCAAiC,kBAAc,4BAAgB,qBAAqB,GAAG;AAC1F,aAAO,SAAS,qBAAqB;AAAA,IACtC;AAEA,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC3F;AAEA,OAAK,KAAK,CAAC,UAAkB,SAAS,gBAAI,GAAG,UAAU,KAAK,CAAC;AAC7D,OAAK,MAAM,CAAC,UAAkB,SAAS,gBAAI,IAAI,UAAU,KAAK,CAAC;AAC/D,OAAK,MAAM,CAAC,UAAkB,SAAS,gBAAI,IAAI,UAAU,KAAK,CAAC;AAC/D,OAAK,MAAM,CAAC,UAAoC,SAAS,gBAAI,IAAI,UAAU,KAAK,CAAC;AACjF,OAAK,OAAO,CAAC,UAAoC,SAAS,gBAAI,KAAK,UAAU,KAAK,CAAC;AACnF,OAAK,OAAO,CAAC,UAAoC,SAAS,gBAAI,KAAK,UAAU,KAAK,CAAC;AACnF,OAAK,OAAO,CAAC,UAAmB,SAAS,gBAAI,KAAK,UAAU,KAAK,CAAC;AAClE,OAAK,SAAS,CAAC,UAAkB,SAAS,gBAAI,OAAO,UAAU,KAAK,CAAC;AACrE,OAAK,UAAU,CAAC,UAAkB,SAAS,gBAAI,QAAQ,UAAU,KAAK,CAAC;AACvE,OAAK,KAAK,KAAK;AACf,OAAK,SAAS,CACb,MACA,UACI;AACJ,WAAO,SAAS,gBAAI,OAAO,eAAe,IAAoB,CAAC,EAAE,UAAU,KAAc,CAAC;AAAA,EAC3F;AACA,OAAK,SAAS,CACb,MACA,UACI;AACJ,WAAO,SAAS,gBAAI,OAAO,eAAe,IAAI,CAAC,EAAE,UAAU,KAAc,CAAC;AAAA,EAC3E;AAEA,SAAO;AACR;AAmCA,SAAS,eACR,MACoC;AACpC,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO,gBAAI,GAAG;AAAA,IACf,KAAK;AACJ,aAAO,gBAAI,IAAI;AAAA,IAChB,KAAK;AACJ,aAAO,gBAAI,IAAI;AAAA,IAChB,KAAK;AACJ,aAAO,gBAAI,IAAI;AAAA,IAChB,KAAK;AACJ,aAAO,gBAAI,KAAK;AAAA,IACjB,KAAK;AACJ,aAAO,gBAAI,KAAK;AAAA,IACjB,KAAK;AACJ,aAAO,gBAAI,KAAK;AAAA,IACjB,KAAK;AACJ,aAAO,gBAAI,OAAO;AAAA,IACnB,KAAK;AAAA,IACL,KAAK;AACJ,aAAO,gBAAI;AAAA,EACb;AAEA,QAAM,UAAU,KAAK,MAAM,yBAAyB;AACpD,MAAI,SAAS;AACZ,UAAM,CAAC,MAAM,KAAK,IAAI,QAAQ,MAAM,CAAC;AACrC,QAAI,SAAS,UAAU;AACtB,aAAO,gBAAI,OAAO,eAAe,KAAqB,CAAC;AAAA,IACxD,OAAO;AACN,aAAO,gBAAI,OAAO,eAAe,KAAqB,CAAC;AAAA,IACxD;AAAA,EACD;AAEA,QAAM,IAAI,MAAM,2BAA2B,IAAI,EAAE;AAClD;",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isSerializedBcs } from '@mysten/bcs';\nimport type { SerializedBcs } from '@mysten/bcs';\n\nimport { bcs } from '../bcs/index.js';\nimport { pureBcsSchemaFromTypeName } from '../bcs/pure.js';\nimport type { PureTypeName, ShapeFromPureTypeName, ValidPureTypeName } from '../bcs/pure.js';\n\nexport function createPure<T>(makePure: (value: SerializedBcs<any, any> | Uint8Array) => T) {\n\tfunction pure<T extends PureTypeName>(\n\t\ttype: T extends PureTypeName ? ValidPureTypeName<T> : T,\n\t\tvalue: ShapeFromPureTypeName<T>,\n\t): T;\n\n\tfunction pure(\n\t\t/**\n\t\t * The pure value, serialized to BCS. If this is a Uint8Array, then the value\n\t\t * is assumed to be raw bytes, and will be used directly.\n\t\t */\n\t\tvalue: SerializedBcs<any, any> | Uint8Array,\n\t): T;\n\n\tfunction pure(\n\t\ttypeOrSerializedValue?: PureTypeName | SerializedBcs<any, any> | Uint8Array,\n\t\tvalue?: unknown,\n\t): T {\n\t\tif (typeof typeOrSerializedValue === 'string') {\n\t\t\treturn makePure(pureBcsSchemaFromTypeName(typeOrSerializedValue).serialize(value as never));\n\t\t}\n\n\t\tif (typeOrSerializedValue instanceof Uint8Array || isSerializedBcs(typeOrSerializedValue)) {\n\t\t\treturn makePure(typeOrSerializedValue);\n\t\t}\n\n\t\tthrow new Error('tx.pure must be called either a bcs type name, or a serialized bcs value');\n\t}\n\n\tpure.u8 = (value: number) => makePure(bcs.U8.serialize(value));\n\tpure.u16 = (value: number) => makePure(bcs.U16.serialize(value));\n\tpure.u32 = (value: number) => makePure(bcs.U32.serialize(value));\n\tpure.u64 = (value: bigint | number | string) => makePure(bcs.U64.serialize(value));\n\tpure.u128 = (value: bigint | number | string) => makePure(bcs.U128.serialize(value));\n\tpure.u256 = (value: bigint | number | string) => makePure(bcs.U256.serialize(value));\n\tpure.bool = (value: boolean) => makePure(bcs.Bool.serialize(value));\n\tpure.string = (value: string) => makePure(bcs.String.serialize(value));\n\tpure.address = (value: string) => makePure(bcs.Address.serialize(value));\n\tpure.id = pure.address;\n\tpure.vector = <Type extends PureTypeName>(\n\t\ttype: T extends PureTypeName ? ValidPureTypeName<Type> : Type,\n\t\tvalue: Iterable<ShapeFromPureTypeName<Type>> & { length: number },\n\t) => {\n\t\treturn makePure(\n\t\t\tbcs.vector(pureBcsSchemaFromTypeName(type as PureTypeName)).serialize(value as never),\n\t\t);\n\t};\n\tpure.option = <Type extends PureTypeName>(\n\t\ttype: T extends PureTypeName ? ValidPureTypeName<Type> : Type,\n\t\tvalue: ShapeFromPureTypeName<Type> | null | undefined,\n\t) => {\n\t\treturn makePure(bcs.option(pureBcsSchemaFromTypeName(type)).serialize(value as never));\n\t};\n\n\treturn pure;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAAgC;AAGhC,IAAAA,cAAoB;AACpB,kBAA0C;AAGnC,SAAS,WAAc,UAA8D;AAc3F,WAAS,KACR,uBACA,OACI;AACJ,QAAI,OAAO,0BAA0B,UAAU;AAC9C,aAAO,aAAS,uCAA0B,qBAAqB,EAAE,UAAU,KAAc,CAAC;AAAA,IAC3F;AAEA,QAAI,iCAAiC,kBAAc,4BAAgB,qBAAqB,GAAG;AAC1F,aAAO,SAAS,qBAAqB;AAAA,IACtC;AAEA,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC3F;AAEA,OAAK,KAAK,CAAC,UAAkB,SAAS,gBAAI,GAAG,UAAU,KAAK,CAAC;AAC7D,OAAK,MAAM,CAAC,UAAkB,SAAS,gBAAI,IAAI,UAAU,KAAK,CAAC;AAC/D,OAAK,MAAM,CAAC,UAAkB,SAAS,gBAAI,IAAI,UAAU,KAAK,CAAC;AAC/D,OAAK,MAAM,CAAC,UAAoC,SAAS,gBAAI,IAAI,UAAU,KAAK,CAAC;AACjF,OAAK,OAAO,CAAC,UAAoC,SAAS,gBAAI,KAAK,UAAU,KAAK,CAAC;AACnF,OAAK,OAAO,CAAC,UAAoC,SAAS,gBAAI,KAAK,UAAU,KAAK,CAAC;AACnF,OAAK,OAAO,CAAC,UAAmB,SAAS,gBAAI,KAAK,UAAU,KAAK,CAAC;AAClE,OAAK,SAAS,CAAC,UAAkB,SAAS,gBAAI,OAAO,UAAU,KAAK,CAAC;AACrE,OAAK,UAAU,CAAC,UAAkB,SAAS,gBAAI,QAAQ,UAAU,KAAK,CAAC;AACvE,OAAK,KAAK,KAAK;AACf,OAAK,SAAS,CACb,MACA,UACI;AACJ,WAAO;AAAA,MACN,gBAAI,WAAO,uCAA0B,IAAoB,CAAC,EAAE,UAAU,KAAc;AAAA,IACrF;AAAA,EACD;AACA,OAAK,SAAS,CACb,MACA,UACI;AACJ,WAAO,SAAS,gBAAI,WAAO,uCAA0B,IAAI,CAAC,EAAE,UAAU,KAAc,CAAC;AAAA,EACtF;AAEA,SAAO;AACR;",
6
6
  "names": ["import_bcs"]
7
7
  }
@@ -1,2 +1,2 @@
1
- export declare const PACKAGE_VERSION = "1.19.0";
2
- export declare const TARGETED_RPC_VERSION = "1.41.0";
1
+ export declare const PACKAGE_VERSION = "1.21.0";
2
+ export declare const TARGETED_RPC_VERSION = "1.42.0";
@@ -22,6 +22,6 @@ __export(version_exports, {
22
22
  TARGETED_RPC_VERSION: () => TARGETED_RPC_VERSION
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- const PACKAGE_VERSION = "1.19.0";
26
- const TARGETED_RPC_VERSION = "1.41.0";
25
+ const PACKAGE_VERSION = "1.21.0";
26
+ const TARGETED_RPC_VERSION = "1.42.0";
27
27
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/version.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '1.19.0';\nexport const TARGETED_RPC_VERSION = '1.41.0';\n"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '1.21.0';\nexport const TARGETED_RPC_VERSION = '1.42.0';\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,MAAM,kBAAkB;AACxB,MAAM,uBAAuB;",
6
6
  "names": []
7
7
  }
@@ -3143,4 +3143,5 @@ declare const suiBcs: {
3143
3143
  map<K, V, InputK = K, InputV = V>(keyType: import("@mysten/bcs").BcsType<K, InputK>, valueType: import("@mysten/bcs").BcsType<V, InputV>): import("@mysten/bcs").BcsType<Map<K, V>, Map<InputK, InputV>>;
3144
3144
  lazy<T extends import("@mysten/bcs").BcsType<any>>(cb: () => T): T;
3145
3145
  };
3146
+ export { pureBcsSchemaFromTypeName, type ShapeFromPureTypeName, type PureTypeName, } from './pure.js';
3146
3147
  export { suiBcs as bcs };
@@ -77,9 +77,13 @@ const suiBcs = {
77
77
  TransactionEffects,
78
78
  PasskeyAuthenticator
79
79
  };
80
+ import {
81
+ pureBcsSchemaFromTypeName
82
+ } from "./pure.js";
80
83
  export {
81
84
  BcsType,
82
85
  TypeTagSerializer,
83
- suiBcs as bcs
86
+ suiBcs as bcs,
87
+ pureBcsSchemaFromTypeName
84
88
  };
85
89
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/bcs/index.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { bcs } from '@mysten/bcs';\n\nimport {\n\tAddress,\n\tAppId,\n\tArgument,\n\tCallArg,\n\tCommand,\n\tCompressedSignature,\n\tGasData,\n\tIntent,\n\tIntentMessage,\n\tIntentScope,\n\tIntentVersion,\n\tMultiSig,\n\tMultiSigPkMap,\n\tMultiSigPublicKey,\n\tObjectArg,\n\tObjectDigest,\n\tPasskeyAuthenticator,\n\tProgrammableMoveCall,\n\tProgrammableTransaction,\n\tPublicKey,\n\tSenderSignedData,\n\tSenderSignedTransaction,\n\tSharedObjectRef,\n\tStructTag,\n\tSuiObjectRef,\n\tTransactionData,\n\tTransactionDataV1,\n\tTransactionExpiration,\n\tTransactionKind,\n\tTypeTag,\n} from './bcs.js';\nimport { TransactionEffects } from './effects.js';\n\nexport type { TypeTag } from './types.js';\n\nexport { TypeTagSerializer } from './type-tag-serializer.js';\nexport { BcsType, type BcsTypeOptions } from '@mysten/bcs';\n\nconst suiBcs = {\n\t...bcs,\n\tU8: bcs.u8(),\n\tU16: bcs.u16(),\n\tU32: bcs.u32(),\n\tU64: bcs.u64(),\n\tU128: bcs.u128(),\n\tU256: bcs.u256(),\n\tULEB128: bcs.uleb128(),\n\tBool: bcs.bool(),\n\tString: bcs.string(),\n\tAddress,\n\tAppId,\n\tArgument,\n\tCallArg,\n\tCompressedSignature,\n\tGasData,\n\tIntent,\n\tIntentMessage,\n\tIntentScope,\n\tIntentVersion,\n\tMultiSig,\n\tMultiSigPkMap,\n\tMultiSigPublicKey,\n\tObjectArg,\n\tObjectDigest,\n\tProgrammableMoveCall,\n\tProgrammableTransaction,\n\tPublicKey,\n\tSenderSignedData,\n\tSenderSignedTransaction,\n\tSharedObjectRef,\n\tStructTag,\n\tSuiObjectRef,\n\tCommand,\n\tTransactionData,\n\tTransactionDataV1,\n\tTransactionExpiration,\n\tTransactionKind,\n\tTypeTag,\n\tTransactionEffects,\n\tPasskeyAuthenticator,\n};\n\nexport { suiBcs as bcs };\n"],
5
- "mappings": "AAGA,SAAS,WAAW;AAEpB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,0BAA0B;AAInC,SAAS,yBAAyB;AAClC,SAAS,eAAoC;AAE7C,MAAM,SAAS;AAAA,EACd,GAAG;AAAA,EACH,IAAI,IAAI,GAAG;AAAA,EACX,KAAK,IAAI,IAAI;AAAA,EACb,KAAK,IAAI,IAAI;AAAA,EACb,KAAK,IAAI,IAAI;AAAA,EACb,MAAM,IAAI,KAAK;AAAA,EACf,MAAM,IAAI,KAAK;AAAA,EACf,SAAS,IAAI,QAAQ;AAAA,EACrB,MAAM,IAAI,KAAK;AAAA,EACf,QAAQ,IAAI,OAAO;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { bcs } from '@mysten/bcs';\n\nimport {\n\tAddress,\n\tAppId,\n\tArgument,\n\tCallArg,\n\tCommand,\n\tCompressedSignature,\n\tGasData,\n\tIntent,\n\tIntentMessage,\n\tIntentScope,\n\tIntentVersion,\n\tMultiSig,\n\tMultiSigPkMap,\n\tMultiSigPublicKey,\n\tObjectArg,\n\tObjectDigest,\n\tPasskeyAuthenticator,\n\tProgrammableMoveCall,\n\tProgrammableTransaction,\n\tPublicKey,\n\tSenderSignedData,\n\tSenderSignedTransaction,\n\tSharedObjectRef,\n\tStructTag,\n\tSuiObjectRef,\n\tTransactionData,\n\tTransactionDataV1,\n\tTransactionExpiration,\n\tTransactionKind,\n\tTypeTag,\n} from './bcs.js';\nimport { TransactionEffects } from './effects.js';\n\nexport type { TypeTag } from './types.js';\n\nexport { TypeTagSerializer } from './type-tag-serializer.js';\nexport { BcsType, type BcsTypeOptions } from '@mysten/bcs';\n\nconst suiBcs = {\n\t...bcs,\n\tU8: bcs.u8(),\n\tU16: bcs.u16(),\n\tU32: bcs.u32(),\n\tU64: bcs.u64(),\n\tU128: bcs.u128(),\n\tU256: bcs.u256(),\n\tULEB128: bcs.uleb128(),\n\tBool: bcs.bool(),\n\tString: bcs.string(),\n\tAddress,\n\tAppId,\n\tArgument,\n\tCallArg,\n\tCompressedSignature,\n\tGasData,\n\tIntent,\n\tIntentMessage,\n\tIntentScope,\n\tIntentVersion,\n\tMultiSig,\n\tMultiSigPkMap,\n\tMultiSigPublicKey,\n\tObjectArg,\n\tObjectDigest,\n\tProgrammableMoveCall,\n\tProgrammableTransaction,\n\tPublicKey,\n\tSenderSignedData,\n\tSenderSignedTransaction,\n\tSharedObjectRef,\n\tStructTag,\n\tSuiObjectRef,\n\tCommand,\n\tTransactionData,\n\tTransactionDataV1,\n\tTransactionExpiration,\n\tTransactionKind,\n\tTypeTag,\n\tTransactionEffects,\n\tPasskeyAuthenticator,\n};\nexport {\n\tpureBcsSchemaFromTypeName,\n\ttype ShapeFromPureTypeName,\n\ttype PureTypeName,\n} from './pure.js';\n\nexport { suiBcs as bcs };\n"],
5
+ "mappings": "AAGA,SAAS,WAAW;AAEpB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,0BAA0B;AAInC,SAAS,yBAAyB;AAClC,SAAS,eAAoC;AAE7C,MAAM,SAAS;AAAA,EACd,GAAG;AAAA,EACH,IAAI,IAAI,GAAG;AAAA,EACX,KAAK,IAAI,IAAI;AAAA,EACb,KAAK,IAAI,IAAI;AAAA,EACb,KAAK,IAAI,IAAI;AAAA,EACb,MAAM,IAAI,KAAK;AAAA,EACf,MAAM,IAAI,KAAK;AAAA,EACf,SAAS,IAAI,QAAQ;AAAA,EACrB,MAAM,IAAI,KAAK;AAAA,EACf,QAAQ,IAAI,OAAO;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AACA;AAAA,EACC;AAAA,OAGM;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,22 @@
1
+ import type { BcsType } from '@mysten/bcs';
2
+ export type BasePureType = 'u8' | 'u16' | 'u32' | 'u64' | 'u128' | 'u256' | 'bool' | 'id' | 'string' | 'address';
3
+ interface PureShapeByType {
4
+ u8: number;
5
+ u16: number;
6
+ u32: number;
7
+ u64: bigint | string | number;
8
+ u128: bigint | string | number;
9
+ u256: bigint | string | number;
10
+ bool: boolean;
11
+ string: string;
12
+ id: string | Uint8Array;
13
+ address: string | Uint8Array;
14
+ }
15
+ export type PureTypeName = BasePureType | `vector<${string}>` | `option<${string}>`;
16
+ export type ValidPureTypeName<T extends string> = T extends BasePureType ? PureTypeName : T extends `vector<${infer U}>` ? ValidPureTypeName<U> : T extends `option<${infer U}>` ? ValidPureTypeName<U> : PureTypeValidationError<T>;
17
+ export type ShapeFromPureTypeName<T extends PureTypeName> = T extends BasePureType ? PureShapeByType[T] : T extends `vector<${infer U extends PureTypeName}>` ? ShapeFromPureTypeName<U>[] : T extends `option<${infer U extends PureTypeName}>` ? ShapeFromPureTypeName<U> | null : never;
18
+ type PureTypeValidationError<T extends string> = T & {
19
+ error: `Invalid Pure type name: ${T}`;
20
+ };
21
+ export declare function pureBcsSchemaFromTypeName<T extends PureTypeName>(name: T extends PureTypeName ? ValidPureTypeName<T> : T): BcsType<ShapeFromPureTypeName<T>>;
22
+ export {};
@@ -0,0 +1,39 @@
1
+ import { bcs } from "@mysten/bcs";
2
+ import { Address } from "./bcs.js";
3
+ function pureBcsSchemaFromTypeName(name) {
4
+ switch (name) {
5
+ case "u8":
6
+ return bcs.u8();
7
+ case "u16":
8
+ return bcs.u16();
9
+ case "u32":
10
+ return bcs.u32();
11
+ case "u64":
12
+ return bcs.u64();
13
+ case "u128":
14
+ return bcs.u128();
15
+ case "u256":
16
+ return bcs.u256();
17
+ case "bool":
18
+ return bcs.bool();
19
+ case "string":
20
+ return bcs.string();
21
+ case "id":
22
+ case "address":
23
+ return Address;
24
+ }
25
+ const generic = name.match(/^(vector|option)<(.+)>$/);
26
+ if (generic) {
27
+ const [kind, inner] = generic.slice(1);
28
+ if (kind === "vector") {
29
+ return bcs.vector(pureBcsSchemaFromTypeName(inner));
30
+ } else {
31
+ return bcs.option(pureBcsSchemaFromTypeName(inner));
32
+ }
33
+ }
34
+ throw new Error(`Invalid Pure type name: ${name}`);
35
+ }
36
+ export {
37
+ pureBcsSchemaFromTypeName
38
+ };
39
+ //# sourceMappingURL=pure.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/bcs/pure.ts"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { bcs } from '@mysten/bcs';\nimport type { BcsType } from '@mysten/bcs';\n\nimport { Address } from './bcs.js';\n\nexport type BasePureType =\n\t| 'u8'\n\t| 'u16'\n\t| 'u32'\n\t| 'u64'\n\t| 'u128'\n\t| 'u256'\n\t| 'bool'\n\t| 'id'\n\t| 'string'\n\t| 'address';\n\ninterface PureShapeByType {\n\tu8: number;\n\tu16: number;\n\tu32: number;\n\tu64: bigint | string | number;\n\tu128: bigint | string | number;\n\tu256: bigint | string | number;\n\tbool: boolean;\n\tstring: string;\n\tid: string | Uint8Array;\n\taddress: string | Uint8Array;\n}\n\nexport type PureTypeName = BasePureType | `vector<${string}>` | `option<${string}>`;\nexport type ValidPureTypeName<T extends string> = T extends BasePureType\n\t? PureTypeName\n\t: T extends `vector<${infer U}>`\n\t\t? ValidPureTypeName<U>\n\t\t: T extends `option<${infer U}>`\n\t\t\t? ValidPureTypeName<U>\n\t\t\t: PureTypeValidationError<T>;\n\nexport type ShapeFromPureTypeName<T extends PureTypeName> = T extends BasePureType\n\t? PureShapeByType[T]\n\t: T extends `vector<${infer U extends PureTypeName}>`\n\t\t? ShapeFromPureTypeName<U>[]\n\t\t: T extends `option<${infer U extends PureTypeName}>`\n\t\t\t? ShapeFromPureTypeName<U> | null\n\t\t\t: never;\n\ntype PureTypeValidationError<T extends string> = T & {\n\terror: `Invalid Pure type name: ${T}`;\n};\n\nexport function pureBcsSchemaFromTypeName<T extends PureTypeName>(\n\tname: T extends PureTypeName ? ValidPureTypeName<T> : T,\n): BcsType<ShapeFromPureTypeName<T>> {\n\tswitch (name) {\n\t\tcase 'u8':\n\t\t\treturn bcs.u8() as never;\n\t\tcase 'u16':\n\t\t\treturn bcs.u16() as never;\n\t\tcase 'u32':\n\t\t\treturn bcs.u32() as never;\n\t\tcase 'u64':\n\t\t\treturn bcs.u64() as never;\n\t\tcase 'u128':\n\t\t\treturn bcs.u128() as never;\n\t\tcase 'u256':\n\t\t\treturn bcs.u256() as never;\n\t\tcase 'bool':\n\t\t\treturn bcs.bool() as never;\n\t\tcase 'string':\n\t\t\treturn bcs.string() as never;\n\t\tcase 'id':\n\t\tcase 'address':\n\t\t\treturn Address as never;\n\t}\n\n\tconst generic = name.match(/^(vector|option)<(.+)>$/);\n\tif (generic) {\n\t\tconst [kind, inner] = generic.slice(1);\n\t\tif (kind === 'vector') {\n\t\t\treturn bcs.vector(pureBcsSchemaFromTypeName(inner as PureTypeName)) as never;\n\t\t} else {\n\t\t\treturn bcs.option(pureBcsSchemaFromTypeName(inner as PureTypeName)) as never;\n\t\t}\n\t}\n\n\tthrow new Error(`Invalid Pure type name: ${name}`);\n}\n"],
5
+ "mappings": "AAGA,SAAS,WAAW;AAGpB,SAAS,eAAe;AAgDjB,SAAS,0BACf,MACoC;AACpC,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO,IAAI,GAAG;AAAA,IACf,KAAK;AACJ,aAAO,IAAI,IAAI;AAAA,IAChB,KAAK;AACJ,aAAO,IAAI,IAAI;AAAA,IAChB,KAAK;AACJ,aAAO,IAAI,IAAI;AAAA,IAChB,KAAK;AACJ,aAAO,IAAI,KAAK;AAAA,IACjB,KAAK;AACJ,aAAO,IAAI,KAAK;AAAA,IACjB,KAAK;AACJ,aAAO,IAAI,KAAK;AAAA,IACjB,KAAK;AACJ,aAAO,IAAI,OAAO;AAAA,IACnB,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,EACT;AAEA,QAAM,UAAU,KAAK,MAAM,yBAAyB;AACpD,MAAI,SAAS;AACZ,UAAM,CAAC,MAAM,KAAK,IAAI,QAAQ,MAAM,CAAC;AACrC,QAAI,SAAS,UAAU;AACtB,aAAO,IAAI,OAAO,0BAA0B,KAAqB,CAAC;AAAA,IACnE,OAAO;AACN,aAAO,IAAI,OAAO,0BAA0B,KAAqB,CAAC;AAAA,IACnE;AAAA,EACD;AAEA,QAAM,IAAI,MAAM,2BAA2B,IAAI,EAAE;AAClD;",
6
+ "names": []
7
+ }
@@ -1,3 +1,3 @@
1
- export { PasskeyKeypair, BrowserPasskeyProvider } from './keypair.js';
1
+ export { PasskeyKeypair, BrowserPasskeyProvider, findCommonPublicKey } from './keypair.js';
2
2
  export type { PasskeyProvider, BrowserPasswordProviderOptions } from './keypair.js';
3
3
  export { PasskeyPublicKey } from './publickey.js';
@@ -1,8 +1,9 @@
1
- import { PasskeyKeypair, BrowserPasskeyProvider } from "./keypair.js";
1
+ import { PasskeyKeypair, BrowserPasskeyProvider, findCommonPublicKey } from "./keypair.js";
2
2
  import { PasskeyPublicKey } from "./publickey.js";
3
3
  export {
4
4
  BrowserPasskeyProvider,
5
5
  PasskeyKeypair,
6
- PasskeyPublicKey
6
+ PasskeyPublicKey,
7
+ findCommonPublicKey
7
8
  };
8
9
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/keypairs/passkey/index.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nexport { PasskeyKeypair, BrowserPasskeyProvider } from './keypair.js';\nexport type { PasskeyProvider, BrowserPasswordProviderOptions } from './keypair.js';\nexport { PasskeyPublicKey } from './publickey.js';\n"],
5
- "mappings": "AAEA,SAAS,gBAAgB,8BAA8B;AAEvD,SAAS,wBAAwB;",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nexport { PasskeyKeypair, BrowserPasskeyProvider, findCommonPublicKey } from './keypair.js';\nexport type { PasskeyProvider, BrowserPasswordProviderOptions } from './keypair.js';\nexport { PasskeyPublicKey } from './publickey.js';\n"],
5
+ "mappings": "AAEA,SAAS,gBAAgB,wBAAwB,2BAA2B;AAE5E,SAAS,wBAAwB;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- import type { AuthenticationCredential, RegistrationCredential } from '@simplewebauthn/typescript-types';
2
1
  import type { IntentScope, SignatureWithBytes } from '../../cryptography/index.js';
3
2
  import { Signer } from '../../cryptography/index.js';
4
3
  import type { PublicKey } from '../../cryptography/publickey.js';
5
4
  import type { SignatureScheme } from '../../cryptography/signature-scheme.js';
5
+ import type { AuthenticationCredential, RegistrationCredential } from './types.js';
6
6
  type DeepPartialConfigKeys = 'rp' | 'user' | 'authenticatorSelection';
7
7
  type DeepPartial<T> = T extends object ? {
8
8
  [P in keyof T]?: DeepPartial<T[P]>;
@@ -30,15 +30,27 @@ export declare class PasskeyKeypair extends Signer {
30
30
  */
31
31
  getKeyScheme(): SignatureScheme;
32
32
  /**
33
- * Creates an instance of Passkey signer. It's expected to call the static `getPasskeyInstance` method to create an instance.
34
- * For example:
33
+ * Creates an instance of Passkey signer. If no passkey wallet had created before,
34
+ * use `getPasskeyInstance`. For example:
35
35
  * ```
36
- * const signer = await PasskeyKeypair.getPasskeyInstance();
36
+ * let provider = new BrowserPasskeyProvider('Sui Passkey Example',{
37
+ * rpName: 'Sui Passkey Example',
38
+ * rpId: window.location.hostname,
39
+ * } as BrowserPasswordProviderOptions);
40
+ * const signer = await PasskeyKeypair.getPasskeyInstance(provider);
37
41
  * ```
42
+ *
43
+ * If there are existing passkey wallet, use `signAndRecover` to identify the correct
44
+ * public key and then initialize the instance. See usage in `signAndRecover`.
38
45
  */
39
46
  constructor(publicKey: Uint8Array, provider: PasskeyProvider);
40
47
  /**
41
48
  * Creates an instance of Passkey signer invoking the passkey from navigator.
49
+ * Note that this will invoke the passkey device to create a fresh credential.
50
+ * Should only be called if passkey wallet is created for the first time.
51
+ *
52
+ * @param provider - the passkey provider.
53
+ * @returns the passkey instance.
42
54
  */
43
55
  static getPasskeyInstance(provider: PasskeyProvider): Promise<PasskeyKeypair>;
44
56
  /**
@@ -55,5 +67,47 @@ export declare class PasskeyKeypair extends Signer {
55
67
  * digest of the intent message, then serialize it with the passkey flag.
56
68
  */
57
69
  signWithIntent(bytes: Uint8Array, intent: IntentScope): Promise<SignatureWithBytes>;
70
+ /**
71
+ * Given a message, asks the passkey device to sign it and return all (up to 4) possible public keys.
72
+ * See: https://bitcoin.stackexchange.com/questions/81232/how-is-public-key-extracted-from-message-digital-signature-address
73
+ *
74
+ * This is useful if the user previously created passkey wallet with the origin, but the wallet session
75
+ * does not have the public key / address. By calling this method twice with two different messages, the
76
+ * wallet can compare the returned public keys and uniquely identify the previously created passkey wallet
77
+ * using `findCommonPublicKey`.
78
+ *
79
+ * Alternatively, one call can be made and all possible public keys should be checked onchain to see if
80
+ * there is any assets.
81
+ *
82
+ * Once the correct public key is identified, a passkey instance can then be initialized with this public key.
83
+ *
84
+ * Example usage to recover wallet with two signing calls:
85
+ * ```
86
+ * let provider = new BrowserPasskeyProvider('Sui Passkey Example',{
87
+ * rpName: 'Sui Passkey Example',
88
+ * rpId: window.location.hostname,
89
+ * } as BrowserPasswordProviderOptions);
90
+ * const testMessage = new TextEncoder().encode('Hello world!');
91
+ * const possiblePks = await PasskeyKeypair.signAndRecover(provider, testMessage);
92
+ * const testMessage2 = new TextEncoder().encode('Hello world 2!');
93
+ * const possiblePks2 = await PasskeyKeypair.signAndRecover(provider, testMessage2);
94
+ * const commonPk = findCommonPublicKey(possiblePks, possiblePks2);
95
+ * const signer = new PasskeyKeypair(provider, commonPk.toRawBytes());
96
+ * ```
97
+ *
98
+ * @param provider - the passkey provider.
99
+ * @param message - the message to sign.
100
+ * @returns all possible public keys.
101
+ */
102
+ static signAndRecover(provider: PasskeyProvider, message: Uint8Array): Promise<PublicKey[]>;
58
103
  }
104
+ /**
105
+ * Finds the unique public key that exists in both arrays, throws error if the common
106
+ * pubkey does not equal to one.
107
+ *
108
+ * @param arr1 - The first pubkeys array.
109
+ * @param arr2 - The second pubkeys array.
110
+ * @returns The only common pubkey in both arrays.
111
+ */
112
+ export declare function findCommonPublicKey(arr1: PublicKey[], arr2: PublicKey[]): PublicKey;
59
113
  export {};
@@ -9,6 +9,7 @@ var _name, _options;
9
9
  import { toBase64 } from "@mysten/bcs";
10
10
  import { secp256r1 } from "@noble/curves/p256";
11
11
  import { blake2b } from "@noble/hashes/blake2b";
12
+ import { sha256 } from "@noble/hashes/sha256";
12
13
  import { randomBytes } from "@noble/hashes/utils";
13
14
  import { PasskeyAuthenticator } from "../../bcs/bcs.js";
14
15
  import { messageWithIntent, SIGNATURE_SCHEME_TO_FLAG, Signer } from "../../cryptography/index.js";
@@ -72,11 +73,18 @@ class PasskeyKeypair extends Signer {
72
73
  return "Passkey";
73
74
  }
74
75
  /**
75
- * Creates an instance of Passkey signer. It's expected to call the static `getPasskeyInstance` method to create an instance.
76
- * For example:
76
+ * Creates an instance of Passkey signer. If no passkey wallet had created before,
77
+ * use `getPasskeyInstance`. For example:
77
78
  * ```
78
- * const signer = await PasskeyKeypair.getPasskeyInstance();
79
+ * let provider = new BrowserPasskeyProvider('Sui Passkey Example',{
80
+ * rpName: 'Sui Passkey Example',
81
+ * rpId: window.location.hostname,
82
+ * } as BrowserPasswordProviderOptions);
83
+ * const signer = await PasskeyKeypair.getPasskeyInstance(provider);
79
84
  * ```
85
+ *
86
+ * If there are existing passkey wallet, use `signAndRecover` to identify the correct
87
+ * public key and then initialize the instance. See usage in `signAndRecover`.
80
88
  */
81
89
  constructor(publicKey, provider) {
82
90
  super();
@@ -85,6 +93,11 @@ class PasskeyKeypair extends Signer {
85
93
  }
86
94
  /**
87
95
  * Creates an instance of Passkey signer invoking the passkey from navigator.
96
+ * Note that this will invoke the passkey device to create a fresh credential.
97
+ * Should only be called if passkey wallet is created for the first time.
98
+ *
99
+ * @param provider - the passkey provider.
100
+ * @returns the passkey instance.
88
101
  */
89
102
  static async getPasskeyInstance(provider) {
90
103
  const credential = await provider.create();
@@ -145,9 +158,79 @@ class PasskeyKeypair extends Signer {
145
158
  bytes: toBase64(bytes)
146
159
  };
147
160
  }
161
+ /**
162
+ * Given a message, asks the passkey device to sign it and return all (up to 4) possible public keys.
163
+ * See: https://bitcoin.stackexchange.com/questions/81232/how-is-public-key-extracted-from-message-digital-signature-address
164
+ *
165
+ * This is useful if the user previously created passkey wallet with the origin, but the wallet session
166
+ * does not have the public key / address. By calling this method twice with two different messages, the
167
+ * wallet can compare the returned public keys and uniquely identify the previously created passkey wallet
168
+ * using `findCommonPublicKey`.
169
+ *
170
+ * Alternatively, one call can be made and all possible public keys should be checked onchain to see if
171
+ * there is any assets.
172
+ *
173
+ * Once the correct public key is identified, a passkey instance can then be initialized with this public key.
174
+ *
175
+ * Example usage to recover wallet with two signing calls:
176
+ * ```
177
+ * let provider = new BrowserPasskeyProvider('Sui Passkey Example',{
178
+ * rpName: 'Sui Passkey Example',
179
+ * rpId: window.location.hostname,
180
+ * } as BrowserPasswordProviderOptions);
181
+ * const testMessage = new TextEncoder().encode('Hello world!');
182
+ * const possiblePks = await PasskeyKeypair.signAndRecover(provider, testMessage);
183
+ * const testMessage2 = new TextEncoder().encode('Hello world 2!');
184
+ * const possiblePks2 = await PasskeyKeypair.signAndRecover(provider, testMessage2);
185
+ * const commonPk = findCommonPublicKey(possiblePks, possiblePks2);
186
+ * const signer = new PasskeyKeypair(provider, commonPk.toRawBytes());
187
+ * ```
188
+ *
189
+ * @param provider - the passkey provider.
190
+ * @param message - the message to sign.
191
+ * @returns all possible public keys.
192
+ */
193
+ static async signAndRecover(provider, message) {
194
+ const credential = await provider.get(message);
195
+ const fullMessage = messageFromAssertionResponse(credential.response);
196
+ const sig = secp256r1.Signature.fromDER(new Uint8Array(credential.response.signature));
197
+ const res = [];
198
+ for (let i = 0; i < 4; i++) {
199
+ const s = sig.addRecoveryBit(i);
200
+ try {
201
+ const pubkey = s.recoverPublicKey(sha256(fullMessage));
202
+ const pk = new PasskeyPublicKey(pubkey.toRawBytes(true));
203
+ res.push(pk);
204
+ } catch {
205
+ continue;
206
+ }
207
+ }
208
+ return res;
209
+ }
210
+ }
211
+ function findCommonPublicKey(arr1, arr2) {
212
+ const matchingPubkeys = [];
213
+ for (const pubkey1 of arr1) {
214
+ for (const pubkey2 of arr2) {
215
+ if (pubkey1.equals(pubkey2)) {
216
+ matchingPubkeys.push(pubkey1);
217
+ }
218
+ }
219
+ }
220
+ if (matchingPubkeys.length !== 1) {
221
+ throw new Error("No unique public key found");
222
+ }
223
+ return matchingPubkeys[0];
224
+ }
225
+ function messageFromAssertionResponse(response) {
226
+ const authenticatorData = new Uint8Array(response.authenticatorData);
227
+ const clientDataJSON = new Uint8Array(response.clientDataJSON);
228
+ const clientDataJSONDigest = sha256(clientDataJSON);
229
+ return new Uint8Array([...authenticatorData, ...clientDataJSONDigest]);
148
230
  }
149
231
  export {
150
232
  BrowserPasskeyProvider,
151
- PasskeyKeypair
233
+ PasskeyKeypair,
234
+ findCommonPublicKey
152
235
  };
153
236
  //# sourceMappingURL=keypair.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/keypairs/passkey/keypair.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toBase64 } from '@mysten/bcs';\nimport { secp256r1 } from '@noble/curves/p256';\nimport { blake2b } from '@noble/hashes/blake2b';\nimport { randomBytes } from '@noble/hashes/utils';\nimport type {\n\tAuthenticationCredential,\n\tRegistrationCredential,\n} from '@simplewebauthn/typescript-types';\n\nimport { PasskeyAuthenticator } from '../../bcs/bcs.js';\nimport type { IntentScope, SignatureWithBytes } from '../../cryptography/index.js';\nimport { messageWithIntent, SIGNATURE_SCHEME_TO_FLAG, Signer } from '../../cryptography/index.js';\nimport type { PublicKey } from '../../cryptography/publickey.js';\nimport type { SignatureScheme } from '../../cryptography/signature-scheme.js';\nimport {\n\tparseDerSPKI,\n\tPASSKEY_PUBLIC_KEY_SIZE,\n\tPASSKEY_SIGNATURE_SIZE,\n\tPasskeyPublicKey,\n} from './publickey.js';\n\ntype DeepPartialConfigKeys = 'rp' | 'user' | 'authenticatorSelection';\n\ntype DeepPartial<T> = T extends object\n\t? {\n\t\t\t[P in keyof T]?: DeepPartial<T[P]>;\n\t\t}\n\t: T;\n\nexport type BrowserPasswordProviderOptions = Pick<\n\tDeepPartial<PublicKeyCredentialCreationOptions>,\n\tDeepPartialConfigKeys\n> &\n\tOmit<\n\t\tPartial<PublicKeyCredentialCreationOptions>,\n\t\tDeepPartialConfigKeys | 'pubKeyCredParams' | 'challenge'\n\t>;\n\nexport interface PasskeyProvider {\n\tcreate(): Promise<RegistrationCredential>;\n\tget(challenge: Uint8Array): Promise<AuthenticationCredential>;\n}\n\n// Default browser implementation\nexport class BrowserPasskeyProvider implements PasskeyProvider {\n\t#name: string;\n\t#options: BrowserPasswordProviderOptions;\n\n\tconstructor(name: string, options: BrowserPasswordProviderOptions) {\n\t\tthis.#name = name;\n\t\tthis.#options = options;\n\t}\n\n\tasync create(): Promise<RegistrationCredential> {\n\t\treturn (await navigator.credentials.create({\n\t\t\tpublicKey: {\n\t\t\t\ttimeout: this.#options.timeout ?? 60000,\n\t\t\t\t...this.#options,\n\t\t\t\trp: {\n\t\t\t\t\tname: this.#name,\n\t\t\t\t\t...this.#options.rp,\n\t\t\t\t},\n\t\t\t\tuser: {\n\t\t\t\t\tname: this.#name,\n\t\t\t\t\tdisplayName: this.#name,\n\t\t\t\t\t...this.#options.user,\n\t\t\t\t\tid: randomBytes(10),\n\t\t\t\t},\n\t\t\t\tchallenge: new TextEncoder().encode('Create passkey wallet on Sui'),\n\t\t\t\tpubKeyCredParams: [{ alg: -7, type: 'public-key' }],\n\t\t\t\tauthenticatorSelection: {\n\t\t\t\t\tauthenticatorAttachment: 'cross-platform',\n\t\t\t\t\tresidentKey: 'required',\n\t\t\t\t\trequireResidentKey: true,\n\t\t\t\t\tuserVerification: 'required',\n\t\t\t\t\t...this.#options.authenticatorSelection,\n\t\t\t\t},\n\t\t\t},\n\t\t})) as RegistrationCredential;\n\t}\n\n\tasync get(challenge: Uint8Array): Promise<AuthenticationCredential> {\n\t\treturn (await navigator.credentials.get({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge,\n\t\t\t\tuserVerification: this.#options.authenticatorSelection?.userVerification || 'required',\n\t\t\t\ttimeout: this.#options.timeout ?? 60000,\n\t\t\t},\n\t\t})) as AuthenticationCredential;\n\t}\n}\n\n/**\n * @experimental\n * A passkey signer used for signing transactions. This is a client side implementation for [SIP-9](https://github.com/sui-foundation/sips/blob/main/sips/sip-9.md).\n */\nexport class PasskeyKeypair extends Signer {\n\tprivate publicKey: Uint8Array;\n\tprivate provider: PasskeyProvider;\n\n\t/**\n\t * Get the key scheme of passkey,\n\t */\n\tgetKeyScheme(): SignatureScheme {\n\t\treturn 'Passkey';\n\t}\n\n\t/**\n\t * Creates an instance of Passkey signer. It's expected to call the static `getPasskeyInstance` method to create an instance.\n\t * For example:\n\t * ```\n\t * const signer = await PasskeyKeypair.getPasskeyInstance();\n\t * ```\n\t */\n\tconstructor(publicKey: Uint8Array, provider: PasskeyProvider) {\n\t\tsuper();\n\t\tthis.publicKey = publicKey;\n\t\tthis.provider = provider;\n\t}\n\n\t/**\n\t * Creates an instance of Passkey signer invoking the passkey from navigator.\n\t */\n\tstatic async getPasskeyInstance(provider: PasskeyProvider): Promise<PasskeyKeypair> {\n\t\t// create a passkey secp256r1 with the provider.\n\t\tconst credential = await provider.create();\n\n\t\tif (!credential.response.getPublicKey()) {\n\t\t\tthrow new Error('Invalid credential create response');\n\t\t} else {\n\t\t\tconst derSPKI = credential.response.getPublicKey()!;\n\t\t\tconst pubkeyUncompressed = parseDerSPKI(new Uint8Array(derSPKI));\n\t\t\tconst pubkey = secp256r1.ProjectivePoint.fromHex(pubkeyUncompressed);\n\t\t\tconst pubkeyCompressed = pubkey.toRawBytes(true);\n\t\t\treturn new PasskeyKeypair(pubkeyCompressed, provider);\n\t\t}\n\t}\n\n\t/**\n\t * Return the public key for this passkey.\n\t */\n\tgetPublicKey(): PublicKey {\n\t\treturn new PasskeyPublicKey(this.publicKey);\n\t}\n\n\t/**\n\t * Return the signature for the provided data (i.e. blake2b(intent_message)).\n\t * This is sent to passkey as the challenge field.\n\t */\n\tasync sign(data: Uint8Array) {\n\t\t// sendss the passkey to sign over challenge as the data.\n\t\tconst credential = await this.provider.get(data);\n\n\t\t// parse authenticatorData (as bytes), clientDataJSON (decoded as string).\n\t\tconst authenticatorData = new Uint8Array(credential.response.authenticatorData);\n\t\tconst clientDataJSON = new Uint8Array(credential.response.clientDataJSON); // response.clientDataJSON is already UTF-8 encoded JSON\n\t\tconst decoder = new TextDecoder();\n\t\tconst clientDataJSONString: string = decoder.decode(clientDataJSON);\n\n\t\t// parse the signature from DER format, normalize and convert to compressed format (33 bytes).\n\t\tconst sig = secp256r1.Signature.fromDER(new Uint8Array(credential.response.signature));\n\t\tconst normalized = sig.normalizeS().toCompactRawBytes();\n\n\t\tif (\n\t\t\tnormalized.length !== PASSKEY_SIGNATURE_SIZE ||\n\t\t\tthis.publicKey.length !== PASSKEY_PUBLIC_KEY_SIZE\n\t\t) {\n\t\t\tthrow new Error('Invalid signature or public key length');\n\t\t}\n\n\t\t// construct userSignature as flag || sig || pubkey for the secp256r1 signature.\n\t\tconst arr = new Uint8Array(1 + normalized.length + this.publicKey.length);\n\t\tarr.set([SIGNATURE_SCHEME_TO_FLAG['Secp256r1']]);\n\t\tarr.set(normalized, 1);\n\t\tarr.set(this.publicKey, 1 + normalized.length);\n\n\t\t// serialize all fields into a passkey signature according to https://github.com/sui-foundation/sips/blob/main/sips/sip-9.md#signature-encoding\n\t\treturn PasskeyAuthenticator.serialize({\n\t\t\tauthenticatorData: authenticatorData,\n\t\t\tclientDataJson: clientDataJSONString,\n\t\t\tuserSignature: arr,\n\t\t}).toBytes();\n\t}\n\n\t/**\n\t * This overrides the base class implementation that accepts the raw bytes and signs its\n\t * digest of the intent message, then serialize it with the passkey flag.\n\t */\n\tasync signWithIntent(bytes: Uint8Array, intent: IntentScope): Promise<SignatureWithBytes> {\n\t\t// prepend it into an intent message and computes the digest.\n\t\tconst intentMessage = messageWithIntent(intent, bytes);\n\t\tconst digest = blake2b(intentMessage, { dkLen: 32 });\n\n\t\t// sign the digest.\n\t\tconst signature = await this.sign(digest);\n\n\t\t// prepend with the passkey flag.\n\t\tconst serializedSignature = new Uint8Array(1 + signature.length);\n\t\tserializedSignature.set([SIGNATURE_SCHEME_TO_FLAG[this.getKeyScheme()]]);\n\t\tserializedSignature.set(signature, 1);\n\t\treturn {\n\t\t\tsignature: toBase64(serializedSignature),\n\t\t\tbytes: toBase64(bytes),\n\t\t};\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toBase64 } from '@mysten/bcs';\nimport { secp256r1 } from '@noble/curves/p256';\nimport { blake2b } from '@noble/hashes/blake2b';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { randomBytes } from '@noble/hashes/utils';\n\nimport { PasskeyAuthenticator } from '../../bcs/bcs.js';\nimport type { IntentScope, SignatureWithBytes } from '../../cryptography/index.js';\nimport { messageWithIntent, SIGNATURE_SCHEME_TO_FLAG, Signer } from '../../cryptography/index.js';\nimport type { PublicKey } from '../../cryptography/publickey.js';\nimport type { SignatureScheme } from '../../cryptography/signature-scheme.js';\nimport {\n\tparseDerSPKI,\n\tPASSKEY_PUBLIC_KEY_SIZE,\n\tPASSKEY_SIGNATURE_SIZE,\n\tPasskeyPublicKey,\n} from './publickey.js';\nimport type { AuthenticationCredential, RegistrationCredential } from './types.js';\n\ntype DeepPartialConfigKeys = 'rp' | 'user' | 'authenticatorSelection';\n\ntype DeepPartial<T> = T extends object\n\t? {\n\t\t\t[P in keyof T]?: DeepPartial<T[P]>;\n\t\t}\n\t: T;\n\nexport type BrowserPasswordProviderOptions = Pick<\n\tDeepPartial<PublicKeyCredentialCreationOptions>,\n\tDeepPartialConfigKeys\n> &\n\tOmit<\n\t\tPartial<PublicKeyCredentialCreationOptions>,\n\t\tDeepPartialConfigKeys | 'pubKeyCredParams' | 'challenge'\n\t>;\n\nexport interface PasskeyProvider {\n\tcreate(): Promise<RegistrationCredential>;\n\tget(challenge: Uint8Array): Promise<AuthenticationCredential>;\n}\n\n// Default browser implementation\nexport class BrowserPasskeyProvider implements PasskeyProvider {\n\t#name: string;\n\t#options: BrowserPasswordProviderOptions;\n\n\tconstructor(name: string, options: BrowserPasswordProviderOptions) {\n\t\tthis.#name = name;\n\t\tthis.#options = options;\n\t}\n\n\tasync create(): Promise<RegistrationCredential> {\n\t\treturn (await navigator.credentials.create({\n\t\t\tpublicKey: {\n\t\t\t\ttimeout: this.#options.timeout ?? 60000,\n\t\t\t\t...this.#options,\n\t\t\t\trp: {\n\t\t\t\t\tname: this.#name,\n\t\t\t\t\t...this.#options.rp,\n\t\t\t\t},\n\t\t\t\tuser: {\n\t\t\t\t\tname: this.#name,\n\t\t\t\t\tdisplayName: this.#name,\n\t\t\t\t\t...this.#options.user,\n\t\t\t\t\tid: randomBytes(10),\n\t\t\t\t},\n\t\t\t\tchallenge: new TextEncoder().encode('Create passkey wallet on Sui'),\n\t\t\t\tpubKeyCredParams: [{ alg: -7, type: 'public-key' }],\n\t\t\t\tauthenticatorSelection: {\n\t\t\t\t\tauthenticatorAttachment: 'cross-platform',\n\t\t\t\t\tresidentKey: 'required',\n\t\t\t\t\trequireResidentKey: true,\n\t\t\t\t\tuserVerification: 'required',\n\t\t\t\t\t...this.#options.authenticatorSelection,\n\t\t\t\t},\n\t\t\t},\n\t\t})) as RegistrationCredential;\n\t}\n\n\tasync get(challenge: Uint8Array): Promise<AuthenticationCredential> {\n\t\treturn (await navigator.credentials.get({\n\t\t\tpublicKey: {\n\t\t\t\tchallenge,\n\t\t\t\tuserVerification: this.#options.authenticatorSelection?.userVerification || 'required',\n\t\t\t\ttimeout: this.#options.timeout ?? 60000,\n\t\t\t},\n\t\t})) as AuthenticationCredential;\n\t}\n}\n\n/**\n * @experimental\n * A passkey signer used for signing transactions. This is a client side implementation for [SIP-9](https://github.com/sui-foundation/sips/blob/main/sips/sip-9.md).\n */\nexport class PasskeyKeypair extends Signer {\n\tprivate publicKey: Uint8Array;\n\tprivate provider: PasskeyProvider;\n\n\t/**\n\t * Get the key scheme of passkey,\n\t */\n\tgetKeyScheme(): SignatureScheme {\n\t\treturn 'Passkey';\n\t}\n\n\t/**\n\t * Creates an instance of Passkey signer. If no passkey wallet had created before,\n\t * use `getPasskeyInstance`. For example:\n\t * ```\n\t * let provider = new BrowserPasskeyProvider('Sui Passkey Example',{\n\t * \t rpName: 'Sui Passkey Example',\n\t * \t rpId: window.location.hostname,\n\t * } as BrowserPasswordProviderOptions);\n\t * const signer = await PasskeyKeypair.getPasskeyInstance(provider);\n\t * ```\n\t *\n\t * If there are existing passkey wallet, use `signAndRecover` to identify the correct\n\t * public key and then initialize the instance. See usage in `signAndRecover`.\n\t */\n\tconstructor(publicKey: Uint8Array, provider: PasskeyProvider) {\n\t\tsuper();\n\t\tthis.publicKey = publicKey;\n\t\tthis.provider = provider;\n\t}\n\n\t/**\n\t * Creates an instance of Passkey signer invoking the passkey from navigator.\n\t * Note that this will invoke the passkey device to create a fresh credential.\n\t * Should only be called if passkey wallet is created for the first time.\n\t *\n\t * @param provider - the passkey provider.\n\t * @returns the passkey instance.\n\t */\n\tstatic async getPasskeyInstance(provider: PasskeyProvider): Promise<PasskeyKeypair> {\n\t\t// create a passkey secp256r1 with the provider.\n\t\tconst credential = await provider.create();\n\n\t\tif (!credential.response.getPublicKey()) {\n\t\t\tthrow new Error('Invalid credential create response');\n\t\t} else {\n\t\t\tconst derSPKI = credential.response.getPublicKey()!;\n\t\t\tconst pubkeyUncompressed = parseDerSPKI(new Uint8Array(derSPKI));\n\t\t\tconst pubkey = secp256r1.ProjectivePoint.fromHex(pubkeyUncompressed);\n\t\t\tconst pubkeyCompressed = pubkey.toRawBytes(true);\n\t\t\treturn new PasskeyKeypair(pubkeyCompressed, provider);\n\t\t}\n\t}\n\n\t/**\n\t * Return the public key for this passkey.\n\t */\n\tgetPublicKey(): PublicKey {\n\t\treturn new PasskeyPublicKey(this.publicKey);\n\t}\n\n\t/**\n\t * Return the signature for the provided data (i.e. blake2b(intent_message)).\n\t * This is sent to passkey as the challenge field.\n\t */\n\tasync sign(data: Uint8Array) {\n\t\t// asks the passkey to sign over challenge as the data.\n\t\tconst credential = await this.provider.get(data);\n\n\t\t// parse authenticatorData (as bytes), clientDataJSON (decoded as string).\n\t\tconst authenticatorData = new Uint8Array(credential.response.authenticatorData);\n\t\tconst clientDataJSON = new Uint8Array(credential.response.clientDataJSON); // response.clientDataJSON is already UTF-8 encoded JSON\n\t\tconst decoder = new TextDecoder();\n\t\tconst clientDataJSONString: string = decoder.decode(clientDataJSON);\n\n\t\t// parse the signature from DER format, normalize and convert to compressed format (33 bytes).\n\t\tconst sig = secp256r1.Signature.fromDER(new Uint8Array(credential.response.signature));\n\t\tconst normalized = sig.normalizeS().toCompactRawBytes();\n\n\t\tif (\n\t\t\tnormalized.length !== PASSKEY_SIGNATURE_SIZE ||\n\t\t\tthis.publicKey.length !== PASSKEY_PUBLIC_KEY_SIZE\n\t\t) {\n\t\t\tthrow new Error('Invalid signature or public key length');\n\t\t}\n\n\t\t// construct userSignature as flag || sig || pubkey for the secp256r1 signature.\n\t\tconst arr = new Uint8Array(1 + normalized.length + this.publicKey.length);\n\t\tarr.set([SIGNATURE_SCHEME_TO_FLAG['Secp256r1']]);\n\t\tarr.set(normalized, 1);\n\t\tarr.set(this.publicKey, 1 + normalized.length);\n\n\t\t// serialize all fields into a passkey signature according to https://github.com/sui-foundation/sips/blob/main/sips/sip-9.md#signature-encoding\n\t\treturn PasskeyAuthenticator.serialize({\n\t\t\tauthenticatorData: authenticatorData,\n\t\t\tclientDataJson: clientDataJSONString,\n\t\t\tuserSignature: arr,\n\t\t}).toBytes();\n\t}\n\n\t/**\n\t * This overrides the base class implementation that accepts the raw bytes and signs its\n\t * digest of the intent message, then serialize it with the passkey flag.\n\t */\n\tasync signWithIntent(bytes: Uint8Array, intent: IntentScope): Promise<SignatureWithBytes> {\n\t\t// prepend it into an intent message and computes the digest.\n\t\tconst intentMessage = messageWithIntent(intent, bytes);\n\t\tconst digest = blake2b(intentMessage, { dkLen: 32 });\n\n\t\t// sign the digest.\n\t\tconst signature = await this.sign(digest);\n\n\t\t// prepend with the passkey flag.\n\t\tconst serializedSignature = new Uint8Array(1 + signature.length);\n\t\tserializedSignature.set([SIGNATURE_SCHEME_TO_FLAG[this.getKeyScheme()]]);\n\t\tserializedSignature.set(signature, 1);\n\t\treturn {\n\t\t\tsignature: toBase64(serializedSignature),\n\t\t\tbytes: toBase64(bytes),\n\t\t};\n\t}\n\n\t/**\n\t * Given a message, asks the passkey device to sign it and return all (up to 4) possible public keys.\n\t * See: https://bitcoin.stackexchange.com/questions/81232/how-is-public-key-extracted-from-message-digital-signature-address\n\t *\n\t * This is useful if the user previously created passkey wallet with the origin, but the wallet session\n\t * does not have the public key / address. By calling this method twice with two different messages, the\n\t * wallet can compare the returned public keys and uniquely identify the previously created passkey wallet\n\t * using `findCommonPublicKey`.\n\t *\n\t * Alternatively, one call can be made and all possible public keys should be checked onchain to see if\n\t * there is any assets.\n\t *\n\t * Once the correct public key is identified, a passkey instance can then be initialized with this public key.\n\t *\n\t * Example usage to recover wallet with two signing calls:\n\t * ```\n\t * let provider = new BrowserPasskeyProvider('Sui Passkey Example',{\n\t * rpName: 'Sui Passkey Example',\n\t * \t rpId: window.location.hostname,\n\t * } as BrowserPasswordProviderOptions);\n\t * const testMessage = new TextEncoder().encode('Hello world!');\n\t * const possiblePks = await PasskeyKeypair.signAndRecover(provider, testMessage);\n\t * const testMessage2 = new TextEncoder().encode('Hello world 2!');\n\t * const possiblePks2 = await PasskeyKeypair.signAndRecover(provider, testMessage2);\n\t * const commonPk = findCommonPublicKey(possiblePks, possiblePks2);\n\t * const signer = new PasskeyKeypair(provider, commonPk.toRawBytes());\n\t * ```\n\t *\n\t * @param provider - the passkey provider.\n\t * @param message - the message to sign.\n\t * @returns all possible public keys.\n\t */\n\tstatic async signAndRecover(\n\t\tprovider: PasskeyProvider,\n\t\tmessage: Uint8Array,\n\t): Promise<PublicKey[]> {\n\t\tconst credential = await provider.get(message);\n\t\tconst fullMessage = messageFromAssertionResponse(credential.response);\n\t\tconst sig = secp256r1.Signature.fromDER(new Uint8Array(credential.response.signature));\n\n\t\tconst res = [];\n\t\tfor (let i = 0; i < 4; i++) {\n\t\t\tconst s = sig.addRecoveryBit(i);\n\t\t\ttry {\n\t\t\t\tconst pubkey = s.recoverPublicKey(sha256(fullMessage));\n\t\t\t\tconst pk = new PasskeyPublicKey(pubkey.toRawBytes(true));\n\t\t\t\tres.push(pk);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t}\n}\n\n/**\n * Finds the unique public key that exists in both arrays, throws error if the common\n * pubkey does not equal to one.\n *\n * @param arr1 - The first pubkeys array.\n * @param arr2 - The second pubkeys array.\n * @returns The only common pubkey in both arrays.\n */\nexport function findCommonPublicKey(arr1: PublicKey[], arr2: PublicKey[]): PublicKey {\n\tconst matchingPubkeys: PublicKey[] = [];\n\tfor (const pubkey1 of arr1) {\n\t\tfor (const pubkey2 of arr2) {\n\t\t\tif (pubkey1.equals(pubkey2)) {\n\t\t\t\tmatchingPubkeys.push(pubkey1);\n\t\t\t}\n\t\t}\n\t}\n\tif (matchingPubkeys.length !== 1) {\n\t\tthrow new Error('No unique public key found');\n\t}\n\treturn matchingPubkeys[0];\n}\n\n/**\n * Constructs the message that the passkey signature is produced over as authenticatorData || sha256(clientDataJSON).\n */\nfunction messageFromAssertionResponse(response: AuthenticatorAssertionResponse): Uint8Array {\n\tconst authenticatorData = new Uint8Array(response.authenticatorData);\n\tconst clientDataJSON = new Uint8Array(response.clientDataJSON);\n\tconst clientDataJSONDigest = sha256(clientDataJSON);\n\treturn new Uint8Array([...authenticatorData, ...clientDataJSONDigest]);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The value returned from navigator.credentials.get()
3
+ */
4
+ export interface AuthenticationCredential extends PublicKeyCredential {
5
+ response: AuthenticatorAssertionResponse;
6
+ }
7
+ /**
8
+ * The value returned from navigator.credentials.create()
9
+ */
10
+ export interface RegistrationCredential extends PublicKeyCredential {
11
+ response: AuthenticatorAttestationResponse;
12
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1,5 +1,5 @@
1
1
  import type { SerializedBcs } from '@mysten/bcs';
2
- import type { Argument } from './data/internal.js';
2
+ import type { PureTypeName, ShapeFromPureTypeName, ValidPureTypeName } from '../bcs/pure.js';
3
3
  export declare function createPure<T>(makePure: (value: SerializedBcs<any, any> | Uint8Array) => T): {
4
4
  <T_1 extends PureTypeName>(type: T_1 extends PureTypeName ? ValidPureTypeName<T_1> : T_1, value: ShapeFromPureTypeName<T_1>): T_1;
5
5
  (value: SerializedBcs<any, any> | Uint8Array): T;
@@ -18,11 +18,3 @@ export declare function createPure<T>(makePure: (value: SerializedBcs<any, any>
18
18
  }): T;
19
19
  option<Type extends PureTypeName>(type: T extends PureTypeName ? ValidPureTypeName<Type> : Type, value: ShapeFromPureTypeName<Type> | null | undefined): T;
20
20
  };
21
- export type BasePureType = 'u8' | 'u16' | 'u32' | 'u64' | 'u128' | 'u256' | 'bool' | 'id' | 'string' | 'address';
22
- export type PureTypeName = BasePureType | `vector<${string}>` | `option<${string}>`;
23
- export type ValidPureTypeName<T extends string> = T extends BasePureType ? PureTypeName : T extends `vector<${infer U}>` ? ValidPureTypeName<U> : T extends `option<${infer U}>` ? ValidPureTypeName<U> : PureTypeValidationError<T>;
24
- type ShapeFromPureTypeName<T extends PureTypeName> = T extends BasePureType ? Parameters<ReturnType<typeof createPure<Argument>>[T]>[0] : T extends `vector<${infer U extends PureTypeName}>` ? ShapeFromPureTypeName<U>[] : T extends `option<${infer U extends PureTypeName}>` ? ShapeFromPureTypeName<U> | null : never;
25
- type PureTypeValidationError<T extends string> = T & {
26
- error: `Invalid Pure type name: ${T}`;
27
- };
28
- export {};
@@ -1,9 +1,10 @@
1
1
  import { isSerializedBcs } from "@mysten/bcs";
2
2
  import { bcs } from "../bcs/index.js";
3
+ import { pureBcsSchemaFromTypeName } from "../bcs/pure.js";
3
4
  function createPure(makePure) {
4
5
  function pure(typeOrSerializedValue, value) {
5
6
  if (typeof typeOrSerializedValue === "string") {
6
- return makePure(schemaFromName(typeOrSerializedValue).serialize(value));
7
+ return makePure(pureBcsSchemaFromTypeName(typeOrSerializedValue).serialize(value));
7
8
  }
8
9
  if (typeOrSerializedValue instanceof Uint8Array || isSerializedBcs(typeOrSerializedValue)) {
9
10
  return makePure(typeOrSerializedValue);
@@ -21,46 +22,15 @@ function createPure(makePure) {
21
22
  pure.address = (value) => makePure(bcs.Address.serialize(value));
22
23
  pure.id = pure.address;
23
24
  pure.vector = (type, value) => {
24
- return makePure(bcs.vector(schemaFromName(type)).serialize(value));
25
+ return makePure(
26
+ bcs.vector(pureBcsSchemaFromTypeName(type)).serialize(value)
27
+ );
25
28
  };
26
29
  pure.option = (type, value) => {
27
- return makePure(bcs.option(schemaFromName(type)).serialize(value));
30
+ return makePure(bcs.option(pureBcsSchemaFromTypeName(type)).serialize(value));
28
31
  };
29
32
  return pure;
30
33
  }
31
- function schemaFromName(name) {
32
- switch (name) {
33
- case "u8":
34
- return bcs.u8();
35
- case "u16":
36
- return bcs.u16();
37
- case "u32":
38
- return bcs.u32();
39
- case "u64":
40
- return bcs.u64();
41
- case "u128":
42
- return bcs.u128();
43
- case "u256":
44
- return bcs.u256();
45
- case "bool":
46
- return bcs.bool();
47
- case "string":
48
- return bcs.string();
49
- case "id":
50
- case "address":
51
- return bcs.Address;
52
- }
53
- const generic = name.match(/^(vector|option)<(.+)>$/);
54
- if (generic) {
55
- const [kind, inner] = generic.slice(1);
56
- if (kind === "vector") {
57
- return bcs.vector(schemaFromName(inner));
58
- } else {
59
- return bcs.option(schemaFromName(inner));
60
- }
61
- }
62
- throw new Error(`Invalid Pure type name: ${name}`);
63
- }
64
34
  export {
65
35
  createPure
66
36
  };