@mysten/sui 1.22.0 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/client/types/generated.d.ts +24 -3
- package/dist/cjs/client/types/generated.js.map +1 -1
- package/dist/cjs/client/types/params.d.ts +14 -0
- package/dist/cjs/client/types/params.js.map +1 -1
- package/dist/cjs/graphql/generated/latest/tada-env.d.ts +56 -12
- package/dist/cjs/graphql/generated/latest/tada-env.js +64 -13
- package/dist/cjs/graphql/generated/latest/tada-env.js.map +2 -2
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/zklogin/address.js +3 -12
- package/dist/cjs/zklogin/address.js.map +2 -2
- package/dist/cjs/zklogin/index.d.ts +1 -0
- package/dist/cjs/zklogin/index.js +2 -0
- package/dist/cjs/zklogin/index.js.map +2 -2
- package/dist/cjs/zklogin/jwt-decode.d.ts +47 -0
- package/dist/cjs/zklogin/jwt-decode.js +85 -0
- package/dist/cjs/zklogin/jwt-decode.js.map +7 -0
- package/dist/cjs/zklogin/jwt-utils.d.ts +7 -0
- package/dist/cjs/zklogin/jwt-utils.js +19 -0
- package/dist/cjs/zklogin/jwt-utils.js.map +2 -2
- package/dist/cjs/zklogin/nonce.js +2 -2
- package/dist/cjs/zklogin/nonce.js.map +2 -2
- package/dist/cjs/zklogin/publickey.d.ts +2 -0
- package/dist/cjs/zklogin/publickey.js +18 -1
- package/dist/cjs/zklogin/publickey.js.map +2 -2
- package/dist/cjs/zklogin/utils.d.ts +1 -0
- package/dist/cjs/zklogin/utils.js +7 -0
- package/dist/cjs/zklogin/utils.js.map +2 -2
- package/dist/esm/client/types/generated.d.ts +24 -3
- package/dist/esm/client/types/params.d.ts +14 -0
- package/dist/esm/graphql/generated/latest/tada-env.d.ts +56 -12
- package/dist/esm/graphql/generated/latest/tada-env.js +64 -13
- package/dist/esm/graphql/generated/latest/tada-env.js.map +2 -2
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/zklogin/address.js +8 -12
- package/dist/esm/zklogin/address.js.map +2 -2
- package/dist/esm/zklogin/index.d.ts +1 -0
- package/dist/esm/zklogin/index.js +2 -0
- package/dist/esm/zklogin/index.js.map +2 -2
- package/dist/esm/zklogin/jwt-decode.d.ts +47 -0
- package/dist/esm/zklogin/jwt-decode.js +65 -0
- package/dist/esm/zklogin/jwt-decode.js.map +7 -0
- package/dist/esm/zklogin/jwt-utils.d.ts +7 -0
- package/dist/esm/zklogin/jwt-utils.js +19 -0
- package/dist/esm/zklogin/jwt-utils.js.map +2 -2
- package/dist/esm/zklogin/nonce.js +2 -2
- package/dist/esm/zklogin/nonce.js.map +2 -2
- package/dist/esm/zklogin/publickey.d.ts +2 -0
- package/dist/esm/zklogin/publickey.js +19 -2
- package/dist/esm/zklogin/publickey.js.map +2 -2
- package/dist/esm/zklogin/utils.d.ts +1 -0
- package/dist/esm/zklogin/utils.js +7 -0
- package/dist/esm/zklogin/utils.js.map +2 -2
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -2
- package/src/client/types/generated.ts +31 -5
- package/src/client/types/params.ts +14 -0
- package/src/graphql/generated/latest/schema.graphql +17 -6
- package/src/graphql/generated/latest/tada-env.ts +64 -13
- package/src/version.ts +1 -1
- package/src/zklogin/address.ts +9 -13
- package/src/zklogin/index.ts +1 -0
- package/src/zklogin/jwt-decode.ts +126 -0
- package/src/zklogin/jwt-utils.ts +29 -0
- package/src/zklogin/nonce.ts +3 -2
- package/src/zklogin/publickey.ts +26 -2
- package/src/zklogin/utils.ts +7 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"author": "Mysten Labs <build@mystenlabs.com>",
|
|
4
4
|
"description": "Sui TypeScript API(Work in Progress)",
|
|
5
5
|
"homepage": "https://sdk.mystenlabs.com",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.24.0",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"files": [
|
|
@@ -138,7 +138,6 @@
|
|
|
138
138
|
"@scure/bip39": "^1.3.0",
|
|
139
139
|
"gql.tada": "^1.8.2",
|
|
140
140
|
"graphql": "^16.9.0",
|
|
141
|
-
"jose": "^5.6.3",
|
|
142
141
|
"poseidon-lite": "^0.2.0",
|
|
143
142
|
"valibot": "^0.36.0",
|
|
144
143
|
"@mysten/bcs": "1.5.0"
|
|
@@ -99,11 +99,18 @@ export type CompressedSignature =
|
|
|
99
99
|
}
|
|
100
100
|
| {
|
|
101
101
|
ZkLogin: string;
|
|
102
|
+
}
|
|
103
|
+
| {
|
|
104
|
+
Passkey: string;
|
|
102
105
|
};
|
|
103
106
|
/** Uses an enum to allow for future expansion of the ConsensusDeterminedVersionAssignments. */
|
|
104
|
-
export type ConsensusDeterminedVersionAssignments =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
export type ConsensusDeterminedVersionAssignments =
|
|
108
|
+
| {
|
|
109
|
+
CancelledTransactions: [string, [string, string][]][];
|
|
110
|
+
}
|
|
111
|
+
| {
|
|
112
|
+
CancelledTransactionsV2: [string, [[string, string], string][]][];
|
|
113
|
+
};
|
|
107
114
|
export type SuiParsedData =
|
|
108
115
|
| {
|
|
109
116
|
dataType: 'moveObject';
|
|
@@ -166,6 +173,7 @@ export interface DryRunTransactionBlockResponse {
|
|
|
166
173
|
balanceChanges: BalanceChange[];
|
|
167
174
|
effects: TransactionEffects;
|
|
168
175
|
events: SuiEvent[];
|
|
176
|
+
executionErrorSource?: string | null;
|
|
169
177
|
input: TransactionBlockData;
|
|
170
178
|
objectChanges: SuiObjectChange[];
|
|
171
179
|
}
|
|
@@ -437,8 +445,8 @@ export interface MultiSig {
|
|
|
437
445
|
sigs: CompressedSignature[];
|
|
438
446
|
}
|
|
439
447
|
/**
|
|
440
|
-
* Deprecated, use [struct MultiSig] instead. The struct that contains signatures and public keys
|
|
441
|
-
* for authenticating a MultiSigLegacy.
|
|
448
|
+
* Deprecated, use [struct MultiSig] instead. The struct that contains signatures and public keys
|
|
449
|
+
* necessary for authenticating a MultiSigLegacy.
|
|
442
450
|
*/
|
|
443
451
|
export interface MultiSigLegacy {
|
|
444
452
|
/** A bitmap that indicates the position of which public key the signature should be authenticated with. */
|
|
@@ -956,6 +964,7 @@ export type SuiEndOfEpochTransactionKind =
|
|
|
956
964
|
| 'AuthenticatorStateCreate'
|
|
957
965
|
| 'RandomnessStateCreate'
|
|
958
966
|
| 'CoinDenyListStateCreate'
|
|
967
|
+
| 'StoreExecutionTimeObservations'
|
|
959
968
|
| {
|
|
960
969
|
ChangeEpoch: SuiChangeEpoch;
|
|
961
970
|
}
|
|
@@ -1466,6 +1475,16 @@ export type SuiTransactionBlockKind =
|
|
|
1466
1475
|
kind: 'ConsensusCommitPrologueV3';
|
|
1467
1476
|
round: string;
|
|
1468
1477
|
sub_dag_index?: string | null;
|
|
1478
|
+
}
|
|
1479
|
+
| {
|
|
1480
|
+
additional_state_digest: string;
|
|
1481
|
+
commit_timestamp_ms: string;
|
|
1482
|
+
consensus_commit_digest: string;
|
|
1483
|
+
consensus_determined_version_assignments: ConsensusDeterminedVersionAssignments;
|
|
1484
|
+
epoch: string;
|
|
1485
|
+
kind: 'ConsensusCommitPrologueV4';
|
|
1486
|
+
round: string;
|
|
1487
|
+
sub_dag_index?: string | null;
|
|
1469
1488
|
};
|
|
1470
1489
|
export interface SuiTransactionBlockResponse {
|
|
1471
1490
|
balanceChanges?: BalanceChange[] | null;
|
|
@@ -1594,9 +1613,16 @@ export interface ZkLoginInputs {
|
|
|
1594
1613
|
issBase64Details: Claim;
|
|
1595
1614
|
proofPoints: ZkLoginProof;
|
|
1596
1615
|
}
|
|
1616
|
+
export type ZkLoginIntentScope = 'TransactionData' | 'PersonalMessage';
|
|
1597
1617
|
/** The struct for zk login proof. */
|
|
1598
1618
|
export interface ZkLoginProof {
|
|
1599
1619
|
a: string[];
|
|
1600
1620
|
b: string[][];
|
|
1601
1621
|
c: string[];
|
|
1602
1622
|
}
|
|
1623
|
+
export interface ZkLoginVerifyResult {
|
|
1624
|
+
/** The errors field captures any verification error */
|
|
1625
|
+
errors: string[];
|
|
1626
|
+
/** The boolean result of the verification. If true, errors should be empty. */
|
|
1627
|
+
success: boolean;
|
|
1628
|
+
}
|
|
@@ -180,6 +180,20 @@ export interface TryMultiGetPastObjectsParams {
|
|
|
180
180
|
/** options for specifying the content to be returned */
|
|
181
181
|
options?: RpcTypes.SuiObjectDataOptions | null | undefined;
|
|
182
182
|
}
|
|
183
|
+
/** Verify a zklogin signature for the given bytes, intent scope and author. */
|
|
184
|
+
export interface VerifyZkLoginSignatureParams {
|
|
185
|
+
/**
|
|
186
|
+
* The Base64 string of bcs bytes for raw transaction data or personal message indicated by
|
|
187
|
+
* intent_scope.
|
|
188
|
+
*/
|
|
189
|
+
bytes: string;
|
|
190
|
+
/** The Base64 string of the zklogin signature to verify. */
|
|
191
|
+
signature: string;
|
|
192
|
+
/** The intent scope, either transaction data or personal message. Used to parse bytes. */
|
|
193
|
+
intentScope: RpcTypes.ZkLoginIntentScope;
|
|
194
|
+
/** The author of the signature. */
|
|
195
|
+
author: string;
|
|
196
|
+
}
|
|
183
197
|
/** Return the total coin balance for all coin type, owned by the address owner. */
|
|
184
198
|
export interface GetAllBalancesParams {
|
|
185
199
|
/** the owner's Sui address */
|
|
@@ -1046,7 +1046,7 @@ type EndOfEpochTransaction {
|
|
|
1046
1046
|
transactions(first: Int, before: String, last: Int, after: String): EndOfEpochTransactionKindConnection!
|
|
1047
1047
|
}
|
|
1048
1048
|
|
|
1049
|
-
union EndOfEpochTransactionKind = ChangeEpochTransaction | AuthenticatorStateCreateTransaction | AuthenticatorStateExpireTransaction | RandomnessStateCreateTransaction | CoinDenyListStateCreateTransaction | BridgeStateCreateTransaction | BridgeCommitteeInitTransaction
|
|
1049
|
+
union EndOfEpochTransactionKind = ChangeEpochTransaction | AuthenticatorStateCreateTransaction | AuthenticatorStateExpireTransaction | RandomnessStateCreateTransaction | CoinDenyListStateCreateTransaction | BridgeStateCreateTransaction | BridgeCommitteeInitTransaction | StoreExecutionTimeObservationsTransaction
|
|
1050
1050
|
|
|
1051
1051
|
type EndOfEpochTransactionKindConnection {
|
|
1052
1052
|
"""
|
|
@@ -2879,7 +2879,7 @@ objects are ones whose
|
|
|
2879
2879
|
|
|
2880
2880
|
- Type matches the `type` filter,
|
|
2881
2881
|
- AND, whose owner matches the `owner` filter,
|
|
2882
|
-
- AND, whose ID is in `objectIds
|
|
2882
|
+
- AND, whose ID is in `objectIds`.
|
|
2883
2883
|
"""
|
|
2884
2884
|
input ObjectFilter {
|
|
2885
2885
|
"""
|
|
@@ -2898,10 +2898,6 @@ input ObjectFilter {
|
|
|
2898
2898
|
Filter for live objects by their IDs.
|
|
2899
2899
|
"""
|
|
2900
2900
|
objectIds: [SuiAddress!]
|
|
2901
|
-
"""
|
|
2902
|
-
Filter for live or potentially historical objects by their ID and version.
|
|
2903
|
-
"""
|
|
2904
|
-
objectKeys: [ObjectKey!]
|
|
2905
2901
|
}
|
|
2906
2902
|
|
|
2907
2903
|
input ObjectKey {
|
|
@@ -3325,6 +3321,10 @@ type Query {
|
|
|
3325
3321
|
"""
|
|
3326
3322
|
transactionBlock(digest: String!): TransactionBlock
|
|
3327
3323
|
"""
|
|
3324
|
+
Fetch a list of objects by their IDs and versions.
|
|
3325
|
+
"""
|
|
3326
|
+
multiGetObjects(keys: [ObjectKey!]!): [Object]!
|
|
3327
|
+
"""
|
|
3328
3328
|
The coin objects that exist in the network.
|
|
3329
3329
|
|
|
3330
3330
|
The type field is a string of the inner type of the coin by which to filter (e.g.
|
|
@@ -3599,6 +3599,10 @@ type ServiceConfig {
|
|
|
3599
3599
|
"""
|
|
3600
3600
|
maxTransactionIds: Int!
|
|
3601
3601
|
"""
|
|
3602
|
+
Maximum number of keys that can be passed to a `multiGetObjects` query.
|
|
3603
|
+
"""
|
|
3604
|
+
maxMultiGetObjectsKeys: Int!
|
|
3605
|
+
"""
|
|
3602
3606
|
Maximum number of candidates to scan when gathering a page of results.
|
|
3603
3607
|
"""
|
|
3604
3608
|
maxScanLimit: Int!
|
|
@@ -3970,6 +3974,13 @@ type StorageFund {
|
|
|
3970
3974
|
nonRefundableBalance: BigInt
|
|
3971
3975
|
}
|
|
3972
3976
|
|
|
3977
|
+
type StoreExecutionTimeObservationsTransaction {
|
|
3978
|
+
"""
|
|
3979
|
+
A workaround to define an empty variant of a GraphQL union.
|
|
3980
|
+
"""
|
|
3981
|
+
_: Boolean
|
|
3982
|
+
}
|
|
3983
|
+
|
|
3973
3984
|
|
|
3974
3985
|
"""
|
|
3975
3986
|
String containing 32B hex-encoded address, with a leading "0x". Leading zeroes can be omitted on input but will always appear in outputs (SuiAddress in output is guaranteed to be 66 characters long).
|
|
@@ -3319,6 +3319,10 @@ const introspection = {
|
|
|
3319
3319
|
{
|
|
3320
3320
|
"kind": "OBJECT",
|
|
3321
3321
|
"name": "RandomnessStateCreateTransaction"
|
|
3322
|
+
},
|
|
3323
|
+
{
|
|
3324
|
+
"kind": "OBJECT",
|
|
3325
|
+
"name": "StoreExecutionTimeObservationsTransaction"
|
|
3322
3326
|
}
|
|
3323
3327
|
]
|
|
3324
3328
|
},
|
|
@@ -8788,19 +8792,6 @@ const introspection = {
|
|
|
8788
8792
|
}
|
|
8789
8793
|
}
|
|
8790
8794
|
}
|
|
8791
|
-
},
|
|
8792
|
-
{
|
|
8793
|
-
"name": "objectKeys",
|
|
8794
|
-
"type": {
|
|
8795
|
-
"kind": "LIST",
|
|
8796
|
-
"ofType": {
|
|
8797
|
-
"kind": "NON_NULL",
|
|
8798
|
-
"ofType": {
|
|
8799
|
-
"kind": "INPUT_OBJECT",
|
|
8800
|
-
"name": "ObjectKey"
|
|
8801
|
-
}
|
|
8802
|
-
}
|
|
8803
|
-
}
|
|
8804
8795
|
}
|
|
8805
8796
|
],
|
|
8806
8797
|
"isOneOf": false
|
|
@@ -10199,6 +10190,38 @@ const introspection = {
|
|
|
10199
10190
|
],
|
|
10200
10191
|
"isDeprecated": false
|
|
10201
10192
|
},
|
|
10193
|
+
{
|
|
10194
|
+
"name": "multiGetObjects",
|
|
10195
|
+
"type": {
|
|
10196
|
+
"kind": "NON_NULL",
|
|
10197
|
+
"ofType": {
|
|
10198
|
+
"kind": "LIST",
|
|
10199
|
+
"ofType": {
|
|
10200
|
+
"kind": "OBJECT",
|
|
10201
|
+
"name": "Object"
|
|
10202
|
+
}
|
|
10203
|
+
}
|
|
10204
|
+
},
|
|
10205
|
+
"args": [
|
|
10206
|
+
{
|
|
10207
|
+
"name": "keys",
|
|
10208
|
+
"type": {
|
|
10209
|
+
"kind": "NON_NULL",
|
|
10210
|
+
"ofType": {
|
|
10211
|
+
"kind": "LIST",
|
|
10212
|
+
"ofType": {
|
|
10213
|
+
"kind": "NON_NULL",
|
|
10214
|
+
"ofType": {
|
|
10215
|
+
"kind": "INPUT_OBJECT",
|
|
10216
|
+
"name": "ObjectKey"
|
|
10217
|
+
}
|
|
10218
|
+
}
|
|
10219
|
+
}
|
|
10220
|
+
}
|
|
10221
|
+
}
|
|
10222
|
+
],
|
|
10223
|
+
"isDeprecated": false
|
|
10224
|
+
},
|
|
10202
10225
|
{
|
|
10203
10226
|
"name": "object",
|
|
10204
10227
|
"type": {
|
|
@@ -10937,6 +10960,18 @@ const introspection = {
|
|
|
10937
10960
|
"args": [],
|
|
10938
10961
|
"isDeprecated": false
|
|
10939
10962
|
},
|
|
10963
|
+
{
|
|
10964
|
+
"name": "maxMultiGetObjectsKeys",
|
|
10965
|
+
"type": {
|
|
10966
|
+
"kind": "NON_NULL",
|
|
10967
|
+
"ofType": {
|
|
10968
|
+
"kind": "SCALAR",
|
|
10969
|
+
"name": "Int"
|
|
10970
|
+
}
|
|
10971
|
+
},
|
|
10972
|
+
"args": [],
|
|
10973
|
+
"isDeprecated": false
|
|
10974
|
+
},
|
|
10940
10975
|
{
|
|
10941
10976
|
"name": "maxOutputNodes",
|
|
10942
10977
|
"type": {
|
|
@@ -12085,6 +12120,22 @@ const introspection = {
|
|
|
12085
12120
|
],
|
|
12086
12121
|
"interfaces": []
|
|
12087
12122
|
},
|
|
12123
|
+
{
|
|
12124
|
+
"kind": "OBJECT",
|
|
12125
|
+
"name": "StoreExecutionTimeObservationsTransaction",
|
|
12126
|
+
"fields": [
|
|
12127
|
+
{
|
|
12128
|
+
"name": "_",
|
|
12129
|
+
"type": {
|
|
12130
|
+
"kind": "SCALAR",
|
|
12131
|
+
"name": "Boolean"
|
|
12132
|
+
},
|
|
12133
|
+
"args": [],
|
|
12134
|
+
"isDeprecated": false
|
|
12135
|
+
}
|
|
12136
|
+
],
|
|
12137
|
+
"interfaces": []
|
|
12138
|
+
},
|
|
12088
12139
|
{
|
|
12089
12140
|
"kind": "SCALAR",
|
|
12090
12141
|
"name": "String"
|
package/src/version.ts
CHANGED
package/src/zklogin/address.ts
CHANGED
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
import { blake2b } from '@noble/hashes/blake2b';
|
|
5
5
|
import { bytesToHex } from '@noble/hashes/utils';
|
|
6
|
-
import { decodeJwt } from 'jose';
|
|
7
6
|
|
|
8
7
|
import { SIGNATURE_SCHEME_TO_FLAG } from '../cryptography/signature-scheme.js';
|
|
9
8
|
import { normalizeSuiAddress, SUI_ADDRESS_LENGTH } from '../utils/index.js';
|
|
10
|
-
import {
|
|
9
|
+
import { decodeJwt } from './jwt-utils.js';
|
|
10
|
+
import {
|
|
11
|
+
genAddressSeed,
|
|
12
|
+
normalizeZkLoginIssuer,
|
|
13
|
+
toBigEndianBytes,
|
|
14
|
+
toPaddedBigEndianBytes,
|
|
15
|
+
} from './utils.js';
|
|
11
16
|
|
|
12
17
|
export function computeZkLoginAddressFromSeed(
|
|
13
18
|
addressSeed: bigint,
|
|
@@ -18,10 +23,8 @@ export function computeZkLoginAddressFromSeed(
|
|
|
18
23
|
const addressSeedBytesBigEndian = legacyAddress
|
|
19
24
|
? toBigEndianBytes(addressSeed, 32)
|
|
20
25
|
: toPaddedBigEndianBytes(addressSeed, 32);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
const addressParamBytes = new TextEncoder().encode(iss);
|
|
26
|
+
|
|
27
|
+
const addressParamBytes = new TextEncoder().encode(normalizeZkLoginIssuer(iss));
|
|
25
28
|
const tmp = new Uint8Array(2 + addressSeedBytesBigEndian.length + addressParamBytes.length);
|
|
26
29
|
|
|
27
30
|
tmp.set([SIGNATURE_SCHEME_TO_FLAG.ZkLogin]);
|
|
@@ -62,13 +65,6 @@ export function jwtToAddress(jwt: string, userSalt: string | bigint, legacyAddre
|
|
|
62
65
|
lengthChecks(jwt);
|
|
63
66
|
|
|
64
67
|
const decodedJWT = decodeJwt(jwt);
|
|
65
|
-
if (!decodedJWT.sub || !decodedJWT.iss || !decodedJWT.aud) {
|
|
66
|
-
throw new Error('Missing jwt data');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (Array.isArray(decodedJWT.aud)) {
|
|
70
|
-
throw new Error('Not supported aud. Aud is an array, string was expected.');
|
|
71
|
-
}
|
|
72
68
|
|
|
73
69
|
return computeZkLoginAddress({
|
|
74
70
|
userSalt,
|
package/src/zklogin/index.ts
CHANGED
|
@@ -15,3 +15,4 @@ export { toZkLoginPublicIdentifier, ZkLoginPublicIdentifier } from './publickey.
|
|
|
15
15
|
export type { ZkLoginSignatureInputs } from './bcs.js';
|
|
16
16
|
export { poseidonHash } from './poseidon.js';
|
|
17
17
|
export { generateNonce, generateRandomness } from './nonce.js';
|
|
18
|
+
export { decodeJwt } from './jwt-utils.js';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// Copyright (c) Mysten Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/** Copied from https://github.com/auth0/jwt-decode/blob/3d372e9875ff673228a9f2d9df74e84690842a9c/lib/index.ts */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
The MIT License (MIT)
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2015 Auth0, Inc. <support@auth0.com> (http://auth0.com)
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export interface JwtDecodeOptions {
|
|
31
|
+
header?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface JwtHeader {
|
|
35
|
+
typ?: string;
|
|
36
|
+
alg?: string;
|
|
37
|
+
kid?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface JwtPayload {
|
|
41
|
+
iss?: string;
|
|
42
|
+
sub?: string;
|
|
43
|
+
aud?: string[] | string;
|
|
44
|
+
exp?: number;
|
|
45
|
+
nbf?: number;
|
|
46
|
+
iat?: number;
|
|
47
|
+
jti?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class InvalidTokenError extends Error {}
|
|
51
|
+
|
|
52
|
+
InvalidTokenError.prototype.name = 'InvalidTokenError';
|
|
53
|
+
|
|
54
|
+
function b64DecodeUnicode(str: string) {
|
|
55
|
+
return decodeURIComponent(
|
|
56
|
+
atob(str).replace(/(.)/g, (_m, p) => {
|
|
57
|
+
let code = (p as string).charCodeAt(0).toString(16).toUpperCase();
|
|
58
|
+
if (code.length < 2) {
|
|
59
|
+
code = '0' + code;
|
|
60
|
+
}
|
|
61
|
+
return '%' + code;
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function base64UrlDecode(str: string) {
|
|
67
|
+
let output = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
68
|
+
switch (output.length % 4) {
|
|
69
|
+
case 0:
|
|
70
|
+
break;
|
|
71
|
+
case 2:
|
|
72
|
+
output += '==';
|
|
73
|
+
break;
|
|
74
|
+
case 3:
|
|
75
|
+
output += '=';
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
throw new Error('base64 string is not of the correct length');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
return b64DecodeUnicode(output);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
return atob(output);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function jwtDecode<T = JwtHeader>(
|
|
89
|
+
token: string,
|
|
90
|
+
options: JwtDecodeOptions & { header: true },
|
|
91
|
+
): T;
|
|
92
|
+
export function jwtDecode<T = JwtPayload>(token: string, options?: JwtDecodeOptions): T;
|
|
93
|
+
export function jwtDecode<T = JwtHeader | JwtPayload>(
|
|
94
|
+
token: string,
|
|
95
|
+
options?: JwtDecodeOptions,
|
|
96
|
+
): T {
|
|
97
|
+
if (typeof token !== 'string') {
|
|
98
|
+
throw new InvalidTokenError('Invalid token specified: must be a string');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
options ||= {};
|
|
102
|
+
|
|
103
|
+
const pos = options.header === true ? 0 : 1;
|
|
104
|
+
const part = token.split('.')[pos];
|
|
105
|
+
|
|
106
|
+
if (typeof part !== 'string') {
|
|
107
|
+
throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let decoded: string;
|
|
111
|
+
try {
|
|
112
|
+
decoded = base64UrlDecode(part);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
throw new InvalidTokenError(
|
|
115
|
+
`Invalid token specified: invalid base64 for part #${pos + 1} (${(e as Error).message})`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
return JSON.parse(decoded) as T;
|
|
121
|
+
} catch (e) {
|
|
122
|
+
throw new InvalidTokenError(
|
|
123
|
+
`Invalid token specified: invalid json for part #${pos + 1} (${(e as Error).message})`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
package/src/zklogin/jwt-utils.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// Copyright (c) Mysten Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import type { JwtPayload } from './jwt-decode.js';
|
|
5
|
+
import { jwtDecode } from './jwt-decode.js';
|
|
6
|
+
import { normalizeZkLoginIssuer } from './utils.js';
|
|
7
|
+
|
|
4
8
|
function base64UrlCharTo6Bits(base64UrlChar: string): number[] {
|
|
5
9
|
if (base64UrlChar.length !== 1) {
|
|
6
10
|
throw new Error('Invalid base64Url character: ' + base64UrlChar);
|
|
@@ -111,3 +115,28 @@ export function extractClaimValue<R>(claim: Claim, claimName: string): R {
|
|
|
111
115
|
}
|
|
112
116
|
return value;
|
|
113
117
|
}
|
|
118
|
+
|
|
119
|
+
export function decodeJwt(jwt: string): Omit<JwtPayload, 'iss' | 'aud' | 'sub'> & {
|
|
120
|
+
iss: string;
|
|
121
|
+
aud: string;
|
|
122
|
+
sub: string;
|
|
123
|
+
rawIss: string;
|
|
124
|
+
} {
|
|
125
|
+
const { iss, aud, sub, ...decodedJWT } = jwtDecode(jwt);
|
|
126
|
+
|
|
127
|
+
if (!sub || !iss || !aud) {
|
|
128
|
+
throw new Error('Missing jwt data');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (Array.isArray(aud)) {
|
|
132
|
+
throw new Error('Not supported aud. Aud is an array, string was expected.');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
...decodedJWT,
|
|
137
|
+
iss: normalizeZkLoginIssuer(iss),
|
|
138
|
+
rawIss: iss,
|
|
139
|
+
aud,
|
|
140
|
+
sub,
|
|
141
|
+
};
|
|
142
|
+
}
|
package/src/zklogin/nonce.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { toHex } from '@mysten/bcs';
|
|
5
5
|
import { randomBytes } from '@noble/hashes/utils';
|
|
6
|
-
import {
|
|
6
|
+
import { base64urlnopad } from '@scure/base';
|
|
7
7
|
|
|
8
8
|
import type { PublicKey } from '../cryptography/publickey.js';
|
|
9
9
|
import { poseidonHash } from './poseidon.js';
|
|
@@ -30,7 +30,8 @@ export function generateNonce(publicKey: PublicKey, maxEpoch: number, randomness
|
|
|
30
30
|
const eph_public_key_1 = publicKeyBytes % 2n ** 128n;
|
|
31
31
|
const bigNum = poseidonHash([eph_public_key_0, eph_public_key_1, maxEpoch, BigInt(randomness)]);
|
|
32
32
|
const Z = toPaddedBigEndianBytes(bigNum, 20);
|
|
33
|
-
const nonce =
|
|
33
|
+
const nonce = base64urlnopad.encode(Z);
|
|
34
|
+
|
|
34
35
|
if (nonce.length !== NONCE_LENGTH) {
|
|
35
36
|
throw new Error(`Length of nonce ${nonce} (${nonce.length}) is not equal to ${NONCE_LENGTH}`);
|
|
36
37
|
}
|
package/src/zklogin/publickey.ts
CHANGED
|
@@ -11,9 +11,10 @@ import { SIGNATURE_SCHEME_TO_FLAG } from '../cryptography/signature-scheme.js';
|
|
|
11
11
|
import { SuiGraphQLClient } from '../graphql/client.js';
|
|
12
12
|
import { graphql } from '../graphql/schemas/latest/index.js';
|
|
13
13
|
import { normalizeSuiAddress, SUI_ADDRESS_LENGTH } from '../utils/sui-types.js';
|
|
14
|
+
import type { ZkLoginSignatureInputs } from './bcs.js';
|
|
14
15
|
import { extractClaimValue } from './jwt-utils.js';
|
|
15
16
|
import { parseZkLoginSignature } from './signature.js';
|
|
16
|
-
import { toBigEndianBytes, toPaddedBigEndianBytes } from './utils.js';
|
|
17
|
+
import { normalizeZkLoginIssuer, toBigEndianBytes, toPaddedBigEndianBytes } from './utils.js';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* A zkLogin public identifier
|
|
@@ -46,6 +47,29 @@ export class ZkLoginPublicIdentifier extends PublicKey {
|
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
static fromProof(address: string, proof: ZkLoginSignatureInputs) {
|
|
51
|
+
const { issBase64Details, addressSeed } = proof;
|
|
52
|
+
const iss = extractClaimValue<string>(issBase64Details, 'iss');
|
|
53
|
+
|
|
54
|
+
const legacyPublicKey = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {
|
|
55
|
+
legacyAddress: true,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (legacyPublicKey.toSuiAddress() === address) {
|
|
59
|
+
return legacyPublicKey;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const publicKey = toZkLoginPublicIdentifier(BigInt(addressSeed), iss, {
|
|
63
|
+
legacyAddress: false,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (publicKey.toSuiAddress() !== address) {
|
|
67
|
+
throw new Error('Proof does not match address');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return publicKey;
|
|
71
|
+
}
|
|
72
|
+
|
|
49
73
|
/**
|
|
50
74
|
* Checks if two zkLogin public identifiers are equal
|
|
51
75
|
*/
|
|
@@ -142,7 +166,7 @@ export function toZkLoginPublicIdentifier(
|
|
|
142
166
|
? toBigEndianBytes(addressSeed, 32)
|
|
143
167
|
: toPaddedBigEndianBytes(addressSeed, 32);
|
|
144
168
|
|
|
145
|
-
const issBytes = new TextEncoder().encode(iss);
|
|
169
|
+
const issBytes = new TextEncoder().encode(normalizeZkLoginIssuer(iss));
|
|
146
170
|
const tmp = new Uint8Array(1 + issBytes.length + addressSeedBytesBigEndian.length);
|
|
147
171
|
tmp.set([issBytes.length], 0);
|
|
148
172
|
tmp.set(issBytes, 1);
|
package/src/zklogin/utils.ts
CHANGED