kawasekit 0.2.0 → 0.4.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 (36) hide show
  1. package/dist/{chunk-VXZHS74W.js → chunk-5TTOAVHE.js} +9 -3
  2. package/dist/chunk-5TTOAVHE.js.map +1 -0
  3. package/dist/chunk-FD6Q4NB2.js +293 -0
  4. package/dist/chunk-FD6Q4NB2.js.map +1 -0
  5. package/dist/{chunk-SMAZUZFO.js → chunk-G3UC6SME.js} +3 -3
  6. package/dist/{chunk-SMAZUZFO.js.map → chunk-G3UC6SME.js.map} +1 -1
  7. package/dist/{chunk-XRSZTZVZ.js → chunk-RJLDKDWL.js} +2 -2
  8. package/dist/{chunk-XRSZTZVZ.js.map → chunk-RJLDKDWL.js.map} +1 -1
  9. package/dist/cli/index.cjs +1 -1
  10. package/dist/cli/index.js +5 -5
  11. package/dist/{index-f-Xg86P9.d.ts → index-C9tbaHPF.d.ts} +1 -1
  12. package/dist/{index-Cn6kg7KH.d.cts → index-CAmTA8xR.d.cts} +1 -1
  13. package/dist/index.cjs +239 -4
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +4 -4
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +4 -4
  18. package/dist/policy/index.d.cts +2 -2
  19. package/dist/policy/index.d.ts +2 -2
  20. package/dist/signer/index.cjs +235 -0
  21. package/dist/signer/index.cjs.map +1 -1
  22. package/dist/signer/index.d.cts +240 -5
  23. package/dist/signer/index.d.ts +240 -5
  24. package/dist/signer/index.js +2 -2
  25. package/dist/{spending-policy-DKZN3Sg8.d.ts → spending-policy-BD2Mpm-L.d.ts} +1 -1
  26. package/dist/{spending-policy-DaajDg9B.d.cts → spending-policy-CGIaBpg-.d.cts} +1 -1
  27. package/dist/{types-IEl-iOIx.d.cts → types-BLJU67HZ.d.cts} +11 -3
  28. package/dist/{types-IEl-iOIx.d.ts → types-BLJU67HZ.d.ts} +11 -3
  29. package/dist/x402/index.cjs.map +1 -1
  30. package/dist/x402/index.d.cts +2 -2
  31. package/dist/x402/index.d.ts +2 -2
  32. package/dist/x402/index.js +2 -2
  33. package/package.json +1 -1
  34. package/dist/chunk-THTVJZ2Q.js +0 -71
  35. package/dist/chunk-THTVJZ2Q.js.map +0 -1
  36. package/dist/chunk-VXZHS74W.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -532,6 +532,12 @@ var PolicyGatedSignerConfigError = class extends Error {
532
532
  this.reason = reason;
533
533
  }
534
534
  };
535
+ var CoSignUnavailableError = class extends Error {
536
+ constructor(message, options) {
537
+ super(message, options);
538
+ this.name = "CoSignUnavailableError";
539
+ }
540
+ };
535
541
 
536
542
  // src/signer/gate.ts
537
543
  function requireNonBypassable(signer) {
@@ -576,11 +582,11 @@ var X402PolicyRejectedError = class extends Error {
576
582
  reason;
577
583
  /** The full typed rejection (its `detail` never contains the nonce or signature). */
578
584
  rejection;
579
- constructor(rejection, options) {
580
- super(`x402 payment rejected by policy: ${rejection.reason} (${rejection.detail})`, options);
585
+ constructor(rejection2, options) {
586
+ super(`x402 payment rejected by policy: ${rejection2.reason} (${rejection2.detail})`, options);
581
587
  this.name = "X402PolicyRejectedError";
582
- this.reason = rejection.reason;
583
- this.rejection = rejection;
588
+ this.reason = rejection2.reason;
589
+ this.rejection = rejection2;
584
590
  }
585
591
  };
586
592
  var KNOWN_ASSETS = [
@@ -829,6 +835,230 @@ function createLocalPolicyGatedSigner(params) {
829
835
  };
830
836
  }
831
837
 
838
+ // src/signer/mpc-2p-wire.ts
839
+ var WIRE_VERSION = 2;
840
+ function toWireIntent(intent) {
841
+ return {
842
+ token: intent.token.toLowerCase(),
843
+ chain_id: intent.chainId,
844
+ from: intent.from.toLowerCase(),
845
+ to: intent.to.toLowerCase(),
846
+ value: intent.value.toString(),
847
+ valid_after: intent.validAfter.toString(),
848
+ valid_before: intent.validBefore.toString(),
849
+ nonce: intent.nonce.toLowerCase()
850
+ };
851
+ }
852
+ function canonicalRequestBytes(env) {
853
+ const i = env.intent;
854
+ const lines = [
855
+ "kawasekit-mpc-2p/cosign-request/v3",
856
+ "wireVersion=2",
857
+ `ceremonyId=${env.ceremonyId}`,
858
+ `ssid=${env.ssid}`,
859
+ `token=${i.token.toLowerCase()}`,
860
+ `chainId=${i.chainId}`,
861
+ `from=${i.from.toLowerCase()}`,
862
+ `to=${i.to.toLowerCase()}`,
863
+ `value=${i.value}`,
864
+ `validAfter=${i.validAfter}`,
865
+ `validBefore=${i.validBefore}`,
866
+ `nonce=${i.nonce.toLowerCase()}`,
867
+ `freshnessTs=${env.freshnessTs}`,
868
+ `freshnessNonce=${env.freshnessNonce.toLowerCase()}`
869
+ ];
870
+ return new TextEncoder().encode(lines.map((l) => `${l}
871
+ `).join(""));
872
+ }
873
+
874
+ // src/signer/mpc-2p.ts
875
+ var POLICY_REASONS = /* @__PURE__ */ new Set([
876
+ "revoked",
877
+ "expired",
878
+ "token_not_allowed",
879
+ "recipient_not_allowed",
880
+ "amount_exceeds_per_sign",
881
+ "amount_exceeds_cumulative",
882
+ "intent_digest_mismatch",
883
+ "unauthenticated",
884
+ "from_mismatch",
885
+ "nonce_reuse_conflict"
886
+ ]);
887
+ function rejection(reason, detail) {
888
+ return { ok: false, rejection: { reason, detail } };
889
+ }
890
+ function createMpc2pPolicyGatedSigner(params) {
891
+ const { agent, transport, authenticator, session } = params;
892
+ const pinned = resolveAssetParam(params.asset);
893
+ const from = viem.getAddress(params.from);
894
+ const agentEoa = viem.getAddress(agent.groupEoa());
895
+ if (agentEoa !== from) {
896
+ throw new PolicyGatedSignerConfigError(
897
+ "from",
898
+ `the agent share controls ${agentEoa} but params.from is ${from}`
899
+ );
900
+ }
901
+ return {
902
+ enforcement: "cryptographic",
903
+ from,
904
+ async sign(intent) {
905
+ if (viem.getAddress(intent.from) !== from) {
906
+ return rejection(
907
+ "from_mismatch",
908
+ `intent.from ${viem.getAddress(intent.from)} does not equal signer.from ${from}`
909
+ );
910
+ }
911
+ if (viem.getAddress(intent.token) !== pinned.verifyingContract) {
912
+ return rejection(
913
+ "token_not_allowed",
914
+ `intent.token ${viem.getAddress(intent.token)} does not equal the signer's pinned verifyingContract ${pinned.verifyingContract}`
915
+ );
916
+ }
917
+ const digest = viem.hashTypedData({
918
+ domain: resolvedAssetToEip3009Domain(pinned, intent.chainId),
919
+ types: transferWithAuthorizationTypes,
920
+ primaryType: "TransferWithAuthorization",
921
+ message: {
922
+ from,
923
+ to: intent.to,
924
+ value: intent.value,
925
+ validAfter: intent.validAfter,
926
+ validBefore: intent.validBefore,
927
+ nonce: intent.nonce
928
+ }
929
+ });
930
+ const env = {
931
+ ceremonyId: globalThis.crypto.randomUUID(),
932
+ ssid: globalThis.crypto.randomUUID(),
933
+ intent,
934
+ freshnessTs: Math.floor(Date.now() / 1e3),
935
+ freshnessNonce: viem.toHex(globalThis.crypto.getRandomValues(new Uint8Array(16)))
936
+ };
937
+ const authTag = await authenticator.tag(canonicalRequestBytes(env));
938
+ const conn = await openConnection(transport);
939
+ try {
940
+ return await runCeremony(conn, agent, session.id, env, digest, authTag);
941
+ } finally {
942
+ try {
943
+ await conn.close();
944
+ } catch {
945
+ }
946
+ }
947
+ },
948
+ describe() {
949
+ return {
950
+ enforcement: "cryptographic",
951
+ from,
952
+ policyId: session.id,
953
+ notAfter: session.notAfter,
954
+ // The backend owns authoritative revocation (a revoked session → a
955
+ // rejection at sign time); this metadata field is best-effort.
956
+ revoked: false
957
+ };
958
+ }
959
+ };
960
+ }
961
+ async function openConnection(transport) {
962
+ try {
963
+ return await transport.connect();
964
+ } catch (cause) {
965
+ throw new CoSignUnavailableError("co-signer connection failed", { cause });
966
+ }
967
+ }
968
+ async function runCeremony(conn, agent, sessionId, env, digest, authTag) {
969
+ const send = async (frame) => {
970
+ try {
971
+ await conn.send(frame);
972
+ } catch (cause) {
973
+ throw new CoSignUnavailableError("co-sign connection dropped while sending", { cause });
974
+ }
975
+ };
976
+ const recv = async () => {
977
+ let frame;
978
+ try {
979
+ frame = await conn.recv();
980
+ } catch (cause) {
981
+ throw new CoSignUnavailableError("co-sign connection dropped mid-ceremony", { cause });
982
+ }
983
+ if (frame.wire_version !== WIRE_VERSION) {
984
+ throw new CoSignUnavailableError(
985
+ `co-signer spoke wire_version ${frame.wire_version}, expected ${WIRE_VERSION}`
986
+ );
987
+ }
988
+ return frame;
989
+ };
990
+ await send({
991
+ wire_version: WIRE_VERSION,
992
+ kind: "request",
993
+ session_id: sessionId,
994
+ ceremony_id: env.ceremonyId,
995
+ ssid: env.ssid,
996
+ intent: toWireIntent(env.intent),
997
+ freshness_ts: env.freshnessTs,
998
+ freshness_nonce: env.freshnessNonce,
999
+ auth_tag: authTag
1000
+ });
1001
+ let first;
1002
+ try {
1003
+ first = agent.start(digest);
1004
+ } catch (cause) {
1005
+ throw new CoSignUnavailableError("the agent failed to start the ceremony", { cause });
1006
+ }
1007
+ await send({ wire_version: WIRE_VERSION, kind: "round", payload: first });
1008
+ let agentSig = null;
1009
+ for (; ; ) {
1010
+ const frame = await recv();
1011
+ switch (frame.kind) {
1012
+ case "round": {
1013
+ let step;
1014
+ try {
1015
+ step = agent.step(frame.payload);
1016
+ } catch (cause) {
1017
+ throw new CoSignUnavailableError("the agent rejected a round frame", { cause });
1018
+ }
1019
+ if ("outbound" in step) {
1020
+ await send({ wire_version: WIRE_VERSION, kind: "round", payload: step.outbound });
1021
+ } else {
1022
+ agentSig = step.signature;
1023
+ }
1024
+ break;
1025
+ }
1026
+ case "result": {
1027
+ if (agentSig === null) {
1028
+ throw new CoSignUnavailableError(
1029
+ "the backend returned a result before the agent derived a signature"
1030
+ );
1031
+ }
1032
+ if (frame.r.toLowerCase() !== agentSig.r.toLowerCase() || frame.s.toLowerCase() !== agentSig.s.toLowerCase() || frame.v !== agentSig.v) {
1033
+ throw new CoSignUnavailableError("the backend and agent derived different signatures");
1034
+ }
1035
+ return { ok: true, signature: assembleSignature(agentSig), intent: env.intent };
1036
+ }
1037
+ case "rejection": {
1038
+ if (POLICY_REASONS.has(frame.reason)) {
1039
+ return rejection(frame.reason, frame.detail);
1040
+ }
1041
+ throw new CoSignUnavailableError(
1042
+ `co-signer returned a non-policy rejection (${frame.reason}): ${frame.detail}`
1043
+ );
1044
+ }
1045
+ case "error": {
1046
+ throw new CoSignUnavailableError(`co-signer error: ${frame.message}`);
1047
+ }
1048
+ default: {
1049
+ throw new CoSignUnavailableError("co-signer sent an unexpected frame");
1050
+ }
1051
+ }
1052
+ }
1053
+ }
1054
+ function assembleSignature(sig) {
1055
+ const yParity = sig.v - 27;
1056
+ if (yParity !== 0 && yParity !== 1) {
1057
+ throw new CoSignUnavailableError(`malformed recovery id v=${sig.v} (expected 27 or 28)`);
1058
+ }
1059
+ return viem.serializeSignature({ r: sig.r, s: sig.s, yParity });
1060
+ }
1061
+
832
1062
  // src/x402/types.ts
833
1063
  var X402_VERSION = 2;
834
1064
  var EIP155_PREFIX = "eip155:";
@@ -2825,6 +3055,7 @@ async function rotateSessionKey(params) {
2825
3055
  }
2826
3056
 
2827
3057
  exports.ChainNotSupportedError = ChainNotSupportedError;
3058
+ exports.CoSignUnavailableError = CoSignUnavailableError;
2828
3059
  exports.IdempotencyConfigError = IdempotencyConfigError;
2829
3060
  exports.IdempotencyRecordParseError = IdempotencyRecordParseError;
2830
3061
  exports.IdempotencyRecordVersionError = IdempotencyRecordVersionError;
@@ -2842,6 +3073,7 @@ exports.SessionEnvelopeSignerMismatchError = SessionEnvelopeSignerMismatchError;
2842
3073
  exports.SessionEnvelopeVersionError = SessionEnvelopeVersionError;
2843
3074
  exports.SpendingPolicyConfigError = SpendingPolicyConfigError;
2844
3075
  exports.TransferJpycInputError = TransferJpycInputError;
3076
+ exports.WIRE_VERSION = WIRE_VERSION;
2845
3077
  exports.X402InvalidConfigError = X402InvalidConfigError;
2846
3078
  exports.X402InvalidPayloadError = X402InvalidPayloadError;
2847
3079
  exports.X402PolicyRejectedError = X402PolicyRejectedError;
@@ -2860,6 +3092,7 @@ exports.avalancheFuji = avalancheFuji;
2860
3092
  exports.buildPaymentRequiredResponse = buildPaymentRequiredResponse;
2861
3093
  exports.buildPaymentRequirements = buildPaymentRequirements;
2862
3094
  exports.cancelAuthorizationTypes = cancelAuthorizationTypes;
3095
+ exports.canonicalRequestBytes = canonicalRequestBytes;
2863
3096
  exports.chainIdToX402Network = chainIdToX402Network;
2864
3097
  exports.createAgentSmartAccount = createAgentSmartAccount;
2865
3098
  exports.createCoinbaseFacilitator = createCoinbaseFacilitator;
@@ -2868,6 +3101,7 @@ exports.createIdempotencyKeyBuilder = createIdempotencyKeyBuilder;
2868
3101
  exports.createInMemoryIdempotencyStore = createInMemoryIdempotencyStore;
2869
3102
  exports.createJpycDailyLimitPolicies = createJpycDailyLimitPolicies;
2870
3103
  exports.createLocalPolicyGatedSigner = createLocalPolicyGatedSigner;
3104
+ exports.createMpc2pPolicyGatedSigner = createMpc2pPolicyGatedSigner;
2871
3105
  exports.createSelfFacilitator = createSelfFacilitator;
2872
3106
  exports.createSpendingPolicy = createSpendingPolicy;
2873
3107
  exports.createX402Handler = createX402Handler;
@@ -2916,6 +3150,7 @@ exports.signCancelAuthorization = signCancelAuthorization;
2916
3150
  exports.signReceiveWithAuthorization = signReceiveWithAuthorization;
2917
3151
  exports.signTransferWithAuthorization = signTransferWithAuthorization;
2918
3152
  exports.supportedChains = supportedChains;
3153
+ exports.toWireIntent = toWireIntent;
2919
3154
  exports.transferJpyc = transferJpyc;
2920
3155
  exports.transferWithAuthorizationTypes = transferWithAuthorizationTypes;
2921
3156
  exports.wrapFetch = wrapFetch;