@mysten/sui 2.16.3 → 2.18.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 (138) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/bcs/bcs.d.mts +6 -6
  3. package/dist/bcs/index.d.mts +20 -20
  4. package/dist/graphql/generated/queries.d.mts.map +1 -1
  5. package/dist/graphql/generated/queries.mjs.map +1 -1
  6. package/dist/graphql/generated/tada-env.d.mts +82 -1
  7. package/dist/grpc/client.d.mts +2 -0
  8. package/dist/grpc/client.d.mts.map +1 -1
  9. package/dist/grpc/client.mjs +2 -0
  10. package/dist/grpc/client.mjs.map +1 -1
  11. package/dist/grpc/proto/google/protobuf/struct.mjs +1 -1
  12. package/dist/grpc/proto/google/protobuf/struct.mjs.map +1 -1
  13. package/dist/grpc/proto/google/rpc/status.mjs +1 -1
  14. package/dist/grpc/proto/google/rpc/status.mjs.map +1 -1
  15. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.d.mts +66 -0
  16. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.d.mts.map +1 -0
  17. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.mjs +48 -0
  18. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.client.mjs.map +1 -0
  19. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.d.mts +135 -0
  20. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.d.mts.map +1 -0
  21. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.mjs +144 -0
  22. package/dist/grpc/proto/sui/forking/v1alpha/forking_service.mjs.map +1 -0
  23. package/dist/grpc/proto/sui/rpc/v2/checkpoint.mjs +1 -1
  24. package/dist/grpc/proto/sui/rpc/v2/checkpoint.mjs.map +1 -1
  25. package/dist/grpc/proto/sui/rpc/v2/checkpoint_contents.mjs +3 -3
  26. package/dist/grpc/proto/sui/rpc/v2/checkpoint_contents.mjs.map +1 -1
  27. package/dist/grpc/proto/sui/rpc/v2/checkpoint_summary.mjs +3 -3
  28. package/dist/grpc/proto/sui/rpc/v2/checkpoint_summary.mjs.map +1 -1
  29. package/dist/grpc/proto/sui/rpc/v2/effects.d.mts +71 -3
  30. package/dist/grpc/proto/sui/rpc/v2/effects.d.mts.map +1 -1
  31. package/dist/grpc/proto/sui/rpc/v2/effects.mjs +71 -5
  32. package/dist/grpc/proto/sui/rpc/v2/effects.mjs.map +1 -1
  33. package/dist/grpc/proto/sui/rpc/v2/event.mjs +1 -1
  34. package/dist/grpc/proto/sui/rpc/v2/event.mjs.map +1 -1
  35. package/dist/grpc/proto/sui/rpc/v2/executed_transaction.mjs +2 -2
  36. package/dist/grpc/proto/sui/rpc/v2/executed_transaction.mjs.map +1 -1
  37. package/dist/grpc/proto/sui/rpc/v2/ledger_service.client.d.mts +4 -4
  38. package/dist/grpc/proto/sui/rpc/v2/ledger_service.mjs +3 -3
  39. package/dist/grpc/proto/sui/rpc/v2/ledger_service.mjs.map +1 -1
  40. package/dist/grpc/proto/sui/rpc/v2/move_package.d.mts.map +1 -1
  41. package/dist/grpc/proto/sui/rpc/v2/move_package.mjs +13 -13
  42. package/dist/grpc/proto/sui/rpc/v2/move_package.mjs.map +1 -1
  43. package/dist/grpc/proto/sui/rpc/v2/move_package_service.client.d.mts +4 -4
  44. package/dist/grpc/proto/sui/rpc/v2/move_package_service.mjs +1 -1
  45. package/dist/grpc/proto/sui/rpc/v2/move_package_service.mjs.map +1 -1
  46. package/dist/grpc/proto/sui/rpc/v2/name_service.client.d.mts +4 -4
  47. package/dist/grpc/proto/sui/rpc/v2/object.d.mts.map +1 -1
  48. package/dist/grpc/proto/sui/rpc/v2/object.mjs +1 -1
  49. package/dist/grpc/proto/sui/rpc/v2/object.mjs.map +1 -1
  50. package/dist/grpc/proto/sui/rpc/v2/signature.mjs +3 -3
  51. package/dist/grpc/proto/sui/rpc/v2/signature.mjs.map +1 -1
  52. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.client.d.mts +4 -4
  53. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.d.mts.map +1 -1
  54. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.mjs +1 -1
  55. package/dist/grpc/proto/sui/rpc/v2/signature_verification_service.mjs.map +1 -1
  56. package/dist/grpc/proto/sui/rpc/v2/state_service.client.d.mts +4 -4
  57. package/dist/grpc/proto/sui/rpc/v2/state_service.d.mts.map +1 -1
  58. package/dist/grpc/proto/sui/rpc/v2/state_service.mjs +3 -3
  59. package/dist/grpc/proto/sui/rpc/v2/state_service.mjs.map +1 -1
  60. package/dist/grpc/proto/sui/rpc/v2/subscription_service.client.d.mts +4 -4
  61. package/dist/grpc/proto/sui/rpc/v2/system_state.mjs +2 -2
  62. package/dist/grpc/proto/sui/rpc/v2/system_state.mjs.map +1 -1
  63. package/dist/grpc/proto/sui/rpc/v2/transaction.d.mts.map +1 -1
  64. package/dist/grpc/proto/sui/rpc/v2/transaction.mjs +16 -16
  65. package/dist/grpc/proto/sui/rpc/v2/transaction.mjs.map +1 -1
  66. package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.mjs +4 -4
  67. package/dist/grpc/proto/sui/rpc/v2/transaction_execution_service.mjs.map +1 -1
  68. package/dist/grpc/proto/types.d.mts +3 -2
  69. package/dist/grpc/proto/types.mjs +11 -1
  70. package/dist/grpc/proto/types.mjs.map +1 -1
  71. package/dist/jsonRpc/types/params.d.mts +5 -5
  72. package/dist/transactions/Transaction.d.mts +25 -11
  73. package/dist/transactions/Transaction.d.mts.map +1 -1
  74. package/dist/transactions/Transaction.mjs +8 -3
  75. package/dist/transactions/Transaction.mjs.map +1 -1
  76. package/dist/transactions/index.d.mts +2 -2
  77. package/dist/version.mjs +1 -1
  78. package/dist/version.mjs.map +1 -1
  79. package/dist/zklogin/jwt-utils.d.mts.map +1 -1
  80. package/dist/zklogin/jwt-utils.mjs.map +1 -1
  81. package/dist/zklogin/utils.d.mts.map +1 -1
  82. package/dist/zklogin/utils.mjs +9 -0
  83. package/dist/zklogin/utils.mjs.map +1 -1
  84. package/docs/bcs.md +11 -6
  85. package/docs/clients/core.md +10 -9
  86. package/docs/clients/grpc.md +1 -1
  87. package/docs/index.md +176 -22
  88. package/docs/llms-index.md +6 -9
  89. package/docs/migrations/0.38.md +2 -2
  90. package/docs/migrations/sui-1.0.md +2 -2
  91. package/docs/migrations/sui-2.0/json-rpc-migration.md +76 -33
  92. package/docs/plugins.md +29 -5
  93. package/docs/transactions/basics.md +279 -0
  94. package/docs/transactions/coins-and-balances.md +293 -0
  95. package/docs/transactions/offline.md +192 -0
  96. package/docs/transactions/reference.md +380 -0
  97. package/docs/transactions/signing-and-execution.md +401 -0
  98. package/package.json +27 -27
  99. package/src/graphql/generated/queries.ts +46 -1
  100. package/src/graphql/generated/schema.graphql +49 -3
  101. package/src/graphql/generated/tada-env.ts +97 -1
  102. package/src/grpc/client.ts +3 -0
  103. package/src/grpc/proto/google/protobuf/struct.ts +1 -1
  104. package/src/grpc/proto/google/rpc/error_details.ts +4 -4
  105. package/src/grpc/proto/google/rpc/status.ts +1 -1
  106. package/src/grpc/proto/sui/forking/v1alpha/forking_service.client.ts +125 -0
  107. package/src/grpc/proto/sui/forking/v1alpha/forking_service.ts +230 -0
  108. package/src/grpc/proto/sui/rpc/v2/checkpoint.ts +1 -1
  109. package/src/grpc/proto/sui/rpc/v2/checkpoint_contents.ts +3 -3
  110. package/src/grpc/proto/sui/rpc/v2/checkpoint_summary.ts +3 -3
  111. package/src/grpc/proto/sui/rpc/v2/effects.ts +112 -6
  112. package/src/grpc/proto/sui/rpc/v2/event.ts +1 -1
  113. package/src/grpc/proto/sui/rpc/v2/executed_transaction.ts +2 -2
  114. package/src/grpc/proto/sui/rpc/v2/ledger_service.ts +3 -3
  115. package/src/grpc/proto/sui/rpc/v2/move_package.ts +19 -13
  116. package/src/grpc/proto/sui/rpc/v2/move_package_service.ts +1 -1
  117. package/src/grpc/proto/sui/rpc/v2/object.ts +7 -1
  118. package/src/grpc/proto/sui/rpc/v2/signature.ts +3 -3
  119. package/src/grpc/proto/sui/rpc/v2/signature_verification_service.ts +7 -1
  120. package/src/grpc/proto/sui/rpc/v2/state_service.ts +9 -3
  121. package/src/grpc/proto/sui/rpc/v2/system_state.ts +2 -2
  122. package/src/grpc/proto/sui/rpc/v2/transaction.ts +22 -16
  123. package/src/grpc/proto/sui/rpc/v2/transaction_execution_service.ts +4 -4
  124. package/src/grpc/proto/types.ts +1 -0
  125. package/src/jsonRpc/types/params.ts +5 -5
  126. package/src/transactions/Transaction.ts +36 -5
  127. package/src/transactions/index.ts +1 -0
  128. package/src/version.ts +1 -1
  129. package/src/zklogin/jwt-utils.ts +3 -0
  130. package/src/zklogin/utils.ts +17 -0
  131. package/docs/faucet.md +0 -26
  132. package/docs/hello-sui.md +0 -115
  133. package/docs/install.md +0 -61
  134. package/docs/transaction-building/basics.md +0 -299
  135. package/docs/transaction-building/gas.md +0 -61
  136. package/docs/transaction-building/intents.md +0 -62
  137. package/docs/transaction-building/offline.md +0 -73
  138. package/docs/transaction-building/sponsored-transactions.md +0 -22
package/dist/version.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
- const PACKAGE_VERSION = "2.16.3";
2
+ const PACKAGE_VERSION = "2.18.0";
3
3
 
4
4
  //#endregion
5
5
  export { PACKAGE_VERSION };
@@ -1 +1 @@
1
- {"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"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 = '2.16.3';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
1
+ {"version":3,"file":"version.mjs","names":[],"sources":["../src/version.ts"],"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 = '2.18.0';\n"],"mappings":";AAKA,MAAa,kBAAkB"}
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-utils.d.mts","names":[],"sources":["../../src/zklogin/jwt-utils.ts"],"mappings":";;;iBAsHgB,SAAA,CAAU,GAAA,WAAc,IAAA,CAAK,UAAA;EAC5C,GAAA;EACA,GAAA;EACA,GAAA;EACA,MAAA;AAAA"}
1
+ {"version":3,"file":"jwt-utils.d.mts","names":[],"sources":["../../src/zklogin/jwt-utils.ts"],"mappings":";;;iBAyHgB,SAAA,CAAU,GAAA,WAAc,IAAA,CAAK,UAAA;EAC5C,GAAA;EACA,GAAA;EACA,GAAA;EACA,MAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-utils.mjs","names":["i"],"sources":["../../src/zklogin/jwt-utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { JwtPayload } from './jwt-decode.js';\nimport { jwtDecode } from './jwt-decode.js';\nimport { normalizeZkLoginIssuer } from './utils.js';\n\nfunction base64UrlCharTo6Bits(base64UrlChar: string): number[] {\n\tif (base64UrlChar.length !== 1) {\n\t\tthrow new Error('Invalid base64Url character: ' + base64UrlChar);\n\t}\n\n\t// Define the base64URL character set\n\tconst base64UrlCharacterSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\t// Find the index of the input character in the base64URL character set\n\tconst index = base64UrlCharacterSet.indexOf(base64UrlChar);\n\n\tif (index === -1) {\n\t\tthrow new Error('Invalid base64Url character: ' + base64UrlChar);\n\t}\n\n\t// Convert the index to a 6-bit binary string\n\tconst binaryString = index.toString(2).padStart(6, '0');\n\n\t// Convert the binary string to an array of bits\n\tconst bits = Array.from(binaryString).map(Number);\n\n\treturn bits;\n}\n\nfunction base64UrlStringToBitVector(base64UrlString: string) {\n\tlet bitVector: number[] = [];\n\tfor (let i = 0; i < base64UrlString.length; i++) {\n\t\tconst base64UrlChar = base64UrlString.charAt(i);\n\t\tconst bits = base64UrlCharTo6Bits(base64UrlChar);\n\t\tbitVector = bitVector.concat(bits);\n\t}\n\treturn bitVector;\n}\n\nfunction decodeBase64URL(s: string, i: number): string {\n\tif (s.length < 2) {\n\t\tthrow new Error(`Input (s = ${s}) is not tightly packed because s.length < 2`);\n\t}\n\tlet bits = base64UrlStringToBitVector(s);\n\n\tconst firstCharOffset = i % 4;\n\tif (firstCharOffset === 0) {\n\t\t// skip\n\t} else if (firstCharOffset === 1) {\n\t\tbits = bits.slice(2);\n\t} else if (firstCharOffset === 2) {\n\t\tbits = bits.slice(4);\n\t} else {\n\t\t// (offset == 3)\n\t\tthrow new Error(`Input (s = ${s}) is not tightly packed because i%4 = 3 (i = ${i}))`);\n\t}\n\n\tconst lastCharOffset = (i + s.length - 1) % 4;\n\tif (lastCharOffset === 3) {\n\t\t// skip\n\t} else if (lastCharOffset === 2) {\n\t\tbits = bits.slice(0, bits.length - 2);\n\t} else if (lastCharOffset === 1) {\n\t\tbits = bits.slice(0, bits.length - 4);\n\t} else {\n\t\t// (offset == 0)\n\t\tthrow new Error(\n\t\t\t`Input (s = ${s}) is not tightly packed because (i + s.length - 1)%4 = 0 (i = ${i}))`,\n\t\t);\n\t}\n\n\tif (bits.length % 8 !== 0) {\n\t\tthrow new Error(`We should never reach here...`);\n\t}\n\n\tconst bytes = new Uint8Array(Math.floor(bits.length / 8));\n\tlet currentByteIndex = 0;\n\tfor (let i = 0; i < bits.length; i += 8) {\n\t\tconst bitChunk = bits.slice(i, i + 8);\n\n\t\t// Convert the 8-bit chunk to a byte and add it to the bytes array\n\t\tconst byte = parseInt(bitChunk.join(''), 2);\n\t\tbytes[currentByteIndex++] = byte;\n\t}\n\treturn new TextDecoder().decode(bytes);\n}\n\nfunction verifyExtendedClaim(claim: string) {\n\t// Last character of each extracted_claim must be '}' or ','\n\tif (!(claim.slice(-1) === '}' || claim.slice(-1) === ',')) {\n\t\tthrow new Error('Invalid claim');\n\t}\n\n\t// A hack to parse the JSON key-value pair.. but it should work\n\tconst json = JSON.parse('{' + claim.slice(0, -1) + '}');\n\tif (Object.keys(json).length !== 1) {\n\t\tthrow new Error('Invalid claim');\n\t}\n\tconst key = Object.keys(json)[0];\n\treturn [key, json[key]];\n}\n\nexport type Claim = {\n\tvalue: string;\n\tindexMod4: number;\n};\n\nexport function extractClaimValue<R>(claim: Claim, claimName: string): R {\n\tconst extendedClaim = decodeBase64URL(claim.value, claim.indexMod4);\n\tconst [name, value] = verifyExtendedClaim(extendedClaim);\n\tif (name !== claimName) {\n\t\tthrow new Error(`Invalid field name: found ${name} expected ${claimName}`);\n\t}\n\treturn value;\n}\n\nexport function decodeJwt(jwt: string): Omit<JwtPayload, 'iss' | 'aud' | 'sub'> & {\n\tiss: string;\n\taud: string;\n\tsub: string;\n\trawIss: string;\n} {\n\tconst { iss, aud, sub, ...decodedJWT } = jwtDecode(jwt);\n\n\tif (!sub || !iss || !aud) {\n\t\tthrow new Error('Missing jwt data');\n\t}\n\n\tif (Array.isArray(aud)) {\n\t\tthrow new Error('Not supported aud. Aud is an array, string was expected.');\n\t}\n\n\treturn {\n\t\t...decodedJWT,\n\t\tiss: normalizeZkLoginIssuer(iss),\n\t\trawIss: iss,\n\t\taud,\n\t\tsub,\n\t};\n}\n"],"mappings":";;;;AAOA,SAAS,qBAAqB,eAAiC;AAC9D,KAAI,cAAc,WAAW,EAC5B,OAAM,IAAI,MAAM,kCAAkC,cAAc;CAOjE,MAAM,QAHwB,mEAGM,QAAQ,cAAc;AAE1D,KAAI,UAAU,GACb,OAAM,IAAI,MAAM,kCAAkC,cAAc;CAIjE,MAAM,eAAe,MAAM,SAAS,EAAE,CAAC,SAAS,GAAG,IAAI;AAKvD,QAFa,MAAM,KAAK,aAAa,CAAC,IAAI,OAAO;;AAKlD,SAAS,2BAA2B,iBAAyB;CAC5D,IAAI,YAAsB,EAAE;AAC5B,MAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;EAEhD,MAAM,OAAO,qBADS,gBAAgB,OAAO,EAAE,CACC;AAChD,cAAY,UAAU,OAAO,KAAK;;AAEnC,QAAO;;AAGR,SAAS,gBAAgB,GAAW,GAAmB;AACtD,KAAI,EAAE,SAAS,EACd,OAAM,IAAI,MAAM,cAAc,EAAE,8CAA8C;CAE/E,IAAI,OAAO,2BAA2B,EAAE;CAExC,MAAM,kBAAkB,IAAI;AAC5B,KAAI,oBAAoB,GAAG,YAEhB,oBAAoB,EAC9B,QAAO,KAAK,MAAM,EAAE;UACV,oBAAoB,EAC9B,QAAO,KAAK,MAAM,EAAE;KAGpB,OAAM,IAAI,MAAM,cAAc,EAAE,+CAA+C,EAAE,IAAI;CAGtF,MAAM,kBAAkB,IAAI,EAAE,SAAS,KAAK;AAC5C,KAAI,mBAAmB,GAAG,YAEf,mBAAmB,EAC7B,QAAO,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE;UAC3B,mBAAmB,EAC7B,QAAO,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE;KAGrC,OAAM,IAAI,MACT,cAAc,EAAE,gEAAgE,EAAE,IAClF;AAGF,KAAI,KAAK,SAAS,MAAM,EACvB,OAAM,IAAI,MAAM,gCAAgC;CAGjD,MAAM,QAAQ,IAAI,WAAW,KAAK,MAAM,KAAK,SAAS,EAAE,CAAC;CACzD,IAAI,mBAAmB;AACvB,MAAK,IAAIA,MAAI,GAAGA,MAAI,KAAK,QAAQ,OAAK,GAAG;EACxC,MAAM,WAAW,KAAK,MAAMA,KAAGA,MAAI,EAAE;EAGrC,MAAM,OAAO,SAAS,SAAS,KAAK,GAAG,EAAE,EAAE;AAC3C,QAAM,sBAAsB;;AAE7B,QAAO,IAAI,aAAa,CAAC,OAAO,MAAM;;AAGvC,SAAS,oBAAoB,OAAe;AAE3C,KAAI,EAAE,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,MAAM,GAAG,KAAK,KACpD,OAAM,IAAI,MAAM,gBAAgB;CAIjC,MAAM,OAAO,KAAK,MAAM,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI;AACvD,KAAI,OAAO,KAAK,KAAK,CAAC,WAAW,EAChC,OAAM,IAAI,MAAM,gBAAgB;CAEjC,MAAM,MAAM,OAAO,KAAK,KAAK,CAAC;AAC9B,QAAO,CAAC,KAAK,KAAK,KAAK;;AAQxB,SAAgB,kBAAqB,OAAc,WAAsB;CAExE,MAAM,CAAC,MAAM,SAAS,oBADA,gBAAgB,MAAM,OAAO,MAAM,UAAU,CACX;AACxD,KAAI,SAAS,UACZ,OAAM,IAAI,MAAM,6BAA6B,KAAK,YAAY,YAAY;AAE3E,QAAO;;AAGR,SAAgB,UAAU,KAKxB;CACD,MAAM,EAAE,KAAK,KAAK,KAAK,GAAG,eAAe,UAAU,IAAI;AAEvD,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IACpB,OAAM,IAAI,MAAM,mBAAmB;AAGpC,KAAI,MAAM,QAAQ,IAAI,CACrB,OAAM,IAAI,MAAM,2DAA2D;AAG5E,QAAO;EACN,GAAG;EACH,KAAK,uBAAuB,IAAI;EAChC,QAAQ;EACR;EACA;EACA"}
1
+ {"version":3,"file":"jwt-utils.mjs","names":["i"],"sources":["../../src/zklogin/jwt-utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { JwtPayload } from './jwt-decode.js';\nimport { jwtDecode } from './jwt-decode.js';\nimport { normalizeZkLoginIssuer } from './utils.js';\n\nfunction base64UrlCharTo6Bits(base64UrlChar: string): number[] {\n\tif (base64UrlChar.length !== 1) {\n\t\tthrow new Error('Invalid base64Url character: ' + base64UrlChar);\n\t}\n\n\t// Define the base64URL character set\n\tconst base64UrlCharacterSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\t// Find the index of the input character in the base64URL character set\n\tconst index = base64UrlCharacterSet.indexOf(base64UrlChar);\n\n\tif (index === -1) {\n\t\tthrow new Error('Invalid base64Url character: ' + base64UrlChar);\n\t}\n\n\t// Convert the index to a 6-bit binary string\n\tconst binaryString = index.toString(2).padStart(6, '0');\n\n\t// Convert the binary string to an array of bits\n\tconst bits = Array.from(binaryString).map(Number);\n\n\treturn bits;\n}\n\nfunction base64UrlStringToBitVector(base64UrlString: string) {\n\tlet bitVector: number[] = [];\n\tfor (let i = 0; i < base64UrlString.length; i++) {\n\t\tconst base64UrlChar = base64UrlString.charAt(i);\n\t\tconst bits = base64UrlCharTo6Bits(base64UrlChar);\n\t\tbitVector = bitVector.concat(bits);\n\t}\n\treturn bitVector;\n}\n\nfunction decodeBase64URL(s: string, i: number): string {\n\tif (s.length < 2) {\n\t\tthrow new Error(`Input (s = ${s}) is not tightly packed because s.length < 2`);\n\t}\n\tlet bits = base64UrlStringToBitVector(s);\n\n\tconst firstCharOffset = i % 4;\n\tif (firstCharOffset === 0) {\n\t\t// skip\n\t} else if (firstCharOffset === 1) {\n\t\tbits = bits.slice(2);\n\t} else if (firstCharOffset === 2) {\n\t\tbits = bits.slice(4);\n\t} else {\n\t\t// (offset == 3)\n\t\tthrow new Error(`Input (s = ${s}) is not tightly packed because i%4 = 3 (i = ${i}))`);\n\t}\n\n\tconst lastCharOffset = (i + s.length - 1) % 4;\n\tif (lastCharOffset === 3) {\n\t\t// skip\n\t} else if (lastCharOffset === 2) {\n\t\tbits = bits.slice(0, bits.length - 2);\n\t} else if (lastCharOffset === 1) {\n\t\tbits = bits.slice(0, bits.length - 4);\n\t} else {\n\t\t// (offset == 0)\n\t\tthrow new Error(\n\t\t\t`Input (s = ${s}) is not tightly packed because (i + s.length - 1)%4 = 0 (i = ${i}))`,\n\t\t);\n\t}\n\n\tif (bits.length % 8 !== 0) {\n\t\tthrow new Error(`We should never reach here...`);\n\t}\n\n\tconst bytes = new Uint8Array(Math.floor(bits.length / 8));\n\tlet currentByteIndex = 0;\n\tfor (let i = 0; i < bits.length; i += 8) {\n\t\tconst bitChunk = bits.slice(i, i + 8);\n\n\t\t// Convert the 8-bit chunk to a byte and add it to the bytes array\n\t\tconst byte = parseInt(bitChunk.join(''), 2);\n\t\tbytes[currentByteIndex++] = byte;\n\t}\n\treturn new TextDecoder().decode(bytes);\n}\n\nfunction verifyExtendedClaim(claim: string) {\n\t// Last character of each extracted_claim must be '}' or ','\n\tif (!(claim.slice(-1) === '}' || claim.slice(-1) === ',')) {\n\t\tthrow new Error('Invalid claim');\n\t}\n\n\t// A hack to parse the JSON key-value pair.. but it should work\n\tconst json = JSON.parse('{' + claim.slice(0, -1) + '}');\n\tif (Object.keys(json).length !== 1) {\n\t\tthrow new Error('Invalid claim');\n\t}\n\tconst key = Object.keys(json)[0];\n\treturn [key, json[key]];\n}\n\nexport type Claim = {\n\tvalue: string;\n\tindexMod4: number;\n};\n\nexport function extractClaimValue<R>(claim: Claim, claimName: string): R {\n\tconst extendedClaim = decodeBase64URL(claim.value, claim.indexMod4);\n\tconst [name, value] = verifyExtendedClaim(extendedClaim);\n\tif (name !== claimName) {\n\t\tthrow new Error(`Invalid field name: found ${name} expected ${claimName}`);\n\t}\n\treturn value;\n}\n\n// TODO: root cause of the claim-escaping bug — jwtDecode resolves JSON escapes, but the\n// circuit derives the address seed from raw JWT bytes, so escaped claim values decode\n// differently here than the circuit hashes. Real fix: parse claims over raw bytes.\nexport function decodeJwt(jwt: string): Omit<JwtPayload, 'iss' | 'aud' | 'sub'> & {\n\tiss: string;\n\taud: string;\n\tsub: string;\n\trawIss: string;\n} {\n\tconst { iss, aud, sub, ...decodedJWT } = jwtDecode(jwt);\n\n\tif (!sub || !iss || !aud) {\n\t\tthrow new Error('Missing jwt data');\n\t}\n\n\tif (Array.isArray(aud)) {\n\t\tthrow new Error('Not supported aud. Aud is an array, string was expected.');\n\t}\n\n\treturn {\n\t\t...decodedJWT,\n\t\tiss: normalizeZkLoginIssuer(iss),\n\t\trawIss: iss,\n\t\taud,\n\t\tsub,\n\t};\n}\n"],"mappings":";;;;AAOA,SAAS,qBAAqB,eAAiC;AAC9D,KAAI,cAAc,WAAW,EAC5B,OAAM,IAAI,MAAM,kCAAkC,cAAc;CAOjE,MAAM,QAHwB,mEAGM,QAAQ,cAAc;AAE1D,KAAI,UAAU,GACb,OAAM,IAAI,MAAM,kCAAkC,cAAc;CAIjE,MAAM,eAAe,MAAM,SAAS,EAAE,CAAC,SAAS,GAAG,IAAI;AAKvD,QAFa,MAAM,KAAK,aAAa,CAAC,IAAI,OAAO;;AAKlD,SAAS,2BAA2B,iBAAyB;CAC5D,IAAI,YAAsB,EAAE;AAC5B,MAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;EAEhD,MAAM,OAAO,qBADS,gBAAgB,OAAO,EAAE,CACC;AAChD,cAAY,UAAU,OAAO,KAAK;;AAEnC,QAAO;;AAGR,SAAS,gBAAgB,GAAW,GAAmB;AACtD,KAAI,EAAE,SAAS,EACd,OAAM,IAAI,MAAM,cAAc,EAAE,8CAA8C;CAE/E,IAAI,OAAO,2BAA2B,EAAE;CAExC,MAAM,kBAAkB,IAAI;AAC5B,KAAI,oBAAoB,GAAG,YAEhB,oBAAoB,EAC9B,QAAO,KAAK,MAAM,EAAE;UACV,oBAAoB,EAC9B,QAAO,KAAK,MAAM,EAAE;KAGpB,OAAM,IAAI,MAAM,cAAc,EAAE,+CAA+C,EAAE,IAAI;CAGtF,MAAM,kBAAkB,IAAI,EAAE,SAAS,KAAK;AAC5C,KAAI,mBAAmB,GAAG,YAEf,mBAAmB,EAC7B,QAAO,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE;UAC3B,mBAAmB,EAC7B,QAAO,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE;KAGrC,OAAM,IAAI,MACT,cAAc,EAAE,gEAAgE,EAAE,IAClF;AAGF,KAAI,KAAK,SAAS,MAAM,EACvB,OAAM,IAAI,MAAM,gCAAgC;CAGjD,MAAM,QAAQ,IAAI,WAAW,KAAK,MAAM,KAAK,SAAS,EAAE,CAAC;CACzD,IAAI,mBAAmB;AACvB,MAAK,IAAIA,MAAI,GAAGA,MAAI,KAAK,QAAQ,OAAK,GAAG;EACxC,MAAM,WAAW,KAAK,MAAMA,KAAGA,MAAI,EAAE;EAGrC,MAAM,OAAO,SAAS,SAAS,KAAK,GAAG,EAAE,EAAE;AAC3C,QAAM,sBAAsB;;AAE7B,QAAO,IAAI,aAAa,CAAC,OAAO,MAAM;;AAGvC,SAAS,oBAAoB,OAAe;AAE3C,KAAI,EAAE,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,MAAM,GAAG,KAAK,KACpD,OAAM,IAAI,MAAM,gBAAgB;CAIjC,MAAM,OAAO,KAAK,MAAM,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI;AACvD,KAAI,OAAO,KAAK,KAAK,CAAC,WAAW,EAChC,OAAM,IAAI,MAAM,gBAAgB;CAEjC,MAAM,MAAM,OAAO,KAAK,KAAK,CAAC;AAC9B,QAAO,CAAC,KAAK,KAAK,KAAK;;AAQxB,SAAgB,kBAAqB,OAAc,WAAsB;CAExE,MAAM,CAAC,MAAM,SAAS,oBADA,gBAAgB,MAAM,OAAO,MAAM,UAAU,CACX;AACxD,KAAI,SAAS,UACZ,OAAM,IAAI,MAAM,6BAA6B,KAAK,YAAY,YAAY;AAE3E,QAAO;;AAMR,SAAgB,UAAU,KAKxB;CACD,MAAM,EAAE,KAAK,KAAK,KAAK,GAAG,eAAe,UAAU,IAAI;AAEvD,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IACpB,OAAM,IAAI,MAAM,mBAAmB;AAGpC,KAAI,MAAM,QAAQ,IAAI,CACrB,OAAM,IAAI,MAAM,2DAA2D;AAG5E,QAAO;EACN,GAAG;EACH,KAAK,uBAAuB,IAAI;EAChC,QAAQ;EACR;EACA;EACA"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/zklogin/utils.ts"],"mappings":";;;iBAwBgB,sBAAA,CAAuB,GAAA,UAAa,KAAA,WAAgB,UAAA;AAAA,iBAMpD,gBAAA,CAAiB,GAAA,UAAa,KAAA,WAAgB,UAAA;AAAA,iBAY9C,6BAAA,CAA8B,SAAA,EAAW,SAAA;AAAA,iBA8BzC,mBAAA,CAAoB,GAAA,UAAa,OAAA;AAAA,iBAiBjC,cAAA,CACf,IAAA,mBACA,IAAA,UACA,KAAA,UACA,GAAA,UACA,eAAA,WACA,gBAAA,WACA,cAAA"}
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/zklogin/utils.ts"],"mappings":";;;iBAwBgB,sBAAA,CAAuB,GAAA,UAAa,KAAA,WAAgB,UAAA;AAAA,iBAMpD,gBAAA,CAAiB,GAAA,UAAa,KAAA,WAAgB,UAAA;AAAA,iBAY9C,6BAAA,CAA8B,SAAA,EAAW,SAAA;AAAA,iBA8BzC,mBAAA,CAAoB,GAAA,UAAa,OAAA;AAAA,iBA+BjC,cAAA,CACf,IAAA,mBACA,IAAA,UACA,KAAA,UACA,GAAA,UACA,eAAA,WACA,gBAAA,WACA,cAAA"}
@@ -45,7 +45,16 @@ function hashASCIIStrToField(str, maxSize) {
45
45
  if (str.length > maxSize) throw new Error(`String ${str} is longer than ${maxSize} chars`);
46
46
  return poseidonHash(chunkArray(str.padEnd(maxSize, String.fromCharCode(0)).split("").map((c) => c.charCodeAt(0)), PACK_WIDTH / 8).map((chunk) => bytesBEToBigInt(chunk)));
47
47
  }
48
+ function assertNoJsonEscape(value, label) {
49
+ for (let i = 0; i < value.length; i++) {
50
+ const c = value.charCodeAt(i);
51
+ if (c < 32 || c === 34 || c === 92) throw new Error(`zkLogin ${label} contains a JSON-escaped character (code ${c}); the circuit hashes raw JWT bytes, so claim values with escapes are not supported`);
52
+ }
53
+ }
48
54
  function genAddressSeed(salt, name, value, aud, max_name_length = MAX_KEY_CLAIM_NAME_LENGTH, max_value_length = MAX_KEY_CLAIM_VALUE_LENGTH, max_aud_length = MAX_AUD_VALUE_LENGTH) {
55
+ assertNoJsonEscape(name, "key claim name");
56
+ assertNoJsonEscape(value, "key claim value");
57
+ assertNoJsonEscape(aud, "aud");
49
58
  return poseidonHash([
50
59
  hashASCIIStrToField(name, max_name_length),
51
60
  hashASCIIStrToField(value, max_value_length),
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/zklogin/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { hexToBytes } from '@noble/hashes/utils.js';\n\nimport type { PublicKey } from '../cryptography/publickey.js';\nimport { poseidonHash } from './poseidon.js';\n\nconst MAX_KEY_CLAIM_NAME_LENGTH = 32;\nconst MAX_KEY_CLAIM_VALUE_LENGTH = 115;\nconst MAX_AUD_VALUE_LENGTH = 145;\nconst PACK_WIDTH = 248;\n\nfunction findFirstNonZeroIndex(bytes: Uint8Array) {\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tif (bytes[i] !== 0) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n// Derive bytearray from num where the bytearray is padded to the left with 0s to the specified width.\nexport function toPaddedBigEndianBytes(num: bigint, width: number): Uint8Array {\n\tconst hex = num.toString(16);\n\treturn hexToBytes(hex.padStart(width * 2, '0').slice(-width * 2));\n}\n\n// Derive bytearray from num where the bytearray is not padded with 0.\nexport function toBigEndianBytes(num: bigint, width: number): Uint8Array {\n\tconst bytes = toPaddedBigEndianBytes(num, width);\n\n\tconst firstNonZeroIndex = findFirstNonZeroIndex(bytes);\n\n\tif (firstNonZeroIndex === -1) {\n\t\treturn new Uint8Array([0]);\n\t}\n\n\treturn bytes.slice(firstNonZeroIndex);\n}\n\nexport function getExtendedEphemeralPublicKey(publicKey: PublicKey) {\n\treturn publicKey.toSuiPublicKey();\n}\n\n/**\n * Splits an array into chunks of size chunk_size. If the array is not evenly\n * divisible by chunk_size, the first chunk will be smaller than chunk_size.\n *\n * E.g., arrayChunk([1, 2, 3, 4, 5], 2) => [[1], [2, 3], [4, 5]]\n *\n * Note: Can be made more efficient by avoiding the reverse() calls.\n */\nexport function chunkArray<T>(array: T[], chunk_size: number): T[][] {\n\tconst chunks = Array(Math.ceil(array.length / chunk_size));\n\tconst revArray = array.reverse();\n\tfor (let i = 0; i < chunks.length; i++) {\n\t\tchunks[i] = revArray.slice(i * chunk_size, (i + 1) * chunk_size).reverse();\n\t}\n\treturn chunks.reverse();\n}\n\nfunction bytesBEToBigInt(bytes: number[]): bigint {\n\tconst hex = bytes.map((b) => b.toString(16).padStart(2, '0')).join('');\n\tif (hex.length === 0) {\n\t\treturn BigInt(0);\n\t}\n\treturn BigInt('0x' + hex);\n}\n\n// hashes an ASCII string to a field element\nexport function hashASCIIStrToField(str: string, maxSize: number) {\n\tif (str.length > maxSize) {\n\t\tthrow new Error(`String ${str} is longer than ${maxSize} chars`);\n\t}\n\n\t// Note: Padding with zeroes is safe because we are only using this function to map human-readable sequence of bytes.\n\t// So the ASCII values of those characters will never be zero (null character).\n\tconst strPadded = str\n\t\t.padEnd(maxSize, String.fromCharCode(0))\n\t\t.split('')\n\t\t.map((c) => c.charCodeAt(0));\n\n\tconst chunkSize = PACK_WIDTH / 8;\n\tconst packed = chunkArray(strPadded, chunkSize).map((chunk) => bytesBEToBigInt(chunk));\n\treturn poseidonHash(packed);\n}\n\nexport function genAddressSeed(\n\tsalt: string | bigint,\n\tname: string,\n\tvalue: string,\n\taud: string,\n\tmax_name_length = MAX_KEY_CLAIM_NAME_LENGTH,\n\tmax_value_length = MAX_KEY_CLAIM_VALUE_LENGTH,\n\tmax_aud_length = MAX_AUD_VALUE_LENGTH,\n): bigint {\n\treturn poseidonHash([\n\t\thashASCIIStrToField(name, max_name_length),\n\t\thashASCIIStrToField(value, max_value_length),\n\t\thashASCIIStrToField(aud, max_aud_length),\n\t\tposeidonHash([BigInt(salt)]),\n\t]);\n}\n\nexport function normalizeZkLoginIssuer(iss: string) {\n\tif (iss === 'accounts.google.com') {\n\t\treturn 'https://accounts.google.com';\n\t}\n\treturn iss;\n}\n"],"mappings":";;;;AAQA,MAAM,4BAA4B;AAClC,MAAM,6BAA6B;AACnC,MAAM,uBAAuB;AAC7B,MAAM,aAAa;AAEnB,SAAS,sBAAsB,OAAmB;AACjD,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IACjC,KAAI,MAAM,OAAO,EAChB,QAAO;AAIT,QAAO;;AAIR,SAAgB,uBAAuB,KAAa,OAA2B;AAE9E,QAAO,WADK,IAAI,SAAS,GAAG,CACN,SAAS,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;;AAIlE,SAAgB,iBAAiB,KAAa,OAA2B;CACxE,MAAM,QAAQ,uBAAuB,KAAK,MAAM;CAEhD,MAAM,oBAAoB,sBAAsB,MAAM;AAEtD,KAAI,sBAAsB,GACzB,QAAO,IAAI,WAAW,CAAC,EAAE,CAAC;AAG3B,QAAO,MAAM,MAAM,kBAAkB;;AAGtC,SAAgB,8BAA8B,WAAsB;AACnE,QAAO,UAAU,gBAAgB;;;;;;;;;;AAWlC,SAAgB,WAAc,OAAY,YAA2B;CACpE,MAAM,SAAS,MAAM,KAAK,KAAK,MAAM,SAAS,WAAW,CAAC;CAC1D,MAAM,WAAW,MAAM,SAAS;AAChC,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IAClC,QAAO,KAAK,SAAS,MAAM,IAAI,aAAa,IAAI,KAAK,WAAW,CAAC,SAAS;AAE3E,QAAO,OAAO,SAAS;;AAGxB,SAAS,gBAAgB,OAAyB;CACjD,MAAM,MAAM,MAAM,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG;AACtE,KAAI,IAAI,WAAW,EAClB,QAAO,OAAO,EAAE;AAEjB,QAAO,OAAO,OAAO,IAAI;;AAI1B,SAAgB,oBAAoB,KAAa,SAAiB;AACjE,KAAI,IAAI,SAAS,QAChB,OAAM,IAAI,MAAM,UAAU,IAAI,kBAAkB,QAAQ,QAAQ;AAYjE,QAAO,aADQ,WANG,IAChB,OAAO,SAAS,OAAO,aAAa,EAAE,CAAC,CACvC,MAAM,GAAG,CACT,KAAK,MAAM,EAAE,WAAW,EAAE,CAAC,EAEX,aAAa,EACgB,CAAC,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAC3D;;AAG5B,SAAgB,eACf,MACA,MACA,OACA,KACA,kBAAkB,2BAClB,mBAAmB,4BACnB,iBAAiB,sBACR;AACT,QAAO,aAAa;EACnB,oBAAoB,MAAM,gBAAgB;EAC1C,oBAAoB,OAAO,iBAAiB;EAC5C,oBAAoB,KAAK,eAAe;EACxC,aAAa,CAAC,OAAO,KAAK,CAAC,CAAC;EAC5B,CAAC;;AAGH,SAAgB,uBAAuB,KAAa;AACnD,KAAI,QAAQ,sBACX,QAAO;AAER,QAAO"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/zklogin/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { hexToBytes } from '@noble/hashes/utils.js';\n\nimport type { PublicKey } from '../cryptography/publickey.js';\nimport { poseidonHash } from './poseidon.js';\n\nconst MAX_KEY_CLAIM_NAME_LENGTH = 32;\nconst MAX_KEY_CLAIM_VALUE_LENGTH = 115;\nconst MAX_AUD_VALUE_LENGTH = 145;\nconst PACK_WIDTH = 248;\n\nfunction findFirstNonZeroIndex(bytes: Uint8Array) {\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tif (bytes[i] !== 0) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n// Derive bytearray from num where the bytearray is padded to the left with 0s to the specified width.\nexport function toPaddedBigEndianBytes(num: bigint, width: number): Uint8Array {\n\tconst hex = num.toString(16);\n\treturn hexToBytes(hex.padStart(width * 2, '0').slice(-width * 2));\n}\n\n// Derive bytearray from num where the bytearray is not padded with 0.\nexport function toBigEndianBytes(num: bigint, width: number): Uint8Array {\n\tconst bytes = toPaddedBigEndianBytes(num, width);\n\n\tconst firstNonZeroIndex = findFirstNonZeroIndex(bytes);\n\n\tif (firstNonZeroIndex === -1) {\n\t\treturn new Uint8Array([0]);\n\t}\n\n\treturn bytes.slice(firstNonZeroIndex);\n}\n\nexport function getExtendedEphemeralPublicKey(publicKey: PublicKey) {\n\treturn publicKey.toSuiPublicKey();\n}\n\n/**\n * Splits an array into chunks of size chunk_size. If the array is not evenly\n * divisible by chunk_size, the first chunk will be smaller than chunk_size.\n *\n * E.g., arrayChunk([1, 2, 3, 4, 5], 2) => [[1], [2, 3], [4, 5]]\n *\n * Note: Can be made more efficient by avoiding the reverse() calls.\n */\nexport function chunkArray<T>(array: T[], chunk_size: number): T[][] {\n\tconst chunks = Array(Math.ceil(array.length / chunk_size));\n\tconst revArray = array.reverse();\n\tfor (let i = 0; i < chunks.length; i++) {\n\t\tchunks[i] = revArray.slice(i * chunk_size, (i + 1) * chunk_size).reverse();\n\t}\n\treturn chunks.reverse();\n}\n\nfunction bytesBEToBigInt(bytes: number[]): bigint {\n\tconst hex = bytes.map((b) => b.toString(16).padStart(2, '0')).join('');\n\tif (hex.length === 0) {\n\t\treturn BigInt(0);\n\t}\n\treturn BigInt('0x' + hex);\n}\n\n// hashes an ASCII string to a field element\nexport function hashASCIIStrToField(str: string, maxSize: number) {\n\tif (str.length > maxSize) {\n\t\tthrow new Error(`String ${str} is longer than ${maxSize} chars`);\n\t}\n\n\t// Note: Padding with zeroes is safe because we are only using this function to map human-readable sequence of bytes.\n\t// So the ASCII values of those characters will never be zero (null character).\n\tconst strPadded = str\n\t\t.padEnd(maxSize, String.fromCharCode(0))\n\t\t.split('')\n\t\t.map((c) => c.charCodeAt(0));\n\n\tconst chunkSize = PACK_WIDTH / 8;\n\tconst packed = chunkArray(strPadded, chunkSize).map((chunk) => bytesBEToBigInt(chunk));\n\treturn poseidonHash(packed);\n}\n\n// Reject claim inputs whose decoded form reveals a JSON escape ('\"', '\\', control char):\n// the circuit hashes raw JWT bytes, so an escaped value would derive a different address.\nfunction assertNoJsonEscape(value: string, label: string) {\n\tfor (let i = 0; i < value.length; i++) {\n\t\tconst c = value.charCodeAt(i);\n\t\tif (c < 0x20 || c === 0x22 || c === 0x5c) {\n\t\t\tthrow new Error(\n\t\t\t\t`zkLogin ${label} contains a JSON-escaped character (code ${c}); the circuit ` +\n\t\t\t\t\t`hashes raw JWT bytes, so claim values with escapes are not supported`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport function genAddressSeed(\n\tsalt: string | bigint,\n\tname: string,\n\tvalue: string,\n\taud: string,\n\tmax_name_length = MAX_KEY_CLAIM_NAME_LENGTH,\n\tmax_value_length = MAX_KEY_CLAIM_VALUE_LENGTH,\n\tmax_aud_length = MAX_AUD_VALUE_LENGTH,\n): bigint {\n\tassertNoJsonEscape(name, 'key claim name');\n\tassertNoJsonEscape(value, 'key claim value');\n\tassertNoJsonEscape(aud, 'aud');\n\treturn poseidonHash([\n\t\thashASCIIStrToField(name, max_name_length),\n\t\thashASCIIStrToField(value, max_value_length),\n\t\thashASCIIStrToField(aud, max_aud_length),\n\t\tposeidonHash([BigInt(salt)]),\n\t]);\n}\n\nexport function normalizeZkLoginIssuer(iss: string) {\n\tif (iss === 'accounts.google.com') {\n\t\treturn 'https://accounts.google.com';\n\t}\n\treturn iss;\n}\n"],"mappings":";;;;AAQA,MAAM,4BAA4B;AAClC,MAAM,6BAA6B;AACnC,MAAM,uBAAuB;AAC7B,MAAM,aAAa;AAEnB,SAAS,sBAAsB,OAAmB;AACjD,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IACjC,KAAI,MAAM,OAAO,EAChB,QAAO;AAIT,QAAO;;AAIR,SAAgB,uBAAuB,KAAa,OAA2B;AAE9E,QAAO,WADK,IAAI,SAAS,GAAG,CACN,SAAS,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;;AAIlE,SAAgB,iBAAiB,KAAa,OAA2B;CACxE,MAAM,QAAQ,uBAAuB,KAAK,MAAM;CAEhD,MAAM,oBAAoB,sBAAsB,MAAM;AAEtD,KAAI,sBAAsB,GACzB,QAAO,IAAI,WAAW,CAAC,EAAE,CAAC;AAG3B,QAAO,MAAM,MAAM,kBAAkB;;AAGtC,SAAgB,8BAA8B,WAAsB;AACnE,QAAO,UAAU,gBAAgB;;;;;;;;;;AAWlC,SAAgB,WAAc,OAAY,YAA2B;CACpE,MAAM,SAAS,MAAM,KAAK,KAAK,MAAM,SAAS,WAAW,CAAC;CAC1D,MAAM,WAAW,MAAM,SAAS;AAChC,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IAClC,QAAO,KAAK,SAAS,MAAM,IAAI,aAAa,IAAI,KAAK,WAAW,CAAC,SAAS;AAE3E,QAAO,OAAO,SAAS;;AAGxB,SAAS,gBAAgB,OAAyB;CACjD,MAAM,MAAM,MAAM,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG;AACtE,KAAI,IAAI,WAAW,EAClB,QAAO,OAAO,EAAE;AAEjB,QAAO,OAAO,OAAO,IAAI;;AAI1B,SAAgB,oBAAoB,KAAa,SAAiB;AACjE,KAAI,IAAI,SAAS,QAChB,OAAM,IAAI,MAAM,UAAU,IAAI,kBAAkB,QAAQ,QAAQ;AAYjE,QAAO,aADQ,WANG,IAChB,OAAO,SAAS,OAAO,aAAa,EAAE,CAAC,CACvC,MAAM,GAAG,CACT,KAAK,MAAM,EAAE,WAAW,EAAE,CAAC,EAEX,aAAa,EACgB,CAAC,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAC3D;;AAK5B,SAAS,mBAAmB,OAAe,OAAe;AACzD,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACtC,MAAM,IAAI,MAAM,WAAW,EAAE;AAC7B,MAAI,IAAI,MAAQ,MAAM,MAAQ,MAAM,GACnC,OAAM,IAAI,MACT,WAAW,MAAM,2CAA2C,EAAE,qFAE9D;;;AAKJ,SAAgB,eACf,MACA,MACA,OACA,KACA,kBAAkB,2BAClB,mBAAmB,4BACnB,iBAAiB,sBACR;AACT,oBAAmB,MAAM,iBAAiB;AAC1C,oBAAmB,OAAO,kBAAkB;AAC5C,oBAAmB,KAAK,MAAM;AAC9B,QAAO,aAAa;EACnB,oBAAoB,MAAM,gBAAgB;EAC1C,oBAAoB,OAAO,iBAAiB;EAC5C,oBAAoB,KAAK,eAAe;EACxC,aAAa,CAAC,OAAO,KAAK,CAAC,CAAC;EAC5B,CAAC;;AAGH,SAAgB,uBAAuB,KAAa;AACnD,KAAI,QAAQ,sBACX,QAAO;AAER,QAAO"}
package/docs/bcs.md CHANGED
@@ -35,7 +35,6 @@ the following pre-defined schemes:
35
35
  - `SharedObjectRef`
36
36
  - `StructTag`
37
37
  - `SuiObjectRef`
38
- - `Transaction`
39
38
  - `TransactionData`
40
39
  - `TransactionDataV1`
41
40
  - `TransactionExpiration`
@@ -85,12 +84,18 @@ object response, so you typically only need `content`.
85
84
 
86
85
  ```typescript
87
86
 
88
- // Parse a full object envelope (from objectBcs include option)
89
- const envelope = bcs.Object.parse(object.objectBcs);
90
- console.log('Owner:', envelope.owner);
91
- console.log('Inner struct bytes:', envelope.data.Move.contents);
87
+ // Parse a BCS-encoded object
88
+ const { objects } = await grpcClient.getObjects({
89
+ objectIds: [objectId],
90
+ include: { objectBcs: true },
91
+ });
92
+
93
+ const parsed = bcs.Object.parse(objects[0].objectBcs);
94
+ console.log('Owner:', parsed.owner);
95
+ console.log('Previous Transaction:', parsed.previousTransaction);
96
+ console.log('Storage Rebate:', parsed.storageRebate);
92
97
 
93
- // Serialize a full object envelope
98
+ // Serialize an object
94
99
  const serialized = bcs.Object.serialize({
95
100
  data: {
96
101
  Move: {
@@ -178,13 +178,14 @@ The `display` field is `null` when the object's type has no registered Display t
178
178
  Get the balance of a specific coin type for an owner.
179
179
 
180
180
  ```typescript
181
- const balance = await client.core.getBalance({
181
+ const { balance } = await client.core.getBalance({
182
182
  owner: '0xabc...',
183
183
  coinType: '0x2::sui::SUI', // Optional, defaults to SUI
184
184
  });
185
185
 
186
- console.log(balance.totalBalance); // Total balance as bigint
187
- console.log(balance.coinObjectCount); // Number of coin objects
186
+ console.log(balance.balance); // Total balance (coin objects + address balance)
187
+ console.log(balance.coinBalance); // Balance from coin objects only
188
+ console.log(balance.addressBalance); // Balance from address balance only
188
189
  ```
189
190
 
190
191
  ### `listBalances`
@@ -197,7 +198,7 @@ const { balances } = await client.core.listBalances({
197
198
  });
198
199
 
199
200
  for (const balance of balances) {
200
- console.log(balance.coinType, balance.totalBalance);
201
+ console.log(balance.coinType, balance.balance);
201
202
  }
202
203
  ```
203
204
 
@@ -212,7 +213,7 @@ const result = await client.core.listCoins({
212
213
  limit: 10,
213
214
  });
214
215
 
215
- for (const coin of result.coins) {
216
+ for (const coin of result.objects) {
216
217
  console.log(coin.objectId, coin.balance);
217
218
  }
218
219
  ```
@@ -454,7 +455,7 @@ console.log(referenceGasPrice); // bigint
454
455
  Get the current system state including epoch information.
455
456
 
456
457
  ```typescript
457
- const systemState = await client.core.getCurrentSystemState();
458
+ const { systemState } = await client.core.getCurrentSystemState();
458
459
  console.log(systemState.epoch);
459
460
  console.log(systemState.systemStateVersion);
460
461
  ```
@@ -478,7 +479,7 @@ Get information about a Move function.
478
479
  const { function: fn } = await client.core.getMoveFunction({
479
480
  packageId: '0x2',
480
481
  moduleName: 'coin',
481
- name: 'transfer',
482
+ name: 'value',
482
483
  });
483
484
 
484
485
  console.log(fn.name);
@@ -566,7 +567,7 @@ function processObject(obj: SuiClientTypes.Object<{ content: true }>) {
566
567
  async function fetchBalance(
567
568
  client: ClientWithCoreApi,
568
569
  owner: string,
569
- ): Promise<SuiClientTypes.CoinBalance> {
570
+ ): Promise<SuiClientTypes.Balance> {
570
571
  const { balance } = await client.core.getBalance({ owner });
571
572
  return balance;
572
573
  }
@@ -584,7 +585,7 @@ const options: SuiClientTypes.GetObjectOptions<{ content: true }> = {
584
585
  | ---------------------- | ------------------------------------------- |
585
586
  | `Object<Include>` | Fetched object with optional included data |
586
587
  | `Coin` | Coin object with balance |
587
- | `CoinBalance` | Balance summary for a coin type |
588
+ | `Balance` | Balance summary for a coin type |
588
589
  | `CoinMetadata` | Metadata for a coin type |
589
590
  | `Transaction<Include>` | Executed transaction with optional data |
590
591
  | `TransactionResult` | Success or failure result from execution |
@@ -179,7 +179,7 @@ const { response: fields } = await grpcClient.stateService.listDynamicFields({
179
179
  const { response } = await grpcClient.movePackageService.getFunction({
180
180
  packageId: '0x2',
181
181
  moduleName: 'coin',
182
- name: 'transfer',
182
+ name: 'value',
183
183
  });
184
184
  ```
185
185
 
package/docs/index.md CHANGED
@@ -1,22 +1,55 @@
1
- # Sui TypeScript SDK Quick Start
1
+ # Sui TypeScript SDK
2
2
 
3
- > The Sui TypeScript SDK is a modular library of tools for interacting with the Sui blockchain.
3
+ > TypeScript SDK for building on the Sui blockchain
4
4
 
5
5
  The Sui TypeScript SDK is a modular library of tools for interacting with the Sui blockchain. Use it
6
6
  to send queries to RPC nodes, build and sign transactions, and interact with a Sui or local network.
7
7
 
8
8
  ## Installation
9
9
 
10
- ```sh npm2yarn
10
+ ```npm
11
11
  npm i @mysten/sui
12
12
  ```
13
13
 
14
+ The SDK is published as an ESM only package. Make sure your `package.json` includes
15
+ `"type": "module"`:
16
+
17
+ ```json
18
+ {
19
+ "type": "module"
20
+ }
21
+ ```
22
+
23
+ If you are using TypeScript, your `tsconfig.json` should use a compatible `moduleResolution` setting
24
+ such as `"NodeNext"`, `"Node16"`, or `"Bundler"`.
25
+
26
+ ## Module packages
27
+
28
+ The SDK contains a set of modular packages that you can use independently or together. Import just
29
+ what you need to keep your code light and compact.
30
+
31
+ - [`@mysten/sui/client`](/sui/clients): A client for interacting with Sui RPC nodes.
32
+ - [`@mysten/sui/bcs`](/sui/bcs): A BCS builder with pre-defined types for Sui.
33
+ - [`@mysten/sui/transactions`](/sui/transactions/basics): Utilities for building and interacting
34
+ with transactions.
35
+ - [`@mysten/sui/keypairs/*`](/sui/cryptography/keypairs): Modular exports for specific KeyPair
36
+ implementations.
37
+ - [`@mysten/sui/verify`](/sui/cryptography/keypairs#verifying-signatures-without-a-key-pair):
38
+ Methods for verifying transactions and messages.
39
+ - [`@mysten/sui/cryptography`](/sui/cryptography/keypairs): Shared types and classes for
40
+ cryptography.
41
+ - [`@mysten/sui/multisig`](/sui/cryptography/multisig): Utilities for working with multisig
42
+ signatures.
43
+ - [`@mysten/sui/utils`](/sui/utils): Utilities for formatting and parsing various Sui types.
44
+ - [`@mysten/sui/faucet`](#faucet): Methods for requesting SUI from a faucet.
45
+ - [`@mysten/sui/zklogin`](/sui/zklogin): Utilities for working with zkLogin.
46
+
14
47
  ## Network locations
15
48
 
16
49
  The following table lists the locations for Sui networks.
17
50
 
18
51
  | Network | Full node | faucet |
19
- | :------ | :------------------------------------ | :--------------------------------------- |
52
+ | ------- | ------------------------------------- | ---------------------------------------- |
20
53
  | local | `http://127.0.0.1:9000` (default) | `http://127.0.0.1:9123/v2/gas` (default) |
21
54
  | Devnet | `https://fullnode.devnet.sui.io:443` | `https://faucet.devnet.sui.io/v2/gas` |
22
55
  | Testnet | `https://fullnode.testnet.sui.io:443` | `https://faucet.testnet.sui.io/v2/gas` |
@@ -31,23 +64,144 @@ The following table lists the locations for Sui networks.
31
64
  > (preferred for apps that have high traffic). You can find a list of reliable RPC endpoint providers
32
65
  > for Sui on the [Sui Dev Portal](https://sui.io/developers#dev-tools) using the **Node Service** tab.
33
66
 
34
- ## Module packages
67
+ ## Quick start
35
68
 
36
- The SDK contains a set of modular packages that you can use independently or together. Import just
37
- what you need to keep your code light and compact.
69
+ Get started in a few minutes. This guide walks you through creating a keypair, funding it from a
70
+ faucet, and checking your balance.
38
71
 
39
- - [`@mysten/sui/client`](/sui/clients): A client for interacting with Sui RPC nodes.
40
- - [`@mysten/sui/bcs`](/sui/bcs): A BCS builder with pre-defined types for Sui.
41
- - [`@mysten/sui/transactions`](/sui/transaction-building/basics): Utilities for building and
42
- interacting with transactions.
43
- - [`@mysten/sui/keypairs/*`](/sui/cryptography/keypairs): Modular exports for specific KeyPair
44
- implementations.
45
- - [`@mysten/sui/verify`](/sui/cryptography/keypairs#verifying-signatures-without-a-key-pair):
46
- Methods for verifying transactions and messages.
47
- - [`@mysten/sui/cryptography`](/sui/cryptography/keypairs): Shared types and classes for
48
- cryptography.
49
- - [`@mysten/sui/multisig`](/sui/cryptography/multisig): Utilities for working with multisig
50
- signatures.
51
- - [`@mysten/sui/utils`](/sui/utils): Utilities for formatting and parsing various Sui types.
52
- - [`@mysten/sui/faucet`](/sui/faucet): Methods for requesting SUI from a faucet.
53
- - [`@mysten/sui/zklogin`](/sui/zklogin): Utilities for working with zkLogin.
72
+ ### Create a project
73
+
74
+ ```sh
75
+ mkdir hello-sui
76
+ cd hello-sui
77
+ npm init -y
78
+ npm pkg set type=module
79
+ npm i @mysten/sui
80
+ ```
81
+
82
+ ### Step 1: Create a keypair and get SUI
83
+
84
+ Create a `setup.ts` file that generates a new keypair, requests SUI from the faucet, and prints your
85
+ secret key for later use:
86
+
87
+ ```typescript
88
+
89
+ // Generate a new keypair
90
+ const keypair = new Ed25519Keypair();
91
+
92
+ console.log('Address:', keypair.toSuiAddress());
93
+ console.log('Secret key:', keypair.getSecretKey());
94
+
95
+ // Request SUI from the devnet faucet
96
+ await requestSuiFromFaucetV2({
97
+ host: getFaucetHost('devnet'),
98
+ recipient: keypair.toSuiAddress(),
99
+ });
100
+
101
+ console.log('Faucet request sent! Save the secret key above for the next step.');
102
+ ```
103
+
104
+ Run it:
105
+
106
+ ```sh
107
+ node setup.ts
108
+ ```
109
+
110
+ Save the secret key that gets printed; you'll use it in the next step.
111
+
112
+ > **Warning:** Logging secret keys to the console is only appropriate for quick demos like this. In real
113
+ > applications, never log or expose secret keys. Store them securely using environment variables,
114
+ > encrypted keystores, or a secrets manager.
115
+
116
+ ### Step 2: Check your balance
117
+
118
+ Create a `balance.ts` file that imports your keypair from the secret key and checks the balance:
119
+
120
+ ```typescript
121
+
122
+ // Import the keypair using the secret key from step 1
123
+ const keypair = Ed25519Keypair.fromSecretKey('suiprivkey1...'); // paste your secret key here
124
+
125
+ const grpcClient = new SuiGrpcClient({
126
+ network: 'devnet',
127
+ baseUrl: 'https://fullnode.devnet.sui.io:443',
128
+ });
129
+
130
+ const { balance } = await grpcClient.core.getBalance({
131
+ owner: keypair.toSuiAddress(),
132
+ });
133
+
134
+ const sui = Number(balance.balance) / Number(MIST_PER_SUI);
135
+ console.log(`Address: ${keypair.toSuiAddress()}`);
136
+ console.log(`Balance: ${sui} SUI`);
137
+ ```
138
+
139
+ Run it:
140
+
141
+ ```sh
142
+ node balance.ts
143
+ ```
144
+
145
+ ### Step 3: Transfer SUI
146
+
147
+ Create a `transfer.ts` file that sends SUI to another address and logs the transaction effects:
148
+
149
+ ```typescript
150
+
151
+ const keypair = Ed25519Keypair.fromSecretKey('suiprivkey1...'); // paste your secret key here
152
+ const grpcClient = new SuiGrpcClient({
153
+ network: 'devnet',
154
+ baseUrl: 'https://fullnode.devnet.sui.io:443',
155
+ });
156
+
157
+ const tx = new Transaction();
158
+
159
+ tx.transferObjects(
160
+ [coinWithBalance({ balance: BigInt(0.1 * Number(MIST_PER_SUI)) })],
161
+ '0xRecipientAddress', // replace with the recipient's address
162
+ );
163
+
164
+ const result = await keypair.signAndExecuteTransaction({
165
+ transaction: tx,
166
+ client: grpcClient,
167
+ include: { effects: true, balanceChanges: true },
168
+ });
169
+
170
+ if (result.$kind === 'FailedTransaction') {
171
+ console.error('Transaction failed:', result.FailedTransaction.status.error?.message);
172
+ } else {
173
+ console.log('Transaction digest:', result.Transaction.digest);
174
+ console.log('Effects:', JSON.stringify(result.Transaction.effects, null, 2));
175
+ console.log('Balance changes:', JSON.stringify(result.Transaction.balanceChanges, null, 2));
176
+ }
177
+ ```
178
+
179
+ Run it:
180
+
181
+ ```sh
182
+ node transfer.ts
183
+ ```
184
+
185
+ ### Faucet
186
+
187
+ Devnet, Testnet, and local networks include faucets that mint SUI. Use `requestSuiFromFaucetV2` to
188
+ request SUI programmatically:
189
+
190
+ ```typescript
191
+
192
+ await requestSuiFromFaucetV2({
193
+ host: getFaucetHost('testnet'),
194
+ recipient: '0xYourAddress',
195
+ });
196
+ ```
197
+
198
+ > **Note:** Faucets on Devnet and Testnet are rate limited. If you hit the limit, wait before trying again.
199
+ > For Testnet, you can also get SUI through the web UI at `faucet.sui.io` or through the [Sui
200
+ > Discord](https://discord.gg/sui) faucet channels.
201
+
202
+ ## Next steps
203
+
204
+ - [Building Transactions](/sui/transactions/basics): create and compose transactions
205
+ - [Signing and Execution](/sui/transactions/signing-and-execution): sign and submit transactions
206
+ - [Coins and Balances](/sui/transactions/coins-and-balances): work with tokens
207
+ - [Client Setup](/sui/clients): configure clients for different networks
@@ -1,21 +1,18 @@
1
1
  # Sui SDK
2
2
  > TypeScript interfaces for Sui
3
3
 
4
- - [Sui TypeScript SDK Quick Start](..md): The Sui TypeScript SDK is a modular library of tools for interacting with the Sui blockchain.
5
- - [Install Sui TypeScript SDK](./install.md): Install the @mysten/sui package and configure your project.
4
+ - [Sui TypeScript SDK](..md): TypeScript SDK for building on the Sui blockchain
6
5
  - [LLM Documentation](./llm-docs.md): Give AI agents access to Sui SDK documentation in your project.
7
- - [Hello Sui](./hello-sui.md): Build your first Sui application with the TypeScript SDK.
8
- - [Faucet](./faucet.md): Request test SUI tokens from the faucet on Devnet, Testnet, or local networks.
9
6
  - [Sui Clients](./clients.md): Choose and configure gRPC, GraphQL, or JSON-RPC clients for the Sui network.
10
7
  - [Core API](./clients/core.md): Transport-agnostic Core API shared by all Sui clients.
11
8
  - [SuiGrpcClient](./clients/grpc.md): Connect to Sui through gRPC with SuiGrpcClient.
12
9
  - [SuiGraphQLClient](./clients/graphql.md): Connect to Sui through GraphQL with SuiGraphQLClient.
13
10
  - [SuiJsonRpcClient](./clients/json-rpc.md): Connect to Sui through JSON-RPC with SuiJsonRpcClient.
14
- - [Sui Programmable Transaction Basics](./transaction-building/basics.md): Construct programmable transaction blocks with the Transaction API.
15
- - [Paying for Sui Transactions with Gas Coins](./transaction-building/gas.md): Configure gas budget, price, and coin selection for Sui transactions.
16
- - [Sponsored Transactions](./transaction-building/sponsored-transactions.md): Pay gas fees on behalf of other users with sponsored transactions.
17
- - [Building Offline](./transaction-building/offline.md): Build transactions without a network connection.
18
- - [Transaction Intents](./transaction-building/intents.md): Use high-level intents to simplify transaction building.
11
+ - [Building Transactions](./transactions/basics.md): Construct programmable transaction blocks with the Transaction API
12
+ - [Signing and Execution](./transactions/signing-and-execution.md): Sign transactions and execute them on the Sui network
13
+ - [Coins and Balances](./transactions/coins-and-balances.md): Work with coin objects and address balances in transactions
14
+ - [Commands and Inputs Reference](./transactions/reference.md): Complete reference for transaction commands and input types
15
+ - [Building Offline](./transactions/offline.md): Build transactions without a network connection
19
16
  - [Key pairs](./cryptography/keypairs.md): Create and manage Ed25519, Secp256k1, and Secp256r1 keypairs for Sui transaction signing.
20
17
  - [Multi-Signature Transactions](./cryptography/multisig.md): Create multi-signature transactions with multiple signers on Sui.
21
18
  - [Passkey](./cryptography/passkey.md): Use WebAuthn passkeys for Sui transaction signing.
@@ -13,7 +13,7 @@ earlier version of the SDK, there are some changes you should consider when upda
13
13
 
14
14
  The Sui TypeScript SDK is now divided into modular components. Before version 0.38.0, you imported
15
15
  the complete SDK module. Now, you upload the individual packages of the SDK module instead. See the
16
- [Module Packages section](#module-packages) for the list of packages.
16
+ [Module Structure section](#module-structure) for the list of packages.
17
17
 
18
18
  ### Deprecated classes
19
19
 
@@ -40,7 +40,7 @@ The Sui TypeScript SDK deprecates the following classes with version 0.38.0:
40
40
 
41
41
  Signing and sending transactions changes slightly with the deprecation of the `Signer` pattern. For
42
42
  an example of transaction signing, see the
43
- [Sui Programmable Transaction Blocks Basics](/sui/transaction-building/basics) topic.
43
+ [Sui Programmable Transaction Block Basics](/sui/transactions/basics) topic.
44
44
 
45
45
  ### Faucet requests
46
46
 
@@ -11,7 +11,7 @@ highlights:
11
11
 
12
12
  - [A new GraphQL Client for the newly released Sui GraphQL API](/sui/clients/graphql)
13
13
  - [New Transaction Executor classes for efficient Transaction execution](../executors)
14
- - [New Transaction Intents to simplify common transaction patterns](../transaction-building/intents)
14
+ - [New Transaction Intents to simplify common transaction patterns](../transactions/coins-and-balances)
15
15
  - [A new Plugin system for Extending Transaction Building](../plugins)
16
16
 
17
17
  The majority of changes in this release are in the `@mysten/sui` package, but the changes to API
@@ -24,7 +24,7 @@ As part of the 1.0 release the `@mysten/sui.js` package has been renamed to `@my
24
24
 
25
25
  To upgrade to the new version, uninstall the old package and install the new one:
26
26
 
27
- ```sh npm2yarn
27
+ ```npm
28
28
  npm uninstall @mysten/sui.js
29
29
  npm install @mysten/sui
30
30
  ```