@sequence0/sdk 1.1.2 → 2.0.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 (126) hide show
  1. package/README.md +1 -1
  2. package/dist/chains/algorand.d.ts +44 -0
  3. package/dist/chains/algorand.d.ts.map +1 -0
  4. package/dist/chains/algorand.js +148 -0
  5. package/dist/chains/algorand.js.map +1 -0
  6. package/dist/chains/aptos.d.ts +39 -0
  7. package/dist/chains/aptos.d.ts.map +1 -0
  8. package/dist/chains/aptos.js +168 -0
  9. package/dist/chains/aptos.js.map +1 -0
  10. package/dist/chains/cardano.d.ts +42 -0
  11. package/dist/chains/cardano.d.ts.map +1 -0
  12. package/dist/chains/cardano.js +188 -0
  13. package/dist/chains/cardano.js.map +1 -0
  14. package/dist/chains/cosmos.d.ts +42 -0
  15. package/dist/chains/cosmos.d.ts.map +1 -0
  16. package/dist/chains/cosmos.js +216 -0
  17. package/dist/chains/cosmos.js.map +1 -0
  18. package/dist/chains/dogecoin-litecoin.d.ts +57 -0
  19. package/dist/chains/dogecoin-litecoin.d.ts.map +1 -0
  20. package/dist/chains/dogecoin-litecoin.js +521 -0
  21. package/dist/chains/dogecoin-litecoin.js.map +1 -0
  22. package/dist/chains/ethereum.d.ts.map +1 -1
  23. package/dist/chains/ethereum.js +16 -0
  24. package/dist/chains/ethereum.js.map +1 -1
  25. package/dist/chains/hedera.d.ts +113 -0
  26. package/dist/chains/hedera.d.ts.map +1 -0
  27. package/dist/chains/hedera.js +302 -0
  28. package/dist/chains/hedera.js.map +1 -0
  29. package/dist/chains/icp.d.ts +95 -0
  30. package/dist/chains/icp.d.ts.map +1 -0
  31. package/dist/chains/icp.js +520 -0
  32. package/dist/chains/icp.js.map +1 -0
  33. package/dist/chains/kaspa.d.ts +152 -0
  34. package/dist/chains/kaspa.d.ts.map +1 -0
  35. package/dist/chains/kaspa.js +790 -0
  36. package/dist/chains/kaspa.js.map +1 -0
  37. package/dist/chains/multiversx.d.ts +143 -0
  38. package/dist/chains/multiversx.d.ts.map +1 -0
  39. package/dist/chains/multiversx.js +524 -0
  40. package/dist/chains/multiversx.js.map +1 -0
  41. package/dist/chains/near.d.ts +40 -0
  42. package/dist/chains/near.d.ts.map +1 -0
  43. package/dist/chains/near.js +170 -0
  44. package/dist/chains/near.js.map +1 -0
  45. package/dist/chains/polkadot.d.ts +43 -0
  46. package/dist/chains/polkadot.d.ts.map +1 -0
  47. package/dist/chains/polkadot.js +179 -0
  48. package/dist/chains/polkadot.js.map +1 -0
  49. package/dist/chains/ripple.d.ts +41 -0
  50. package/dist/chains/ripple.d.ts.map +1 -0
  51. package/dist/chains/ripple.js +190 -0
  52. package/dist/chains/ripple.js.map +1 -0
  53. package/dist/chains/stellar.d.ts +40 -0
  54. package/dist/chains/stellar.d.ts.map +1 -0
  55. package/dist/chains/stellar.js +156 -0
  56. package/dist/chains/stellar.js.map +1 -0
  57. package/dist/chains/sui.d.ts +44 -0
  58. package/dist/chains/sui.d.ts.map +1 -0
  59. package/dist/chains/sui.js +157 -0
  60. package/dist/chains/sui.js.map +1 -0
  61. package/dist/chains/tezos.d.ts +43 -0
  62. package/dist/chains/tezos.d.ts.map +1 -0
  63. package/dist/chains/tezos.js +162 -0
  64. package/dist/chains/tezos.js.map +1 -0
  65. package/dist/chains/ton.d.ts +40 -0
  66. package/dist/chains/ton.d.ts.map +1 -0
  67. package/dist/chains/ton.js +168 -0
  68. package/dist/chains/ton.js.map +1 -0
  69. package/dist/chains/tron.d.ts +41 -0
  70. package/dist/chains/tron.d.ts.map +1 -0
  71. package/dist/chains/tron.js +124 -0
  72. package/dist/chains/tron.js.map +1 -0
  73. package/dist/core/atomic.d.ts +76 -0
  74. package/dist/core/atomic.d.ts.map +1 -0
  75. package/dist/core/atomic.js +39 -0
  76. package/dist/core/atomic.js.map +1 -0
  77. package/dist/core/client.d.ts +238 -0
  78. package/dist/core/client.d.ts.map +1 -1
  79. package/dist/core/client.js +536 -4
  80. package/dist/core/client.js.map +1 -1
  81. package/dist/core/delegation.d.ts +184 -0
  82. package/dist/core/delegation.d.ts.map +1 -0
  83. package/dist/core/delegation.js +37 -0
  84. package/dist/core/delegation.js.map +1 -0
  85. package/dist/core/programmable.d.ts +66 -0
  86. package/dist/core/programmable.d.ts.map +1 -0
  87. package/dist/core/programmable.js +36 -0
  88. package/dist/core/programmable.js.map +1 -0
  89. package/dist/core/solvency.d.ts +223 -0
  90. package/dist/core/solvency.d.ts.map +1 -0
  91. package/dist/core/solvency.js +267 -0
  92. package/dist/core/solvency.js.map +1 -0
  93. package/dist/core/types.d.ts +172 -1
  94. package/dist/core/types.d.ts.map +1 -1
  95. package/dist/core/universal-account.d.ts +438 -0
  96. package/dist/core/universal-account.d.ts.map +1 -0
  97. package/dist/core/universal-account.js +597 -0
  98. package/dist/core/universal-account.js.map +1 -0
  99. package/dist/core/witness.d.ts +197 -0
  100. package/dist/core/witness.d.ts.map +1 -0
  101. package/dist/core/witness.js +298 -0
  102. package/dist/core/witness.js.map +1 -0
  103. package/dist/erc4337/types.js +2 -2
  104. package/dist/index.d.ts +30 -2
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +91 -4
  107. package/dist/index.js.map +1 -1
  108. package/dist/settlement/settlement.d.ts +152 -0
  109. package/dist/settlement/settlement.d.ts.map +1 -0
  110. package/dist/settlement/settlement.js +172 -0
  111. package/dist/settlement/settlement.js.map +1 -0
  112. package/dist/utils/eip712.js +2 -2
  113. package/dist/utils/fee.d.ts +2 -2
  114. package/dist/utils/fee.js +2 -2
  115. package/dist/utils/optional-deps.d.ts +9 -0
  116. package/dist/utils/optional-deps.d.ts.map +1 -0
  117. package/dist/utils/optional-deps.js +21 -0
  118. package/dist/utils/optional-deps.js.map +1 -0
  119. package/dist/utils/validation.d.ts.map +1 -1
  120. package/dist/utils/validation.js +6 -1
  121. package/dist/utils/validation.js.map +1 -1
  122. package/dist/wallet/wallet.d.ts +52 -0
  123. package/dist/wallet/wallet.d.ts.map +1 -1
  124. package/dist/wallet/wallet.js +265 -33
  125. package/dist/wallet/wallet.js.map +1 -1
  126. package/package.json +35 -1
@@ -31,6 +31,8 @@ const http_1 = require("../utils/http");
31
31
  const websocket_1 = require("../utils/websocket");
32
32
  const discovery_1 = require("../utils/discovery");
33
33
  const fee_1 = require("../utils/fee");
34
+ const settlement_1 = require("../settlement/settlement");
35
+ const universal_account_1 = require("./universal-account");
34
36
  const errors_1 = require("../utils/errors");
35
37
  const eip712_1 = require("../utils/eip712");
36
38
  const validation_1 = require("../utils/validation");
@@ -63,14 +65,20 @@ const SEQUENCE_RPC = {
63
65
  };
64
66
  /** AgentRegistry contract addresses */
65
67
  const REGISTRY_ADDRESSES = {
66
- testnet: '0xe00bc0ad2d623ea021c9299221125b4e5951cdab',
67
- mainnet: '0x774d9a0dc937bfdc7636cbc6e0fc37f9a0809177',
68
+ testnet: '0xb2c218e154d4374e721eab6293af3eeeaa117400',
69
+ mainnet: '0xdefa5ab7ea6a87ac51628f4cde55bb4d49e62f50',
68
70
  };
69
71
  /** FeeCollector contract addresses */
70
72
  const FEE_COLLECTOR_ADDRESSES = {
71
- testnet: '0x2a23644695fb62f6ab2dffdaf58fc1ce89f3bada',
72
- mainnet: '0x1977f852aa0d16a59c4ea71b6cc72db02803395f',
73
+ testnet: '0xc017d0a5da9369003095325229de1e70f0e33a1c',
74
+ mainnet: '0xccd70007534c33b0ab3997d81207fea5e59ca54a',
73
75
  };
76
+ /** ProgramRegistry contract selectors (K1: Programmable Signing) */
77
+ const PROGRAM_REGISTRY_DEPLOY_SELECTOR = '0x2e1a7d4d'; // deployProgram(bytes,string,uint256,uint256)
78
+ const PROGRAM_REGISTRY_ATTACH_SELECTOR = '0x51cff8d9'; // attachProgram(string,bytes32)
79
+ const PROGRAM_REGISTRY_DETACH_SELECTOR = '0x5e2c576e'; // detachProgram(string,bytes32)
80
+ const PROGRAM_REGISTRY_GET_PROGRAMS_SELECTOR = '0x0e316ab7'; // getWalletPrograms(string)
81
+ const PROGRAM_REGISTRY_GET_INFO_SELECTOR = '0x553eca1f'; // getProgramInfo(bytes32)
74
82
  /** Default chain RPC URLs */
75
83
  const CHAIN_RPCS = {
76
84
  testnet: {
@@ -178,6 +186,10 @@ class Sequence0 {
178
186
  this.ownerSigner = null;
179
187
  /** Owner's Ethereum address (derived from private key when provided) */
180
188
  this.ownerAddress = null;
189
+ /** Optional delegate signer for K4 delegated signing */
190
+ this.delegateSigner = null;
191
+ /** Delegation grant ID for delegated signing */
192
+ this.delegationId = null;
181
193
  const network = config.network || 'mainnet';
182
194
  this.config = {
183
195
  ...config,
@@ -200,6 +212,19 @@ class Sequence0 {
200
212
  return sig.r + sig.s.slice(2) + v;
201
213
  };
202
214
  }
215
+ // Set up delegate signer for K4 delegated signing
216
+ if (config.delegatePrivateKey && config.delegationId) {
217
+ this.delegationId = config.delegationId;
218
+ const delegateKey = config.delegatePrivateKey.startsWith('0x')
219
+ ? config.delegatePrivateKey
220
+ : '0x' + config.delegatePrivateKey;
221
+ const delegateSigningKey = new ethers_1.SigningKey(delegateKey);
222
+ this.delegateSigner = async (messageHash) => {
223
+ const sig = delegateSigningKey.sign(messageHash);
224
+ const v = sig.v === 27 ? '1b' : '1c';
225
+ return sig.r + sig.s.slice(2) + v;
226
+ };
227
+ }
203
228
  const httpOpts = {
204
229
  timeout: config.timeout || 30000,
205
230
  maxRetries: config.maxRetries,
@@ -723,6 +748,392 @@ class Sequence0 {
723
748
  return this.feeManager.buildCollectFeeTx(walletId, agentAddresses);
724
749
  }
725
750
  // ────────────────────────────────────────────────
751
+ // K1: Programmable Signing (WASM Policies)
752
+ // ────────────────────────────────────────────────
753
+ /**
754
+ * Deploy a WASM signing policy program to the Sequence0 chain.
755
+ *
756
+ * The WASM bytecode is uploaded to the ProgramRegistry contract and
757
+ * assigned a unique programId (bytes32). Once deployed, the program
758
+ * can be attached to any wallet owned by the deployer.
759
+ *
760
+ * @param options - Program deployment options (bytecode, metadata, limits)
761
+ * @returns programId as a bytes32 hex string
762
+ *
763
+ * @throws {Sequence0Error} If no ownerSigner is configured
764
+ * @throws {NetworkError} If the deployment transaction fails
765
+ *
766
+ * @example
767
+ * ```typescript
768
+ * const programId = await s0.deployProgram({
769
+ * bytecode: fs.readFileSync('spending-limit.wasm'),
770
+ * metadataUri: 'ipfs://Qm.../metadata.json',
771
+ * gasLimit: 5_000_000,
772
+ * memoryLimit: 16,
773
+ * });
774
+ * console.log('Deployed program:', programId);
775
+ * ```
776
+ */
777
+ async deployProgram(options) {
778
+ if (!this.ownerSigner) {
779
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required to deploy programs. ' +
780
+ 'Provide one in NetworkConfig.');
781
+ }
782
+ // Convert bytecode to hex string if ArrayBuffer
783
+ let bytecodeHex;
784
+ if (options.bytecode instanceof ArrayBuffer) {
785
+ const bytes = new Uint8Array(options.bytecode);
786
+ bytecodeHex = Array.from(bytes)
787
+ .map((b) => b.toString(16).padStart(2, '0'))
788
+ .join('');
789
+ }
790
+ else {
791
+ bytecodeHex = options.bytecode.startsWith('0x')
792
+ ? options.bytecode.slice(2)
793
+ : options.bytecode;
794
+ }
795
+ const metadataUri = options.metadataUri || '';
796
+ const gasLimit = options.gasLimit ?? 10000000;
797
+ const memoryLimit = options.memoryLimit ?? 16;
798
+ // Build ownership proof for the deployment
799
+ const proof = await this.signOwnershipProof('program-deploy', 'deploy');
800
+ if (!proof) {
801
+ throw new errors_1.Sequence0Error('Failed to generate ownership proof for program deployment');
802
+ }
803
+ return this.withFailover(async (http) => {
804
+ const response = await http.post('/programs/deploy', {
805
+ bytecode: bytecodeHex,
806
+ metadata_uri: metadataUri,
807
+ gas_limit: gasLimit,
808
+ memory_limit: memoryLimit,
809
+ owner_signature: proof.owner_signature,
810
+ timestamp: proof.timestamp,
811
+ });
812
+ if (!response || typeof response.program_id !== 'string') {
813
+ throw new errors_1.Sequence0Error('Invalid response from /programs/deploy: missing program_id');
814
+ }
815
+ return response.program_id;
816
+ });
817
+ }
818
+ /**
819
+ * Attach a WASM program to a wallet.
820
+ *
821
+ * Only the wallet owner can attach programs. Once attached, the program
822
+ * runs on every sign request for this wallet -- the agent evaluates it
823
+ * in a sandboxed WASM environment and rejects the request if the program
824
+ * returns "deny".
825
+ *
826
+ * @param walletId - The wallet to attach the program to
827
+ * @param programId - The program ID (bytes32 hex) from deployProgram()
828
+ *
829
+ * @throws {Sequence0Error} If no ownerSigner is configured
830
+ * @throws {NetworkError} If the attach transaction fails
831
+ *
832
+ * @example
833
+ * ```typescript
834
+ * await s0.attachProgram('my-wallet', programId);
835
+ * ```
836
+ */
837
+ async attachProgram(walletId, programId) {
838
+ (0, validation_1.validateWalletId)(walletId);
839
+ if (!programId || typeof programId !== 'string') {
840
+ throw new errors_1.Sequence0Error('programId must be a non-empty string');
841
+ }
842
+ const proof = await this.signOwnershipProof(walletId, 'attach-program');
843
+ if (!proof) {
844
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required to attach programs');
845
+ }
846
+ return this.withFailover(async (http) => {
847
+ await http.post('/programs/attach', {
848
+ wallet_id: walletId,
849
+ program_id: programId,
850
+ owner_signature: proof.owner_signature,
851
+ timestamp: proof.timestamp,
852
+ });
853
+ });
854
+ }
855
+ /**
856
+ * Detach a WASM program from a wallet.
857
+ *
858
+ * Only the wallet owner can detach programs. The program is no longer
859
+ * evaluated on sign requests for this wallet after detachment.
860
+ *
861
+ * @param walletId - The wallet to detach the program from
862
+ * @param programId - The program ID (bytes32 hex) to detach
863
+ *
864
+ * @throws {Sequence0Error} If no ownerSigner is configured
865
+ * @throws {NetworkError} If the detach transaction fails
866
+ *
867
+ * @example
868
+ * ```typescript
869
+ * await s0.detachProgram('my-wallet', programId);
870
+ * ```
871
+ */
872
+ async detachProgram(walletId, programId) {
873
+ (0, validation_1.validateWalletId)(walletId);
874
+ if (!programId || typeof programId !== 'string') {
875
+ throw new errors_1.Sequence0Error('programId must be a non-empty string');
876
+ }
877
+ const proof = await this.signOwnershipProof(walletId, 'detach-program');
878
+ if (!proof) {
879
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required to detach programs');
880
+ }
881
+ return this.withFailover(async (http) => {
882
+ await http.post('/programs/detach', {
883
+ wallet_id: walletId,
884
+ program_id: programId,
885
+ owner_signature: proof.owner_signature,
886
+ timestamp: proof.timestamp,
887
+ });
888
+ });
889
+ }
890
+ /**
891
+ * Get all WASM programs attached to a wallet.
892
+ *
893
+ * @param walletId - The wallet to query
894
+ * @returns Array of program info objects
895
+ *
896
+ * @throws {NetworkError} If the agent is unreachable
897
+ *
898
+ * @example
899
+ * ```typescript
900
+ * const programs = await s0.getWalletPrograms('my-wallet');
901
+ * for (const p of programs) {
902
+ * console.log(`${p.programId}: active=${p.isActive}, gas=${p.gasLimit}`);
903
+ * }
904
+ * ```
905
+ */
906
+ async getWalletPrograms(walletId) {
907
+ (0, validation_1.validateWalletId)(walletId);
908
+ return this.withFailover(async (http) => {
909
+ const response = await http.get(`/programs/wallet/${walletId}`);
910
+ if (!response || !Array.isArray(response.programs)) {
911
+ return [];
912
+ }
913
+ return response.programs.map((p) => ({
914
+ programId: p.program_id,
915
+ deployer: p.deployer,
916
+ createdAt: p.created_at,
917
+ isActive: p.is_active,
918
+ metadataUri: p.metadata_uri,
919
+ gasLimit: p.gas_limit,
920
+ memoryLimit: p.memory_limit,
921
+ }));
922
+ });
923
+ }
924
+ // ────────────────────────────────────────────────
925
+ // K2: Atomic Cross-Chain Signing
926
+ // ────────────────────────────────────────────────
927
+ /**
928
+ * Sign multiple transactions across chains atomically (all-or-nothing).
929
+ *
930
+ * Submits a batch of signing operations to the agent network. The agents
931
+ * coordinate via a 2-phase commit protocol: either all operations produce
932
+ * valid signatures, or the entire batch is aborted and no signatures are
933
+ * released.
934
+ *
935
+ * This is essential for:
936
+ * - Cross-chain arbitrage (buy on chain A, sell on chain B)
937
+ * - Bridge transfers (lock on source, mint on destination)
938
+ * - Multi-leg DeFi strategies
939
+ *
940
+ * @param options - Atomic signing options with operations array
941
+ * @returns Result with all signatures (if committed) or error (if aborted)
942
+ *
943
+ * @throws {Sequence0Error} If no ownerSigner is configured or operations are empty
944
+ * @throws {TimeoutError} If the atomic signing times out
945
+ *
946
+ * @example
947
+ * ```typescript
948
+ * const result = await s0.signAtomic({
949
+ * operations: [
950
+ * { walletId: 'eth-wallet', chain: 'ethereum', message: '0x...' },
951
+ * { walletId: 'arb-wallet', chain: 'arbitrum', message: '0x...' },
952
+ * ],
953
+ * timeout: 60000,
954
+ * });
955
+ *
956
+ * if (result.status === 'committed') {
957
+ * for (const [reqId, sig] of result.signatures) {
958
+ * console.log(`${reqId}: ${sig}`);
959
+ * }
960
+ * } else {
961
+ * console.error('Atomic signing aborted:', result.error);
962
+ * }
963
+ * ```
964
+ */
965
+ async signAtomic(options) {
966
+ if (!options.operations || options.operations.length === 0) {
967
+ throw new errors_1.Sequence0Error('operations array must not be empty');
968
+ }
969
+ // Validate all operations
970
+ for (const op of options.operations) {
971
+ (0, validation_1.validateWalletId)(op.walletId);
972
+ (0, validation_1.validateChain)(op.chain);
973
+ (0, validation_1.validateHexMessage)(op.message);
974
+ }
975
+ const timeout = options.timeout ?? 60000;
976
+ const deadlineBlocks = options.deadlineBlocks ?? 50;
977
+ // Build ownership proofs for all unique wallet IDs in the batch
978
+ const uniqueWalletIds = [...new Set(options.operations.map((op) => op.walletId))];
979
+ const proofs = {};
980
+ for (const walletId of uniqueWalletIds) {
981
+ const proof = await this.signOwnershipProof(walletId, 'atomic-sign');
982
+ if (!proof) {
983
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required for atomic signing. ' +
984
+ 'Provide one in NetworkConfig.');
985
+ }
986
+ proofs[walletId] = proof;
987
+ }
988
+ // Build the request payload
989
+ const operationsPayload = options.operations.map((op) => ({
990
+ wallet_id: op.walletId,
991
+ chain: op.chain,
992
+ message: op.message,
993
+ owner_signature: proofs[op.walletId].owner_signature,
994
+ timestamp: proofs[op.walletId].timestamp,
995
+ }));
996
+ // Submit the atomic signing request
997
+ const submitResponse = await this.withFailover(async (http) => {
998
+ return http.post('/sign-atomic', {
999
+ operations: operationsPayload,
1000
+ deadline_blocks: deadlineBlocks,
1001
+ });
1002
+ });
1003
+ if (!submitResponse || typeof submitResponse.manifest_id !== 'string') {
1004
+ throw new errors_1.Sequence0Error('Invalid response from /sign-atomic: missing manifest_id');
1005
+ }
1006
+ const manifestId = submitResponse.manifest_id;
1007
+ // Poll for completion
1008
+ const deadline = Date.now() + timeout;
1009
+ while (Date.now() < deadline) {
1010
+ const result = await this.withFailover(async (http) => {
1011
+ return http.get(`/sign-atomic/${manifestId}`);
1012
+ });
1013
+ if (result.status === 'committed') {
1014
+ const signatures = new Map();
1015
+ if (result.signatures) {
1016
+ for (const [reqId, sig] of Object.entries(result.signatures)) {
1017
+ signatures.set(reqId, sig);
1018
+ }
1019
+ }
1020
+ return {
1021
+ manifestId,
1022
+ status: 'committed',
1023
+ signatures,
1024
+ };
1025
+ }
1026
+ if (result.status === 'aborted') {
1027
+ return {
1028
+ manifestId,
1029
+ status: 'aborted',
1030
+ signatures: new Map(),
1031
+ error: result.error || 'Atomic signing batch aborted by the agent network',
1032
+ };
1033
+ }
1034
+ // Still pending -- wait and retry
1035
+ await sleep(1000);
1036
+ }
1037
+ throw new errors_1.TimeoutError(`Atomic signing manifest ${manifestId} timed out after ${timeout}ms`);
1038
+ }
1039
+ // ────────────────────────────────────────────────
1040
+ // K3: Settlement
1041
+ // ────────────────────────────────────────────────
1042
+ /**
1043
+ * Get a SettlementClient for K3 Universal Settlement Network operations.
1044
+ *
1045
+ * The settlement client provides methods to submit payment intents,
1046
+ * query cycle status, and retrieve settlement history. Intents are
1047
+ * batched and netted off-chain, then settled atomically via K2.
1048
+ *
1049
+ * @returns A SettlementClient instance bound to the current agent
1050
+ *
1051
+ * @example
1052
+ * ```typescript
1053
+ * const settlement = s0.getSettlementClient();
1054
+ *
1055
+ * const { intentHash, cycleId } = await settlement.submitIntent(
1056
+ * {
1057
+ * senderWalletId: 'alice-wallet',
1058
+ * recipientWalletId: 'bob-wallet',
1059
+ * chain: 'ethereum',
1060
+ * amount: '1000000000000000000',
1061
+ * },
1062
+ * ownerSignature,
1063
+ * timestamp,
1064
+ * );
1065
+ *
1066
+ * const cycle = await settlement.getCurrentCycle();
1067
+ * console.log(`Cycle ${cycle.cycleId}: ${cycle.status}`);
1068
+ * ```
1069
+ */
1070
+ async getSettlementClient() {
1071
+ const http = await this.getHttp();
1072
+ return new settlement_1.SettlementClient(this.resolvedAgentUrl, http);
1073
+ }
1074
+ // ────────────────────────────────────────────────
1075
+ // K7: Universal Account
1076
+ // ────────────────────────────────────────────────
1077
+ /**
1078
+ * Get a UniversalAccountClient bound to a healthy agent.
1079
+ *
1080
+ * The client communicates directly with the agent's `/universal/*`
1081
+ * endpoints for account creation, balance queries, and sends.
1082
+ *
1083
+ * @returns A UniversalAccountClient instance
1084
+ *
1085
+ * @example
1086
+ * ```typescript
1087
+ * const ua = await s0.getUniversalAccountClient();
1088
+ *
1089
+ * const balance = await ua.getUnifiedBalance('ua-abc123');
1090
+ * console.log('Chains:', balance.totalChains);
1091
+ *
1092
+ * const route = await ua.previewRoute({
1093
+ * accountId: 'ua-abc123',
1094
+ * to: '0x...',
1095
+ * amount: '1.0',
1096
+ * token: 'ETH',
1097
+ * });
1098
+ * console.log(`Route: ${route.sourceChain} -> ${route.destinationChain}`);
1099
+ * ```
1100
+ */
1101
+ async getUniversalAccountClient() {
1102
+ await this.getHttp(); // Ensure agent URL is resolved
1103
+ return new universal_account_1.UniversalAccountClient(this.resolvedAgentUrl);
1104
+ }
1105
+ /**
1106
+ * Create a new universal account — one identity across all 81 chains.
1107
+ *
1108
+ * This is a convenience method that discovers a healthy agent,
1109
+ * creates a UniversalAccountClient, and calls createAccount.
1110
+ * For repeated operations, prefer `getUniversalAccountClient()`
1111
+ * and reuse the client.
1112
+ *
1113
+ * @param options - Account creation options
1114
+ * @returns The created account info with all chain addresses
1115
+ *
1116
+ * @example
1117
+ * ```typescript
1118
+ * const account = await s0.createUniversalAccount({
1119
+ * ownerSignature: '0x...',
1120
+ * timestamp: Date.now(),
1121
+ * });
1122
+ *
1123
+ * console.log('Account ID:', account.accountId);
1124
+ * console.log('Ethereum:', account.chainAddresses.ethereum.address);
1125
+ * console.log('Bitcoin:', account.chainAddresses.bitcoin.address);
1126
+ * console.log('Solana:', account.chainAddresses.solana.address);
1127
+ * ```
1128
+ *
1129
+ * @throws {Sequence0Error} If the creation parameters are invalid
1130
+ * @throws {NetworkError} If no healthy agent is available
1131
+ */
1132
+ async createUniversalAccount(options) {
1133
+ const client = await this.getUniversalAccountClient();
1134
+ return client.createAccount(options);
1135
+ }
1136
+ // ────────────────────────────────────────────────
726
1137
  // WebSocket Events
727
1138
  // ────────────────────────────────────────────────
728
1139
  /**
@@ -870,6 +1281,127 @@ class Sequence0 {
870
1281
  const random = secureRandom().toString(36).slice(2, 8);
871
1282
  return `s0-${timestamp}-${random}`;
872
1283
  }
1284
+ // ────────────────────────────────────────────────
1285
+ // K4: Sovereign Agency Protocol — Delegation
1286
+ // ────────────────────────────────────────────────
1287
+ /**
1288
+ * Create a delegation grant for a wallet (owner only).
1289
+ */
1290
+ async createDelegation(walletId, options) {
1291
+ (0, validation_1.validateWalletId)(walletId);
1292
+ const proof = await this.signOwnershipProof(walletId, 'delegate');
1293
+ if (!proof) {
1294
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required to create delegation grants');
1295
+ }
1296
+ return this.withFailover(async (http) => {
1297
+ return http.post('/delegations', {
1298
+ wallet_id: walletId,
1299
+ delegate: options.to,
1300
+ chains: options.chains,
1301
+ wasm_policy_id: options.wasmPolicyId,
1302
+ constraints: options.constraints,
1303
+ valid_from: options.validFrom || new Date().toISOString(),
1304
+ valid_until: options.validUntil,
1305
+ sub_delegation: options.subDelegation ?? false,
1306
+ max_sub_depth: options.maxSubDepth ?? 0,
1307
+ activation: options.activation,
1308
+ owner_signature: proof.owner_signature,
1309
+ timestamp: proof.timestamp,
1310
+ });
1311
+ });
1312
+ }
1313
+ /**
1314
+ * Create a sub-delegation from an existing delegation grant.
1315
+ */
1316
+ async createSubDelegation(walletId, options) {
1317
+ (0, validation_1.validateWalletId)(walletId);
1318
+ const signerKey = options.signerKey.startsWith('0x') ? options.signerKey : '0x' + options.signerKey;
1319
+ const delegateSigningKey = new ethers_1.SigningKey(signerKey);
1320
+ const timestamp = Math.floor(Date.now() / 1000);
1321
+ const network = this.config.network;
1322
+ const chainId = eip712_1.SEQUENCE0_CHAIN_IDS[network] || eip712_1.SEQUENCE0_CHAIN_IDS.mainnet;
1323
+ const walletFactory = eip712_1.WALLET_FACTORY_ADDRESSES[network] || eip712_1.WALLET_FACTORY_ADDRESSES.mainnet;
1324
+ const digest = (0, eip712_1.computeEip712Digest)(walletId, 'sub-delegate', timestamp, chainId, walletFactory);
1325
+ const sig = delegateSigningKey.sign(digest);
1326
+ const v = sig.v === 27 ? '1b' : '1c';
1327
+ const delegateSignature = '0x' + sig.r.slice(2) + sig.s.slice(2) + v;
1328
+ return this.withFailover(async (http) => {
1329
+ return http.post('/delegations/sub', {
1330
+ wallet_id: walletId,
1331
+ parent_grant_id: options.parentGrantId,
1332
+ delegate: options.to,
1333
+ chains: options.chains,
1334
+ constraints: options.constraints,
1335
+ valid_from: options.validFrom || new Date().toISOString(),
1336
+ valid_until: options.validUntil,
1337
+ sub_delegation: options.subDelegation ?? false,
1338
+ max_sub_depth: options.maxSubDepth ?? 0,
1339
+ activation: options.activation,
1340
+ delegate_signature: delegateSignature,
1341
+ timestamp,
1342
+ });
1343
+ });
1344
+ }
1345
+ /**
1346
+ * Revoke a delegation grant (cascading to all sub-grants).
1347
+ */
1348
+ async revokeDelegation(walletId, delegationId) {
1349
+ (0, validation_1.validateWalletId)(walletId);
1350
+ const proof = await this.signOwnershipProof(walletId, 'revoke');
1351
+ if (!proof) {
1352
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required to revoke delegation grants');
1353
+ }
1354
+ await this.withFailover(async (http) => {
1355
+ return http.post(`/delegations/${delegationId}/revoke`, {
1356
+ owner_signature: proof.owner_signature,
1357
+ timestamp: proof.timestamp,
1358
+ });
1359
+ });
1360
+ }
1361
+ /**
1362
+ * List all delegation grants for a wallet.
1363
+ */
1364
+ async listDelegations(walletId) {
1365
+ (0, validation_1.validateWalletId)(walletId);
1366
+ return this.withFailover(async (http) => {
1367
+ const res = await http.get(`/delegations?wallet_id=${encodeURIComponent(walletId)}`);
1368
+ return res.delegations;
1369
+ });
1370
+ }
1371
+ /**
1372
+ * Get the delegation tree for a wallet.
1373
+ */
1374
+ async getDelegationTree(walletId) {
1375
+ (0, validation_1.validateWalletId)(walletId);
1376
+ return this.withFailover(async (http) => {
1377
+ return http.get(`/delegations/tree?wallet_id=${encodeURIComponent(walletId)}`);
1378
+ });
1379
+ }
1380
+ /**
1381
+ * Send heartbeat for dead-man's switch delegation grants.
1382
+ */
1383
+ async heartbeat(walletId) {
1384
+ (0, validation_1.validateWalletId)(walletId);
1385
+ const proof = await this.signOwnershipProof(walletId, 'heartbeat');
1386
+ if (!proof) {
1387
+ throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required for heartbeat');
1388
+ }
1389
+ await this.withFailover(async (http) => {
1390
+ return http.post(`/delegations/heartbeat`, {
1391
+ wallet_id: walletId,
1392
+ owner_signature: proof.owner_signature,
1393
+ timestamp: proof.timestamp,
1394
+ });
1395
+ });
1396
+ }
1397
+ /**
1398
+ * Check remaining authority status of a delegation.
1399
+ */
1400
+ async checkAuthority(delegationId) {
1401
+ return this.withFailover(async (http) => {
1402
+ return http.get(`/delegations/${delegationId}/status`);
1403
+ });
1404
+ }
873
1405
  }
874
1406
  exports.Sequence0 = Sequence0;
875
1407
  function sleep(ms) {