@ottochain/sdk 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -29,7 +29,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
29
29
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
30
30
  };
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.assert = exports.safeParse = exports.validateKeyPair = exports.validateAddress = exports.validatePublicKey = exports.validatePrivateKey = exports.validate = exports.CompleteContractRequestSchema = exports.AcceptContractRequestSchema = exports.ProposeContractRequestSchema = exports.ContractTermsSchema = exports.PlatformLinkSchema = exports.AgentIdentityRegistrationSchema = exports.TransferParamsSchema = exports.CurrencyTransactionSchema = exports.CurrencyTransactionValueSchema = exports.TransactionReferenceSchema = exports.SignedSchema = exports.SignatureProofSchema = exports.KeyPairSchema = exports.PublicKeySchema = exports.PrivateKeySchema = exports.DagAddressSchema = exports.wrapError = exports.isErrorCode = exports.ErrorCode = exports.TransactionError = exports.SigningError = exports.ValidationError = exports.NetworkError = exports.OttoChainError = void 0;
32
+ exports.MetagraphClient = exports.assert = exports.safeParse = exports.validateKeyPair = exports.validateAddress = exports.validatePublicKey = exports.validatePrivateKey = exports.validate = exports.CompleteContractRequestSchema = exports.AcceptContractRequestSchema = exports.ProposeContractRequestSchema = exports.ContractTermsSchema = exports.PlatformLinkSchema = exports.AgentIdentityRegistrationSchema = exports.TransferParamsSchema = exports.CurrencyTransactionSchema = exports.CurrencyTransactionValueSchema = exports.TransactionReferenceSchema = exports.SignedSchema = exports.SignatureProofSchema = exports.KeyPairSchema = exports.PublicKeySchema = exports.PrivateKeySchema = exports.DagAddressSchema = exports.wrapError = exports.isErrorCode = exports.ErrorCode = exports.TransactionError = exports.SigningError = exports.ValidationError = exports.NetworkError = exports.OttoChainError = void 0;
33
33
  // Type aliases for semantic clarity (matches wire format)
34
34
  __exportStar(require("./types.js"), exports);
35
35
  // Metakit utilities (signing, hashing, HTTP client)
@@ -77,3 +77,6 @@ Object.defineProperty(exports, "assert", { enumerable: true, get: function () {
77
77
  __exportStar(require("./errors.js"), exports);
78
78
  // Validation schemas and helpers
79
79
  __exportStar(require("./validation.js"), exports);
80
+ // Ottochain metagraph client
81
+ var metagraph_client_js_1 = require("./ottochain/metagraph-client.js");
82
+ Object.defineProperty(exports, "MetagraphClient", { enumerable: true, get: function () { return metagraph_client_js_1.MetagraphClient; } });
@@ -8,7 +8,7 @@
8
8
  * @packageDocumentation
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.NetworkError = exports.HttpClient = exports.DataL1Client = exports.CurrencyL1Client = exports.unitsToToken = exports.tokenToUnits = exports.isValidDagAddress = exports.getTransactionReference = exports.hashCurrencyTransaction = exports.encodeCurrencyTransaction = exports.verifyCurrencyTransaction = exports.signCurrencyTransaction = exports.createCurrencyTransactionBatch = exports.createCurrencyTransaction = exports.TOKEN_DECIMALS = exports.isValidPublicKey = exports.isValidPrivateKey = exports.getAddress = exports.getPublicKeyId = exports.getPublicKeyHex = exports.keyPairFromPrivateKey = exports.generateKeyPair = exports.batchSign = exports.addSignature = exports.createSignedObject = exports.verifySignature = exports.verifyHash = exports.verify = exports.signHash = exports.signDataUpdate = exports.sign = exports.decodeDataUpdate = exports.computeDigest = exports.hashData = exports.hashBytes = exports.hash = exports.encodeDataUpdate = exports.toBytes = exports.canonicalize = exports.CONSTELLATION_PREFIX = exports.ALGORITHM = void 0;
11
+ exports.createDataTransactionRequest = exports.createScriptPayload = exports.createStateMachinePayload = exports.getPublicKeyForRegistration = exports.addTransactionSignature = exports.signTransaction = exports.createInvokeScriptPayload = exports.createArchivePayload = exports.createTransitionPayload = exports.NetworkError = exports.HttpClient = exports.DataL1Client = exports.CurrencyL1Client = exports.unitsToToken = exports.tokenToUnits = exports.isValidDagAddress = exports.getTransactionReference = exports.hashCurrencyTransaction = exports.encodeCurrencyTransaction = exports.verifyCurrencyTransaction = exports.signCurrencyTransaction = exports.createCurrencyTransactionBatch = exports.createCurrencyTransaction = exports.TOKEN_DECIMALS = exports.isValidPublicKey = exports.isValidPrivateKey = exports.getAddress = exports.getPublicKeyId = exports.getPublicKeyHex = exports.keyPairFromPrivateKey = exports.generateKeyPair = exports.batchSign = exports.addSignature = exports.createSignedObject = exports.verifySignature = exports.verifyHash = exports.verify = exports.signHash = exports.signDataUpdate = exports.sign = exports.decodeDataUpdate = exports.computeDigest = exports.hashData = exports.hashBytes = exports.hash = exports.encodeDataUpdate = exports.toBytes = exports.canonicalize = exports.CONSTELLATION_PREFIX = exports.ALGORITHM = void 0;
12
12
  var types_js_1 = require("./types.js");
13
13
  Object.defineProperty(exports, "ALGORITHM", { enumerable: true, get: function () { return types_js_1.ALGORITHM; } });
14
14
  Object.defineProperty(exports, "CONSTELLATION_PREFIX", { enumerable: true, get: function () { return types_js_1.CONSTELLATION_PREFIX; } });
@@ -72,3 +72,15 @@ Object.defineProperty(exports, "CurrencyL1Client", { enumerable: true, get: func
72
72
  Object.defineProperty(exports, "DataL1Client", { enumerable: true, get: function () { return index_js_1.DataL1Client; } });
73
73
  Object.defineProperty(exports, "HttpClient", { enumerable: true, get: function () { return index_js_1.HttpClient; } });
74
74
  Object.defineProperty(exports, "NetworkError", { enumerable: true, get: function () { return index_js_1.NetworkError; } });
75
+ // Transaction helpers for self-signed mode
76
+ var transaction_js_1 = require("./transaction.js");
77
+ Object.defineProperty(exports, "createTransitionPayload", { enumerable: true, get: function () { return transaction_js_1.createTransitionPayload; } });
78
+ Object.defineProperty(exports, "createArchivePayload", { enumerable: true, get: function () { return transaction_js_1.createArchivePayload; } });
79
+ Object.defineProperty(exports, "createInvokeScriptPayload", { enumerable: true, get: function () { return transaction_js_1.createInvokeScriptPayload; } });
80
+ Object.defineProperty(exports, "signTransaction", { enumerable: true, get: function () { return transaction_js_1.signTransaction; } });
81
+ Object.defineProperty(exports, "addTransactionSignature", { enumerable: true, get: function () { return transaction_js_1.addTransactionSignature; } });
82
+ Object.defineProperty(exports, "getPublicKeyForRegistration", { enumerable: true, get: function () { return transaction_js_1.getPublicKeyForRegistration; } });
83
+ var transaction_js_2 = require("./transaction.js");
84
+ Object.defineProperty(exports, "createStateMachinePayload", { enumerable: true, get: function () { return transaction_js_2.createStateMachinePayload; } });
85
+ Object.defineProperty(exports, "createScriptPayload", { enumerable: true, get: function () { return transaction_js_2.createScriptPayload; } });
86
+ Object.defineProperty(exports, "createDataTransactionRequest", { enumerable: true, get: function () { return transaction_js_2.createDataTransactionRequest; } });
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ /**
3
+ * Transaction Helpers for Self-Signed Mode
4
+ *
5
+ * These helpers create properly formatted payloads for the bridge's
6
+ * self-signed mode, where clients sign their own transactions.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getPublicKeyForRegistration = exports.addTransactionSignature = exports.createDataTransactionRequest = exports.signTransaction = exports.createInvokeScriptPayload = exports.createScriptPayload = exports.createArchivePayload = exports.createTransitionPayload = exports.createStateMachinePayload = void 0;
10
+ const sign_js_1 = require("./sign.js");
11
+ const wallet_js_1 = require("./wallet.js");
12
+ /**
13
+ * Create a new state machine fiber payload.
14
+ *
15
+ * @param params - State machine creation parameters
16
+ * @returns A CreateStateMachine message ready for signing
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const create = createStateMachinePayload({
21
+ * fiberId: crypto.randomUUID(),
22
+ * definition: {
23
+ * states: { CREATED: { on: { activate: 'ACTIVE' } }, ACTIVE: {} },
24
+ * initialState: 'CREATED',
25
+ * },
26
+ * initialData: { owner: myAddress },
27
+ * });
28
+ * const signed = await signTransaction(create, privateKey);
29
+ * ```
30
+ */
31
+ function createStateMachinePayload(params) {
32
+ return {
33
+ CreateStateMachine: {
34
+ fiberId: params.fiberId,
35
+ definition: params.definition,
36
+ initialData: params.initialData ?? {},
37
+ ...(params.parentFiberId ? { parentFiberId: params.parentFiberId } : {}),
38
+ },
39
+ };
40
+ }
41
+ exports.createStateMachinePayload = createStateMachinePayload;
42
+ /**
43
+ * Create a transition payload ready for signing.
44
+ *
45
+ * This creates the exact message structure expected by the metagraph.
46
+ *
47
+ * @param params - Transition parameters
48
+ * @returns A TransitionStateMachine message ready for signing
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const transition = createTransitionPayload({
53
+ * fiberId: 'my-fiber-id',
54
+ * eventName: 'activate',
55
+ * payload: {},
56
+ * targetSequenceNumber: 0,
57
+ * });
58
+ * ```
59
+ */
60
+ function createTransitionPayload(params) {
61
+ return {
62
+ TransitionStateMachine: {
63
+ fiberId: params.fiberId,
64
+ eventName: params.eventName,
65
+ payload: params.payload ?? {},
66
+ targetSequenceNumber: params.targetSequenceNumber,
67
+ },
68
+ };
69
+ }
70
+ exports.createTransitionPayload = createTransitionPayload;
71
+ /**
72
+ * Create an archive payload ready for signing.
73
+ *
74
+ * @param params - Archive parameters
75
+ * @returns An ArchiveStateMachine message ready for signing
76
+ */
77
+ function createArchivePayload(params) {
78
+ return {
79
+ ArchiveStateMachine: {
80
+ fiberId: params.fiberId,
81
+ targetSequenceNumber: params.targetSequenceNumber,
82
+ },
83
+ };
84
+ }
85
+ exports.createArchivePayload = createArchivePayload;
86
+ /**
87
+ * Create a new script fiber payload.
88
+ *
89
+ * Note: `initialState` must be an object or array, NOT a primitive.
90
+ *
91
+ * @param params - Script creation parameters
92
+ * @returns A CreateScript message ready for signing
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const script = createScriptPayload({
97
+ * fiberId: crypto.randomUUID(),
98
+ * scriptProgram: {
99
+ * methods: {
100
+ * increment: { "+": [{ var: "state.value" }, 1] },
101
+ * },
102
+ * },
103
+ * initialState: { value: 0 },
104
+ * accessControl: { type: 'open' },
105
+ * });
106
+ * const signed = await signTransaction(script, privateKey);
107
+ * ```
108
+ */
109
+ function createScriptPayload(params) {
110
+ return {
111
+ CreateScript: {
112
+ fiberId: params.fiberId,
113
+ scriptProgram: params.scriptProgram,
114
+ initialState: params.initialState ?? null,
115
+ accessControl: params.accessControl ?? { type: 'open' },
116
+ },
117
+ };
118
+ }
119
+ exports.createScriptPayload = createScriptPayload;
120
+ /**
121
+ * Create an invoke script payload ready for signing.
122
+ *
123
+ * @param params - Invoke script parameters
124
+ * @returns An InvokeScript message ready for signing
125
+ */
126
+ function createInvokeScriptPayload(params) {
127
+ return {
128
+ InvokeScript: {
129
+ fiberId: params.fiberId,
130
+ method: params.method,
131
+ args: params.args ?? {},
132
+ targetSequenceNumber: params.targetSequenceNumber,
133
+ },
134
+ };
135
+ }
136
+ exports.createInvokeScriptPayload = createInvokeScriptPayload;
137
+ /**
138
+ * Sign a transaction payload for self-signed mode.
139
+ *
140
+ * This creates a Signed<T> object with the exact format expected by the bridge's
141
+ * `/agent/transition` endpoint when using self-signed mode.
142
+ *
143
+ * @param message - The message to sign (e.g., from createTransitionPayload)
144
+ * @param privateKey - The private key in hex format (64 characters)
145
+ * @returns A signed object ready for submission to the bridge
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * import { createTransitionPayload, signTransaction, generateKeyPair } from '@ottochain/sdk';
150
+ *
151
+ * const keyPair = generateKeyPair();
152
+ *
153
+ * // Create the transition message
154
+ * const transition = createTransitionPayload({
155
+ * fiberId: 'my-fiber-id',
156
+ * eventName: 'activate',
157
+ * payload: {},
158
+ * targetSequenceNumber: 0,
159
+ * });
160
+ *
161
+ * // Sign it
162
+ * const signedUpdate = await signTransaction(transition, keyPair.privateKey);
163
+ *
164
+ * // Submit to bridge
165
+ * await fetch('https://bridge/agent/transition', {
166
+ * method: 'POST',
167
+ * body: JSON.stringify({
168
+ * fiberId: 'my-fiber-id',
169
+ * signedUpdate,
170
+ * }),
171
+ * });
172
+ * ```
173
+ */
174
+ async function signTransaction(message, privateKey) {
175
+ const proof = await (0, sign_js_1.signDataUpdate)(message, privateKey);
176
+ return {
177
+ value: message,
178
+ proofs: [proof],
179
+ };
180
+ }
181
+ exports.signTransaction = signTransaction;
182
+ /**
183
+ * Wrap a signed transaction in the DataTransactionRequest format
184
+ * expected by tessellation's DL1 `/data` endpoint.
185
+ *
186
+ * @param signed - A signed transaction from signTransaction()
187
+ * @returns Payload ready for POST to DL1 `/data`
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * const transition = createTransitionPayload({ ... });
192
+ * const signed = await signTransaction(transition, privateKey);
193
+ * const payload = createDataTransactionRequest(signed);
194
+ *
195
+ * // Submit directly to DL1
196
+ * await fetch('http://dl1-node:9400/data', {
197
+ * method: 'POST',
198
+ * headers: { 'Content-Type': 'application/json' },
199
+ * body: JSON.stringify(payload),
200
+ * });
201
+ * ```
202
+ */
203
+ function createDataTransactionRequest(signed) {
204
+ return { data: signed, fee: null };
205
+ }
206
+ exports.createDataTransactionRequest = createDataTransactionRequest;
207
+ /**
208
+ * Add an additional signature to a signed transaction.
209
+ *
210
+ * Use this for multi-signature scenarios where multiple parties
211
+ * need to sign the same transaction.
212
+ *
213
+ * @param signed - The already-signed transaction
214
+ * @param privateKey - Additional signer's private key
215
+ * @returns Transaction with additional signature
216
+ */
217
+ async function addTransactionSignature(signed, privateKey) {
218
+ const newProof = await (0, sign_js_1.signDataUpdate)(signed.value, privateKey);
219
+ return {
220
+ value: signed.value,
221
+ proofs: [...signed.proofs, newProof],
222
+ };
223
+ }
224
+ exports.addTransactionSignature = addTransactionSignature;
225
+ /**
226
+ * Get the public key ID from a private key in the format expected by registration.
227
+ *
228
+ * The bridge's self-signed registration expects the public key as a 128-character
229
+ * hex string (without the 04 prefix).
230
+ *
231
+ * @param privateKey - Private key in hex format
232
+ * @returns Public key ID (128 chars, no prefix)
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * const keyPair = generateKeyPair();
237
+ * const publicKeyId = getPublicKeyForRegistration(keyPair.privateKey);
238
+ *
239
+ * await fetch('https://bridge/agent/register', {
240
+ * method: 'POST',
241
+ * body: JSON.stringify({
242
+ * signingMode: 'self',
243
+ * publicKey: publicKeyId,
244
+ * displayName: 'My Agent',
245
+ * }),
246
+ * });
247
+ * ```
248
+ */
249
+ function getPublicKeyForRegistration(privateKey) {
250
+ return (0, wallet_js_1.getPublicKeyId)(privateKey);
251
+ }
252
+ exports.getPublicKeyForRegistration = getPublicKeyForRegistration;
@@ -11,6 +11,7 @@
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.MetagraphClient = void 0;
14
+ const transaction_js_1 = require("../metakit/transaction.js");
14
15
  const client_js_1 = require("../metakit/network/client.js");
15
16
  const types_js_1 = require("../metakit/network/types.js");
16
17
  const snapshot_js_1 = require("./snapshot.js");
@@ -43,6 +44,9 @@ class MetagraphClient {
43
44
  if (config.dl1Url) {
44
45
  this.dl1 = new client_js_1.HttpClient(config.dl1Url, config.timeout);
45
46
  }
47
+ // Build DL1 client pool from dl1Urls (falls back to dl1Url if provided)
48
+ const urls = config.dl1Urls ?? (config.dl1Url ? [config.dl1Url] : []);
49
+ this.dl1Clients = urls.map((url) => new client_js_1.HttpClient(url, config.timeout));
46
50
  }
47
51
  // -------------------------------------------------------------------------
48
52
  // Custom routes (ML0 /data-application/v1/*)
@@ -300,5 +304,53 @@ class MetagraphClient {
300
304
  }
301
305
  return this.dl1.post('/data', signedData);
302
306
  }
307
+ /**
308
+ * Submit a self-signed transaction directly to DL1 nodes.
309
+ *
310
+ * Wraps the signed payload in `{ data, fee: null }` format and submits
311
+ * to one of the configured DL1 nodes. Uses `Promise.any` when multiple
312
+ * DL1 URLs are configured for resilience.
313
+ *
314
+ * @param signed - A `Signed<T>` object from `signTransaction()`
315
+ * @returns Response containing the data hash
316
+ * @throws Error if no DL1 URLs are configured or all nodes fail
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * const metagraph = new MetagraphClient({
321
+ * ml0Url: 'http://localhost:9200',
322
+ * dl1Urls: ['http://node1:9400', 'http://node2:9400'],
323
+ * });
324
+ * const signed = await signTransaction(payload, privateKey);
325
+ * await metagraph.submitData(signed);
326
+ * ```
327
+ */
328
+ async submitData(signed) {
329
+ if (this.dl1Clients.length === 0) {
330
+ throw new Error('dl1Url or dl1Urls is required for submitData');
331
+ }
332
+ const request = (0, transaction_js_1.createDataTransactionRequest)(signed);
333
+ if (this.dl1Clients.length === 1) {
334
+ return this.dl1Clients[0].post('/data', request);
335
+ }
336
+ // Try all DL1 nodes concurrently, return first success
337
+ const errors = [];
338
+ return new Promise((resolve, reject) => {
339
+ let settled = false;
340
+ let pending = this.dl1Clients.length;
341
+ for (const client of this.dl1Clients) {
342
+ client.post('/data', request).then((result) => { if (!settled) {
343
+ settled = true;
344
+ resolve(result);
345
+ } }, (err) => {
346
+ errors.push(err instanceof Error ? err : new Error(String(err)));
347
+ pending--;
348
+ if (pending === 0 && !settled) {
349
+ reject(new Error('All DL1 nodes failed: ' + errors.map(e => e.message).join('; ')));
350
+ }
351
+ });
352
+ }
353
+ });
354
+ }
303
355
  }
304
356
  exports.MetagraphClient = MetagraphClient;
package/dist/esm/index.js CHANGED
@@ -31,3 +31,5 @@ validate, validatePrivateKey, validatePublicKey, validateAddress, validateKeyPai
31
31
  export * from './errors.js';
32
32
  // Validation schemas and helpers
33
33
  export * from './validation.js';
34
+ // Ottochain metagraph client
35
+ export { MetagraphClient } from './ottochain/metagraph-client.js';
@@ -28,3 +28,6 @@ export { TOKEN_DECIMALS } from './currency-types.js';
28
28
  export { createCurrencyTransaction, createCurrencyTransactionBatch, signCurrencyTransaction, verifyCurrencyTransaction, encodeCurrencyTransaction, hashCurrencyTransaction, getTransactionReference, isValidDagAddress, tokenToUnits, unitsToToken, } from './currency-transaction.js';
29
29
  // Network operations
30
30
  export { CurrencyL1Client, DataL1Client, HttpClient, NetworkError } from './network/index.js';
31
+ // Transaction helpers for self-signed mode
32
+ export { createTransitionPayload, createArchivePayload, createInvokeScriptPayload, signTransaction, addTransactionSignature, getPublicKeyForRegistration, } from './transaction.js';
33
+ export { createStateMachinePayload, createScriptPayload, createDataTransactionRequest, } from './transaction.js';
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Transaction Helpers for Self-Signed Mode
3
+ *
4
+ * These helpers create properly formatted payloads for the bridge's
5
+ * self-signed mode, where clients sign their own transactions.
6
+ */
7
+ import { signDataUpdate } from './sign.js';
8
+ import { getPublicKeyId } from './wallet.js';
9
+ /**
10
+ * Create a new state machine fiber payload.
11
+ *
12
+ * @param params - State machine creation parameters
13
+ * @returns A CreateStateMachine message ready for signing
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const create = createStateMachinePayload({
18
+ * fiberId: crypto.randomUUID(),
19
+ * definition: {
20
+ * states: { CREATED: { on: { activate: 'ACTIVE' } }, ACTIVE: {} },
21
+ * initialState: 'CREATED',
22
+ * },
23
+ * initialData: { owner: myAddress },
24
+ * });
25
+ * const signed = await signTransaction(create, privateKey);
26
+ * ```
27
+ */
28
+ export function createStateMachinePayload(params) {
29
+ return {
30
+ CreateStateMachine: {
31
+ fiberId: params.fiberId,
32
+ definition: params.definition,
33
+ initialData: params.initialData ?? {},
34
+ ...(params.parentFiberId ? { parentFiberId: params.parentFiberId } : {}),
35
+ },
36
+ };
37
+ }
38
+ /**
39
+ * Create a transition payload ready for signing.
40
+ *
41
+ * This creates the exact message structure expected by the metagraph.
42
+ *
43
+ * @param params - Transition parameters
44
+ * @returns A TransitionStateMachine message ready for signing
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const transition = createTransitionPayload({
49
+ * fiberId: 'my-fiber-id',
50
+ * eventName: 'activate',
51
+ * payload: {},
52
+ * targetSequenceNumber: 0,
53
+ * });
54
+ * ```
55
+ */
56
+ export function createTransitionPayload(params) {
57
+ return {
58
+ TransitionStateMachine: {
59
+ fiberId: params.fiberId,
60
+ eventName: params.eventName,
61
+ payload: params.payload ?? {},
62
+ targetSequenceNumber: params.targetSequenceNumber,
63
+ },
64
+ };
65
+ }
66
+ /**
67
+ * Create an archive payload ready for signing.
68
+ *
69
+ * @param params - Archive parameters
70
+ * @returns An ArchiveStateMachine message ready for signing
71
+ */
72
+ export function createArchivePayload(params) {
73
+ return {
74
+ ArchiveStateMachine: {
75
+ fiberId: params.fiberId,
76
+ targetSequenceNumber: params.targetSequenceNumber,
77
+ },
78
+ };
79
+ }
80
+ /**
81
+ * Create a new script fiber payload.
82
+ *
83
+ * Note: `initialState` must be an object or array, NOT a primitive.
84
+ *
85
+ * @param params - Script creation parameters
86
+ * @returns A CreateScript message ready for signing
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const script = createScriptPayload({
91
+ * fiberId: crypto.randomUUID(),
92
+ * scriptProgram: {
93
+ * methods: {
94
+ * increment: { "+": [{ var: "state.value" }, 1] },
95
+ * },
96
+ * },
97
+ * initialState: { value: 0 },
98
+ * accessControl: { type: 'open' },
99
+ * });
100
+ * const signed = await signTransaction(script, privateKey);
101
+ * ```
102
+ */
103
+ export function createScriptPayload(params) {
104
+ return {
105
+ CreateScript: {
106
+ fiberId: params.fiberId,
107
+ scriptProgram: params.scriptProgram,
108
+ initialState: params.initialState ?? null,
109
+ accessControl: params.accessControl ?? { type: 'open' },
110
+ },
111
+ };
112
+ }
113
+ /**
114
+ * Create an invoke script payload ready for signing.
115
+ *
116
+ * @param params - Invoke script parameters
117
+ * @returns An InvokeScript message ready for signing
118
+ */
119
+ export function createInvokeScriptPayload(params) {
120
+ return {
121
+ InvokeScript: {
122
+ fiberId: params.fiberId,
123
+ method: params.method,
124
+ args: params.args ?? {},
125
+ targetSequenceNumber: params.targetSequenceNumber,
126
+ },
127
+ };
128
+ }
129
+ /**
130
+ * Sign a transaction payload for self-signed mode.
131
+ *
132
+ * This creates a Signed<T> object with the exact format expected by the bridge's
133
+ * `/agent/transition` endpoint when using self-signed mode.
134
+ *
135
+ * @param message - The message to sign (e.g., from createTransitionPayload)
136
+ * @param privateKey - The private key in hex format (64 characters)
137
+ * @returns A signed object ready for submission to the bridge
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * import { createTransitionPayload, signTransaction, generateKeyPair } from '@ottochain/sdk';
142
+ *
143
+ * const keyPair = generateKeyPair();
144
+ *
145
+ * // Create the transition message
146
+ * const transition = createTransitionPayload({
147
+ * fiberId: 'my-fiber-id',
148
+ * eventName: 'activate',
149
+ * payload: {},
150
+ * targetSequenceNumber: 0,
151
+ * });
152
+ *
153
+ * // Sign it
154
+ * const signedUpdate = await signTransaction(transition, keyPair.privateKey);
155
+ *
156
+ * // Submit to bridge
157
+ * await fetch('https://bridge/agent/transition', {
158
+ * method: 'POST',
159
+ * body: JSON.stringify({
160
+ * fiberId: 'my-fiber-id',
161
+ * signedUpdate,
162
+ * }),
163
+ * });
164
+ * ```
165
+ */
166
+ export async function signTransaction(message, privateKey) {
167
+ const proof = await signDataUpdate(message, privateKey);
168
+ return {
169
+ value: message,
170
+ proofs: [proof],
171
+ };
172
+ }
173
+ /**
174
+ * Wrap a signed transaction in the DataTransactionRequest format
175
+ * expected by tessellation's DL1 `/data` endpoint.
176
+ *
177
+ * @param signed - A signed transaction from signTransaction()
178
+ * @returns Payload ready for POST to DL1 `/data`
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const transition = createTransitionPayload({ ... });
183
+ * const signed = await signTransaction(transition, privateKey);
184
+ * const payload = createDataTransactionRequest(signed);
185
+ *
186
+ * // Submit directly to DL1
187
+ * await fetch('http://dl1-node:9400/data', {
188
+ * method: 'POST',
189
+ * headers: { 'Content-Type': 'application/json' },
190
+ * body: JSON.stringify(payload),
191
+ * });
192
+ * ```
193
+ */
194
+ export function createDataTransactionRequest(signed) {
195
+ return { data: signed, fee: null };
196
+ }
197
+ /**
198
+ * Add an additional signature to a signed transaction.
199
+ *
200
+ * Use this for multi-signature scenarios where multiple parties
201
+ * need to sign the same transaction.
202
+ *
203
+ * @param signed - The already-signed transaction
204
+ * @param privateKey - Additional signer's private key
205
+ * @returns Transaction with additional signature
206
+ */
207
+ export async function addTransactionSignature(signed, privateKey) {
208
+ const newProof = await signDataUpdate(signed.value, privateKey);
209
+ return {
210
+ value: signed.value,
211
+ proofs: [...signed.proofs, newProof],
212
+ };
213
+ }
214
+ /**
215
+ * Get the public key ID from a private key in the format expected by registration.
216
+ *
217
+ * The bridge's self-signed registration expects the public key as a 128-character
218
+ * hex string (without the 04 prefix).
219
+ *
220
+ * @param privateKey - Private key in hex format
221
+ * @returns Public key ID (128 chars, no prefix)
222
+ *
223
+ * @example
224
+ * ```typescript
225
+ * const keyPair = generateKeyPair();
226
+ * const publicKeyId = getPublicKeyForRegistration(keyPair.privateKey);
227
+ *
228
+ * await fetch('https://bridge/agent/register', {
229
+ * method: 'POST',
230
+ * body: JSON.stringify({
231
+ * signingMode: 'self',
232
+ * publicKey: publicKeyId,
233
+ * displayName: 'My Agent',
234
+ * }),
235
+ * });
236
+ * ```
237
+ */
238
+ export function getPublicKeyForRegistration(privateKey) {
239
+ return getPublicKeyId(privateKey);
240
+ }
@@ -8,6 +8,7 @@
8
8
  * @see modules/data_l1/src/main/scala/xyz/kd5ujc/data_l1/DataL1CustomRoutes.scala
9
9
  * @packageDocumentation
10
10
  */
11
+ import { createDataTransactionRequest } from '../metakit/transaction.js';
11
12
  import { HttpClient } from '../metakit/network/client.js';
12
13
  import { NetworkError } from '../metakit/network/types.js';
13
14
  import { extractOnChainState } from './snapshot.js';
@@ -40,6 +41,9 @@ export class MetagraphClient {
40
41
  if (config.dl1Url) {
41
42
  this.dl1 = new HttpClient(config.dl1Url, config.timeout);
42
43
  }
44
+ // Build DL1 client pool from dl1Urls (falls back to dl1Url if provided)
45
+ const urls = config.dl1Urls ?? (config.dl1Url ? [config.dl1Url] : []);
46
+ this.dl1Clients = urls.map((url) => new HttpClient(url, config.timeout));
43
47
  }
44
48
  // -------------------------------------------------------------------------
45
49
  // Custom routes (ML0 /data-application/v1/*)
@@ -297,4 +301,52 @@ export class MetagraphClient {
297
301
  }
298
302
  return this.dl1.post('/data', signedData);
299
303
  }
304
+ /**
305
+ * Submit a self-signed transaction directly to DL1 nodes.
306
+ *
307
+ * Wraps the signed payload in `{ data, fee: null }` format and submits
308
+ * to one of the configured DL1 nodes. Uses `Promise.any` when multiple
309
+ * DL1 URLs are configured for resilience.
310
+ *
311
+ * @param signed - A `Signed<T>` object from `signTransaction()`
312
+ * @returns Response containing the data hash
313
+ * @throws Error if no DL1 URLs are configured or all nodes fail
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * const metagraph = new MetagraphClient({
318
+ * ml0Url: 'http://localhost:9200',
319
+ * dl1Urls: ['http://node1:9400', 'http://node2:9400'],
320
+ * });
321
+ * const signed = await signTransaction(payload, privateKey);
322
+ * await metagraph.submitData(signed);
323
+ * ```
324
+ */
325
+ async submitData(signed) {
326
+ if (this.dl1Clients.length === 0) {
327
+ throw new Error('dl1Url or dl1Urls is required for submitData');
328
+ }
329
+ const request = createDataTransactionRequest(signed);
330
+ if (this.dl1Clients.length === 1) {
331
+ return this.dl1Clients[0].post('/data', request);
332
+ }
333
+ // Try all DL1 nodes concurrently, return first success
334
+ const errors = [];
335
+ return new Promise((resolve, reject) => {
336
+ let settled = false;
337
+ let pending = this.dl1Clients.length;
338
+ for (const client of this.dl1Clients) {
339
+ client.post('/data', request).then((result) => { if (!settled) {
340
+ settled = true;
341
+ resolve(result);
342
+ } }, (err) => {
343
+ errors.push(err instanceof Error ? err : new Error(String(err)));
344
+ pending--;
345
+ if (pending === 0 && !settled) {
346
+ reject(new Error('All DL1 nodes failed: ' + errors.map(e => e.message).join('; ')));
347
+ }
348
+ });
349
+ }
350
+ });
351
+ }
300
352
  }
@@ -20,3 +20,5 @@ export { OttoChainError, NetworkError, ValidationError, SigningError, Transactio
20
20
  export { DagAddressSchema, PrivateKeySchema, PublicKeySchema, KeyPairSchema, SignatureProofSchema, SignedSchema, TransactionReferenceSchema, CurrencyTransactionValueSchema, CurrencyTransactionSchema, TransferParamsSchema, AgentIdentityRegistrationSchema, PlatformLinkSchema, ContractTermsSchema, ProposeContractRequestSchema, AcceptContractRequestSchema, CompleteContractRequestSchema, validate, validatePrivateKey, validatePublicKey, validateAddress, validateKeyPair, safeParse, assert, type ValidatedKeyPair, type ValidatedSignatureProof, type ValidatedCurrencyTransaction, type ValidatedTransferParams, type ValidatedAgentIdentityRegistration, type ValidatedPlatformLink, type ValidatedProposeContractRequest, type ValidatedAcceptContractRequest, type ValidatedCompleteContractRequest, } from './validation.js';
21
21
  export * from './errors.js';
22
22
  export * from './validation.js';
23
+ export { MetagraphClient } from './ottochain/metagraph-client.js';
24
+ export type { MetagraphClientConfig, Checkpoint, SubscribeOptions, FiberStateCallback, Unsubscribe } from './ottochain/metagraph-client.js';
@@ -21,3 +21,6 @@ export { TOKEN_DECIMALS } from './currency-types.js';
21
21
  export { createCurrencyTransaction, createCurrencyTransactionBatch, signCurrencyTransaction, verifyCurrencyTransaction, encodeCurrencyTransaction, hashCurrencyTransaction, getTransactionReference, isValidDagAddress, tokenToUnits, unitsToToken, } from './currency-transaction.js';
22
22
  export { CurrencyL1Client, DataL1Client, HttpClient, NetworkError } from './network/index.js';
23
23
  export type { NetworkConfig, RequestOptions, TransactionStatus, PendingTransaction, PostTransactionResponse, EstimateFeeResponse, PostDataResponse, } from './network/index.js';
24
+ export { createTransitionPayload, createArchivePayload, createInvokeScriptPayload, signTransaction, addTransactionSignature, getPublicKeyForRegistration, } from './transaction.js';
25
+ export { createStateMachinePayload, createScriptPayload, createDataTransactionRequest, } from './transaction.js';
26
+ export type { CreateStateMachineParams, CreateStateMachineMessage, CreateScriptParams, CreateScriptMessage, DataTransactionRequest, TransitionParams, TransitionStateMachineMessage, ArchiveParams, ArchiveStateMachineMessage, InvokeScriptParams, InvokeScriptMessage, } from './transaction.js';
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Transaction Helpers for Self-Signed Mode
3
+ *
4
+ * These helpers create properly formatted payloads for the bridge's
5
+ * self-signed mode, where clients sign their own transactions.
6
+ */
7
+ import type { Signed } from './types.js';
8
+ /**
9
+ * Parameters for creating a new state machine fiber
10
+ */
11
+ export interface CreateStateMachineParams {
12
+ fiberId: string;
13
+ definition: Record<string, unknown>;
14
+ initialData?: Record<string, unknown>;
15
+ parentFiberId?: string;
16
+ }
17
+ /**
18
+ * A CreateStateMachine message ready for signing
19
+ */
20
+ export interface CreateStateMachineMessage {
21
+ CreateStateMachine: {
22
+ fiberId: string;
23
+ definition: Record<string, unknown>;
24
+ initialData: Record<string, unknown>;
25
+ parentFiberId?: string;
26
+ };
27
+ }
28
+ /**
29
+ * Create a new state machine fiber payload.
30
+ *
31
+ * @param params - State machine creation parameters
32
+ * @returns A CreateStateMachine message ready for signing
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const create = createStateMachinePayload({
37
+ * fiberId: crypto.randomUUID(),
38
+ * definition: {
39
+ * states: { CREATED: { on: { activate: 'ACTIVE' } }, ACTIVE: {} },
40
+ * initialState: 'CREATED',
41
+ * },
42
+ * initialData: { owner: myAddress },
43
+ * });
44
+ * const signed = await signTransaction(create, privateKey);
45
+ * ```
46
+ */
47
+ export declare function createStateMachinePayload(params: CreateStateMachineParams): CreateStateMachineMessage;
48
+ /**
49
+ * Parameters for creating a transition payload
50
+ */
51
+ export interface TransitionParams {
52
+ fiberId: string;
53
+ eventName: string;
54
+ payload?: Record<string, unknown>;
55
+ targetSequenceNumber: number;
56
+ }
57
+ /**
58
+ * A TransitionStateMachine message ready for signing
59
+ */
60
+ export interface TransitionStateMachineMessage {
61
+ TransitionStateMachine: {
62
+ fiberId: string;
63
+ eventName: string;
64
+ payload: Record<string, unknown>;
65
+ targetSequenceNumber: number;
66
+ };
67
+ }
68
+ /**
69
+ * Create a transition payload ready for signing.
70
+ *
71
+ * This creates the exact message structure expected by the metagraph.
72
+ *
73
+ * @param params - Transition parameters
74
+ * @returns A TransitionStateMachine message ready for signing
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const transition = createTransitionPayload({
79
+ * fiberId: 'my-fiber-id',
80
+ * eventName: 'activate',
81
+ * payload: {},
82
+ * targetSequenceNumber: 0,
83
+ * });
84
+ * ```
85
+ */
86
+ export declare function createTransitionPayload(params: TransitionParams): TransitionStateMachineMessage;
87
+ /**
88
+ * Parameters for creating an archive payload
89
+ */
90
+ export interface ArchiveParams {
91
+ fiberId: string;
92
+ targetSequenceNumber: number;
93
+ }
94
+ /**
95
+ * An ArchiveStateMachine message ready for signing
96
+ */
97
+ export interface ArchiveStateMachineMessage {
98
+ ArchiveStateMachine: {
99
+ fiberId: string;
100
+ targetSequenceNumber: number;
101
+ };
102
+ }
103
+ /**
104
+ * Create an archive payload ready for signing.
105
+ *
106
+ * @param params - Archive parameters
107
+ * @returns An ArchiveStateMachine message ready for signing
108
+ */
109
+ export declare function createArchivePayload(params: ArchiveParams): ArchiveStateMachineMessage;
110
+ /**
111
+ * Parameters for creating a new script fiber
112
+ */
113
+ export interface CreateScriptParams {
114
+ fiberId: string;
115
+ scriptProgram: Record<string, unknown>;
116
+ initialState?: Record<string, unknown> | unknown[];
117
+ accessControl?: Record<string, unknown>;
118
+ }
119
+ /**
120
+ * A CreateScript message ready for signing
121
+ */
122
+ export interface CreateScriptMessage {
123
+ CreateScript: {
124
+ fiberId: string;
125
+ scriptProgram: Record<string, unknown>;
126
+ initialState: Record<string, unknown> | unknown[] | null;
127
+ accessControl: Record<string, unknown>;
128
+ };
129
+ }
130
+ /**
131
+ * Create a new script fiber payload.
132
+ *
133
+ * Note: `initialState` must be an object or array, NOT a primitive.
134
+ *
135
+ * @param params - Script creation parameters
136
+ * @returns A CreateScript message ready for signing
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * const script = createScriptPayload({
141
+ * fiberId: crypto.randomUUID(),
142
+ * scriptProgram: {
143
+ * methods: {
144
+ * increment: { "+": [{ var: "state.value" }, 1] },
145
+ * },
146
+ * },
147
+ * initialState: { value: 0 },
148
+ * accessControl: { type: 'open' },
149
+ * });
150
+ * const signed = await signTransaction(script, privateKey);
151
+ * ```
152
+ */
153
+ export declare function createScriptPayload(params: CreateScriptParams): CreateScriptMessage;
154
+ /**
155
+ * Parameters for creating an invoke script payload
156
+ */
157
+ export interface InvokeScriptParams {
158
+ fiberId: string;
159
+ method: string;
160
+ args?: Record<string, unknown>;
161
+ targetSequenceNumber: number;
162
+ }
163
+ /**
164
+ * An InvokeScript message ready for signing
165
+ */
166
+ export interface InvokeScriptMessage {
167
+ InvokeScript: {
168
+ fiberId: string;
169
+ method: string;
170
+ args: Record<string, unknown>;
171
+ targetSequenceNumber: number;
172
+ };
173
+ }
174
+ /**
175
+ * Create an invoke script payload ready for signing.
176
+ *
177
+ * @param params - Invoke script parameters
178
+ * @returns An InvokeScript message ready for signing
179
+ */
180
+ export declare function createInvokeScriptPayload(params: InvokeScriptParams): InvokeScriptMessage;
181
+ /**
182
+ * Sign a transaction payload for self-signed mode.
183
+ *
184
+ * This creates a Signed<T> object with the exact format expected by the bridge's
185
+ * `/agent/transition` endpoint when using self-signed mode.
186
+ *
187
+ * @param message - The message to sign (e.g., from createTransitionPayload)
188
+ * @param privateKey - The private key in hex format (64 characters)
189
+ * @returns A signed object ready for submission to the bridge
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * import { createTransitionPayload, signTransaction, generateKeyPair } from '@ottochain/sdk';
194
+ *
195
+ * const keyPair = generateKeyPair();
196
+ *
197
+ * // Create the transition message
198
+ * const transition = createTransitionPayload({
199
+ * fiberId: 'my-fiber-id',
200
+ * eventName: 'activate',
201
+ * payload: {},
202
+ * targetSequenceNumber: 0,
203
+ * });
204
+ *
205
+ * // Sign it
206
+ * const signedUpdate = await signTransaction(transition, keyPair.privateKey);
207
+ *
208
+ * // Submit to bridge
209
+ * await fetch('https://bridge/agent/transition', {
210
+ * method: 'POST',
211
+ * body: JSON.stringify({
212
+ * fiberId: 'my-fiber-id',
213
+ * signedUpdate,
214
+ * }),
215
+ * });
216
+ * ```
217
+ */
218
+ export declare function signTransaction<T>(message: T, privateKey: string): Promise<Signed<T>>;
219
+ /**
220
+ * A DataTransactionRequest ready for submission to the DL1 `/data` endpoint.
221
+ */
222
+ export interface DataTransactionRequest<T> {
223
+ data: Signed<T>;
224
+ fee: null;
225
+ }
226
+ /**
227
+ * Wrap a signed transaction in the DataTransactionRequest format
228
+ * expected by tessellation's DL1 `/data` endpoint.
229
+ *
230
+ * @param signed - A signed transaction from signTransaction()
231
+ * @returns Payload ready for POST to DL1 `/data`
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * const transition = createTransitionPayload({ ... });
236
+ * const signed = await signTransaction(transition, privateKey);
237
+ * const payload = createDataTransactionRequest(signed);
238
+ *
239
+ * // Submit directly to DL1
240
+ * await fetch('http://dl1-node:9400/data', {
241
+ * method: 'POST',
242
+ * headers: { 'Content-Type': 'application/json' },
243
+ * body: JSON.stringify(payload),
244
+ * });
245
+ * ```
246
+ */
247
+ export declare function createDataTransactionRequest<T>(signed: Signed<T>): DataTransactionRequest<T>;
248
+ /**
249
+ * Add an additional signature to a signed transaction.
250
+ *
251
+ * Use this for multi-signature scenarios where multiple parties
252
+ * need to sign the same transaction.
253
+ *
254
+ * @param signed - The already-signed transaction
255
+ * @param privateKey - Additional signer's private key
256
+ * @returns Transaction with additional signature
257
+ */
258
+ export declare function addTransactionSignature<T>(signed: Signed<T>, privateKey: string): Promise<Signed<T>>;
259
+ /**
260
+ * Get the public key ID from a private key in the format expected by registration.
261
+ *
262
+ * The bridge's self-signed registration expects the public key as a 128-character
263
+ * hex string (without the 04 prefix).
264
+ *
265
+ * @param privateKey - Private key in hex format
266
+ * @returns Public key ID (128 chars, no prefix)
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * const keyPair = generateKeyPair();
271
+ * const publicKeyId = getPublicKeyForRegistration(keyPair.privateKey);
272
+ *
273
+ * await fetch('https://bridge/agent/register', {
274
+ * method: 'POST',
275
+ * body: JSON.stringify({
276
+ * signingMode: 'self',
277
+ * publicKey: publicKeyId,
278
+ * displayName: 'My Agent',
279
+ * }),
280
+ * });
281
+ * ```
282
+ */
283
+ export declare function getPublicKeyForRegistration(privateKey: string): string;
@@ -8,6 +8,7 @@
8
8
  * @see modules/data_l1/src/main/scala/xyz/kd5ujc/data_l1/DataL1CustomRoutes.scala
9
9
  * @packageDocumentation
10
10
  */
11
+ import type { Signed } from '../metakit/types.js';
11
12
  import type { OnChain, CalculatedState, StateMachineFiberRecord, ScriptFiberRecord, EventReceipt, OracleInvocation, FiberStatus } from './types.js';
12
13
  /**
13
14
  * Checkpoint response from the metagraph (ordinal + calculated state).
@@ -63,6 +64,8 @@ export interface MetagraphClientConfig {
63
64
  ml0Url: string;
64
65
  /** DL1 node base URL for data submission (e.g., 'http://localhost:9400') */
65
66
  dl1Url?: string;
67
+ /** Multiple DL1 node URLs for resilient data submission */
68
+ dl1Urls?: string[];
66
69
  /** Request timeout in milliseconds (default: 30000) */
67
70
  timeout?: number;
68
71
  }
@@ -92,6 +95,7 @@ export interface MetagraphClientConfig {
92
95
  export declare class MetagraphClient {
93
96
  private ml0;
94
97
  private dl1?;
98
+ private dl1Clients;
95
99
  constructor(config: MetagraphClientConfig);
96
100
  /**
97
101
  * Get the current on-chain state (directly from L0 context).
@@ -198,4 +202,28 @@ export declare class MetagraphClient {
198
202
  postData<T>(signedData: T): Promise<{
199
203
  hash: string;
200
204
  }>;
205
+ /**
206
+ * Submit a self-signed transaction directly to DL1 nodes.
207
+ *
208
+ * Wraps the signed payload in `{ data, fee: null }` format and submits
209
+ * to one of the configured DL1 nodes. Uses `Promise.any` when multiple
210
+ * DL1 URLs are configured for resilience.
211
+ *
212
+ * @param signed - A `Signed<T>` object from `signTransaction()`
213
+ * @returns Response containing the data hash
214
+ * @throws Error if no DL1 URLs are configured or all nodes fail
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * const metagraph = new MetagraphClient({
219
+ * ml0Url: 'http://localhost:9200',
220
+ * dl1Urls: ['http://node1:9400', 'http://node2:9400'],
221
+ * });
222
+ * const signed = await signTransaction(payload, privateKey);
223
+ * await metagraph.submitData(signed);
224
+ * ```
225
+ */
226
+ submitData<T>(signed: Signed<T>): Promise<{
227
+ hash: string;
228
+ }>;
201
229
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ottochain/sdk",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "TypeScript SDK for ottochain metagraph operations - signing, encoding, and network interactions",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",