schemos 0.1.1 → 0.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/{telescope.d.ts → adapters/telescope.d.ts} +3 -3
- package/dist/adapters/telescope.d.ts.map +1 -0
- package/dist/{telescope.js → adapters/telescope.js} +5 -6
- package/dist/adapters/telescope.js.map +1 -0
- package/dist/adapters/telescope.test.d.ts.map +1 -0
- package/dist/{telescope.test.js → adapters/telescope.test.js} +11 -11
- package/dist/adapters/telescope.test.js.map +1 -0
- package/dist/client.test-d.js +2 -2
- package/dist/client.test-d.js.map +1 -1
- package/dist/contract.bench-d.js +32 -10
- package/dist/contract.bench-d.js.map +1 -1
- package/dist/contract.d.ts +3 -5
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +18 -15
- package/dist/contract.js.map +1 -1
- package/dist/contract.test.js +49 -1
- package/dist/contract.test.js.map +1 -1
- package/dist/encoding/index.d.ts +2 -0
- package/dist/encoding/index.d.ts.map +1 -0
- package/dist/encoding/index.js +2 -0
- package/dist/encoding/index.js.map +1 -0
- package/dist/encoding/json.d.ts +58 -0
- package/dist/encoding/json.d.ts.map +1 -0
- package/dist/encoding/json.js +95 -0
- package/dist/encoding/json.js.map +1 -0
- package/dist/encoding/json.test.d.ts +2 -0
- package/dist/encoding/json.test.d.ts.map +1 -0
- package/dist/encoding/json.test.js +49 -0
- package/dist/encoding/json.test.js.map +1 -0
- package/dist/formats.d.ts +33 -0
- package/dist/formats.d.ts.map +1 -0
- package/dist/formats.js +38 -0
- package/dist/formats.js.map +1 -0
- package/dist/formats.test.d.ts +2 -0
- package/dist/formats.test.d.ts.map +1 -0
- package/dist/formats.test.js +124 -0
- package/dist/formats.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/msg-compat.test-d.d.ts +13 -0
- package/dist/msg-compat.test-d.d.ts.map +1 -0
- package/dist/msg-compat.test-d.js +68 -0
- package/dist/msg-compat.test-d.js.map +1 -0
- package/dist/msg.d.ts +96 -0
- package/dist/msg.d.ts.map +1 -0
- package/dist/msg.js +98 -0
- package/dist/msg.js.map +1 -0
- package/dist/msg.test-d.d.ts +2 -0
- package/dist/msg.test-d.d.ts.map +1 -0
- package/dist/msg.test-d.js +121 -0
- package/dist/msg.test-d.js.map +1 -0
- package/dist/msg.test.d.ts +2 -0
- package/dist/msg.test.d.ts.map +1 -0
- package/dist/msg.test.js +177 -0
- package/dist/msg.test.js.map +1 -0
- package/dist/schemas/cw20/index.d.ts +152 -1
- package/dist/schemas/cw20/index.d.ts.map +1 -1
- package/dist/schemas/cw20/index.js +3 -1
- package/dist/schemas/cw20/index.js.map +1 -1
- package/dist/schemas/cw20/instantiate.d.ts +155 -0
- package/dist/schemas/cw20/instantiate.d.ts.map +1 -0
- package/dist/schemas/cw20/instantiate.js +175 -0
- package/dist/schemas/cw20/instantiate.js.map +1 -0
- package/dist/schemas/cw721/index.d.ts +96 -1
- package/dist/schemas/cw721/index.d.ts.map +1 -1
- package/dist/schemas/cw721/index.js +3 -1
- package/dist/schemas/cw721/index.js.map +1 -1
- package/dist/schemas/cw721/instantiate.d.ts +99 -0
- package/dist/schemas/cw721/instantiate.d.ts.map +1 -0
- package/dist/schemas/cw721/instantiate.js +112 -0
- package/dist/schemas/cw721/instantiate.js.map +1 -0
- package/dist/schemas/schemas.test-d.js +55 -0
- package/dist/schemas/schemas.test-d.js.map +1 -1
- package/dist/wallet-compat.test-d.js +11 -11
- package/dist/wallet-compat.test-d.js.map +1 -1
- package/package.json +7 -17
- package/dist/telescope.d.ts.map +0 -1
- package/dist/telescope.js.map +0 -1
- package/dist/telescope.test.d.ts.map +0 -1
- package/dist/telescope.test.js.map +0 -1
- /package/dist/{telescope.test.d.ts → adapters/telescope.test.d.ts} +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-neutral encoding utilities for CosmWasm message fields.
|
|
3
|
+
*
|
|
4
|
+
* Base64 implementation adapted from ox (MIT, weth LLC)
|
|
5
|
+
* @see https://github.com/wevm/ox/blob/658ecc6/src/core/Base64.ts
|
|
6
|
+
*/
|
|
7
|
+
const textEncoder = /*#__PURE__*/ new TextEncoder();
|
|
8
|
+
const textDecoder = /*#__PURE__*/ new TextDecoder();
|
|
9
|
+
// Base64 lookup table (same approach as ox)
|
|
10
|
+
const integerToCharacter = /*#__PURE__*/ Object.fromEntries(Array.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/').map((c, i) => [i, c.charCodeAt(0)]));
|
|
11
|
+
function utf8Encode(str) {
|
|
12
|
+
return textEncoder.encode(str);
|
|
13
|
+
}
|
|
14
|
+
function utf8Decode(bytes) {
|
|
15
|
+
return textDecoder.decode(bytes);
|
|
16
|
+
}
|
|
17
|
+
function base64Encode(bytes) {
|
|
18
|
+
const encoded = new Uint8Array(Math.ceil(bytes.length / 3) * 4);
|
|
19
|
+
for (let i = 0, j = 0; j < bytes.length; i += 4, j += 3) {
|
|
20
|
+
const y = (bytes[j] << 16) + ((bytes[j + 1] ?? 0) << 8) + (bytes[j + 2] ?? 0);
|
|
21
|
+
encoded[i] = integerToCharacter[y >> 18];
|
|
22
|
+
encoded[i + 1] = integerToCharacter[(y >> 12) & 0x3f];
|
|
23
|
+
encoded[i + 2] = integerToCharacter[(y >> 6) & 0x3f];
|
|
24
|
+
encoded[i + 3] = integerToCharacter[y & 0x3f];
|
|
25
|
+
}
|
|
26
|
+
const remainder = bytes.length % 3;
|
|
27
|
+
const end = Math.floor(bytes.length / 3) * 4 + (remainder && remainder + 1);
|
|
28
|
+
let base64 = textDecoder.decode(new Uint8Array(encoded.buffer, 0, end));
|
|
29
|
+
if (remainder === 1)
|
|
30
|
+
base64 += '==';
|
|
31
|
+
if (remainder === 2)
|
|
32
|
+
base64 += '=';
|
|
33
|
+
return base64;
|
|
34
|
+
}
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Public API: Json namespace
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
export const Json = {
|
|
39
|
+
/**
|
|
40
|
+
* Encode a JSON-serializable object to UTF-8 bytes.
|
|
41
|
+
*
|
|
42
|
+
* Use for `MsgExecuteContract.msg` and `queryData` fields.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { Json } from 'schemos/encoding'
|
|
47
|
+
*
|
|
48
|
+
* const envelope = cw20Msg('transfer', { amount: '1000', recipient: 'osmo1...' })
|
|
49
|
+
* MsgExecuteContract.fromPartial({
|
|
50
|
+
* sender, contract,
|
|
51
|
+
* msg: Json.toBytes(envelope),
|
|
52
|
+
* funds: [],
|
|
53
|
+
* })
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
toBytes(value) {
|
|
57
|
+
return utf8Encode(JSON.stringify(value));
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* Encode a JSON-serializable object to a base64 string.
|
|
61
|
+
*
|
|
62
|
+
* Use for CosmWasm `Binary` fields (e.g. cw20 `send` msg hook).
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { Json } from 'schemos/encoding'
|
|
67
|
+
*
|
|
68
|
+
* cw20Msg('send', {
|
|
69
|
+
* amount: '1000',
|
|
70
|
+
* contract: 'osmo1...',
|
|
71
|
+
* msg: Json.toBase64({ some_hook: { action: 'swap' } }),
|
|
72
|
+
* })
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
toBase64(value) {
|
|
76
|
+
return base64Encode(utf8Encode(JSON.stringify(value)));
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Decode UTF-8 bytes to a JSON object.
|
|
80
|
+
*
|
|
81
|
+
* Use for decoding query responses from telescope RPC.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { Json } from 'schemos/encoding'
|
|
86
|
+
*
|
|
87
|
+
* const res = await rpc.cosmwasm.wasm.v1.smartContractState({ address, queryData })
|
|
88
|
+
* const result = Json.fromBytes(res.data)
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
fromBytes(bytes) {
|
|
92
|
+
return JSON.parse(utf8Decode(bytes));
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/encoding/json.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.test.d.ts","sourceRoot":"","sources":["../../src/encoding/json.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { Json } from './json.js';
|
|
3
|
+
describe('Json.toBytes', () => {
|
|
4
|
+
test('encodes object to JSON UTF-8 bytes', () => {
|
|
5
|
+
const bytes = Json.toBytes({ transfer: { amount: '1000' } });
|
|
6
|
+
expect(bytes).toBeInstanceOf(Uint8Array);
|
|
7
|
+
expect(JSON.parse(new TextDecoder().decode(bytes))).toEqual({
|
|
8
|
+
transfer: { amount: '1000' },
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
test('encodes empty object', () => {
|
|
12
|
+
const bytes = Json.toBytes({ token_info: {} });
|
|
13
|
+
expect(JSON.parse(new TextDecoder().decode(bytes))).toEqual({
|
|
14
|
+
token_info: {},
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('Json.toBase64', () => {
|
|
19
|
+
test('encodes object to base64 string', () => {
|
|
20
|
+
const b64 = Json.toBase64({ some_hook: { action: 'swap' } });
|
|
21
|
+
// Verify roundtrip via atob
|
|
22
|
+
expect(JSON.parse(atob(b64))).toEqual({ some_hook: { action: 'swap' } });
|
|
23
|
+
});
|
|
24
|
+
test('handles padding correctly', () => {
|
|
25
|
+
// Different object sizes produce different padding
|
|
26
|
+
const b64_1 = Json.toBase64({ a: 1 });
|
|
27
|
+
expect(b64_1).toMatch(/^[A-Za-z0-9+/]+=*$/);
|
|
28
|
+
const b64_2 = Json.toBase64({ ab: 12 });
|
|
29
|
+
expect(b64_2).toMatch(/^[A-Za-z0-9+/]+=*$/);
|
|
30
|
+
});
|
|
31
|
+
test('produces valid base64 for cw20 send msg pattern', () => {
|
|
32
|
+
const hookMsg = { execute_swap: { offer_asset: 'uosmo' } };
|
|
33
|
+
const b64 = Json.toBase64(hookMsg);
|
|
34
|
+
expect(JSON.parse(atob(b64))).toEqual(hookMsg);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('Json.fromBytes', () => {
|
|
38
|
+
test('decodes UTF-8 bytes to object', () => {
|
|
39
|
+
const original = { balance: '1000' };
|
|
40
|
+
const bytes = new TextEncoder().encode(JSON.stringify(original));
|
|
41
|
+
expect(Json.fromBytes(bytes)).toEqual(original);
|
|
42
|
+
});
|
|
43
|
+
test('roundtrips with Json.toBytes', () => {
|
|
44
|
+
const original = { transfer: { amount: '1000', recipient: 'osmo1abc' } };
|
|
45
|
+
const bytes = Json.toBytes(original);
|
|
46
|
+
expect(Json.fromBytes(bytes)).toEqual(original);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=json.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.test.js","sourceRoot":"","sources":["../../src/encoding/json.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Ajv format validators for CosmWasm-specific integer formats.
|
|
3
|
+
*
|
|
4
|
+
* The `cosmwasm-schema` Rust crate emits JSON Schemas with format annotations
|
|
5
|
+
* like `"format": "uint64"` on `type: "integer"` fields. Ajv validates these
|
|
6
|
+
* as strings by default; we register numeric validators instead.
|
|
7
|
+
*
|
|
8
|
+
* Formats covered: uint8, uint32, uint64
|
|
9
|
+
* (These are the only formats appearing in the bundled cw20/cw721 schemas.)
|
|
10
|
+
*/
|
|
11
|
+
export interface FormatDefinition {
|
|
12
|
+
type: 'number';
|
|
13
|
+
validate: (value: number) => boolean;
|
|
14
|
+
}
|
|
15
|
+
/** uint8: integer in [0, 255] */
|
|
16
|
+
export declare const uint8Format: FormatDefinition;
|
|
17
|
+
/** uint32: integer in [0, 4294967295] */
|
|
18
|
+
export declare const uint32Format: FormatDefinition;
|
|
19
|
+
/**
|
|
20
|
+
* uint64: integer in [0, 2^64 - 1].
|
|
21
|
+
*
|
|
22
|
+
* JavaScript numbers cannot represent the full uint64 range exactly (max safe
|
|
23
|
+
* integer is 2^53 - 1). We accept any non-negative safe integer here, which
|
|
24
|
+
* matches what JSON parsers can round-trip without loss. Values above
|
|
25
|
+
* Number.MAX_SAFE_INTEGER must be handled via BigInt at the application layer.
|
|
26
|
+
*/
|
|
27
|
+
export declare const uint64Format: FormatDefinition;
|
|
28
|
+
export declare const cosmwasmFormats: {
|
|
29
|
+
readonly uint8: FormatDefinition;
|
|
30
|
+
readonly uint32: FormatDefinition;
|
|
31
|
+
readonly uint64: FormatDefinition;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=formats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../src/formats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAA;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;CACrC;AAED,iCAAiC;AACjC,eAAO,MAAM,WAAW,EAAE,gBAGzB,CAAA;AAED,yCAAyC;AACzC,eAAO,MAAM,YAAY,EAAE,gBAG1B,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,gBAI1B,CAAA;AAED,eAAO,MAAM,eAAe;;;;CAIlB,CAAA"}
|
package/dist/formats.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Ajv format validators for CosmWasm-specific integer formats.
|
|
3
|
+
*
|
|
4
|
+
* The `cosmwasm-schema` Rust crate emits JSON Schemas with format annotations
|
|
5
|
+
* like `"format": "uint64"` on `type: "integer"` fields. Ajv validates these
|
|
6
|
+
* as strings by default; we register numeric validators instead.
|
|
7
|
+
*
|
|
8
|
+
* Formats covered: uint8, uint32, uint64
|
|
9
|
+
* (These are the only formats appearing in the bundled cw20/cw721 schemas.)
|
|
10
|
+
*/
|
|
11
|
+
/** uint8: integer in [0, 255] */
|
|
12
|
+
export const uint8Format = {
|
|
13
|
+
type: 'number',
|
|
14
|
+
validate: (v) => Number.isInteger(v) && v >= 0 && v <= 255,
|
|
15
|
+
};
|
|
16
|
+
/** uint32: integer in [0, 4294967295] */
|
|
17
|
+
export const uint32Format = {
|
|
18
|
+
type: 'number',
|
|
19
|
+
validate: (v) => Number.isInteger(v) && v >= 0 && v <= 4_294_967_295,
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* uint64: integer in [0, 2^64 - 1].
|
|
23
|
+
*
|
|
24
|
+
* JavaScript numbers cannot represent the full uint64 range exactly (max safe
|
|
25
|
+
* integer is 2^53 - 1). We accept any non-negative safe integer here, which
|
|
26
|
+
* matches what JSON parsers can round-trip without loss. Values above
|
|
27
|
+
* Number.MAX_SAFE_INTEGER must be handled via BigInt at the application layer.
|
|
28
|
+
*/
|
|
29
|
+
export const uint64Format = {
|
|
30
|
+
type: 'number',
|
|
31
|
+
validate: (v) => Number.isInteger(v) && v >= 0 && v <= Number.MAX_SAFE_INTEGER,
|
|
32
|
+
};
|
|
33
|
+
export const cosmwasmFormats = {
|
|
34
|
+
uint8: uint8Format,
|
|
35
|
+
uint32: uint32Format,
|
|
36
|
+
uint64: uint64Format,
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=formats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../src/formats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,iCAAiC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG;CACnE,CAAA;AAED,yCAAyC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa;CAC7E,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CACtB,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,gBAAgB;CAChE,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;CACZ,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.test.d.ts","sourceRoot":"","sources":["../src/formats.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { uint8Format, uint32Format, uint64Format } from './formats.js';
|
|
3
|
+
import { createMsgBuilder } from './msg.js';
|
|
4
|
+
import { cw20ExecuteSchema, cw20QuerySchema } from './schemas/cw20/index.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Unit tests for individual format validators
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
describe('uint8Format', () => {
|
|
9
|
+
const { validate } = uint8Format;
|
|
10
|
+
test('accepts 0 (minimum)', () => {
|
|
11
|
+
expect(validate(0)).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
test('accepts 255 (maximum)', () => {
|
|
14
|
+
expect(validate(255)).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
test('accepts mid-range value', () => {
|
|
17
|
+
expect(validate(128)).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
test('rejects -1 (negative)', () => {
|
|
20
|
+
expect(validate(-1)).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
test('rejects 256 (overflow)', () => {
|
|
23
|
+
expect(validate(256)).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
test('rejects non-integer float', () => {
|
|
26
|
+
expect(validate(1.5)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('uint32Format', () => {
|
|
30
|
+
const { validate } = uint32Format;
|
|
31
|
+
test('accepts 0 (minimum)', () => {
|
|
32
|
+
expect(validate(0)).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
test('accepts 4294967295 (maximum)', () => {
|
|
35
|
+
expect(validate(4_294_967_295)).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
test('accepts mid-range value', () => {
|
|
38
|
+
expect(validate(100_000)).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
test('rejects -1 (negative)', () => {
|
|
41
|
+
expect(validate(-1)).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
test('rejects 4294967296 (overflow)', () => {
|
|
44
|
+
expect(validate(4_294_967_296)).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
test('rejects non-integer float', () => {
|
|
47
|
+
expect(validate(3.14)).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('uint64Format', () => {
|
|
51
|
+
const { validate } = uint64Format;
|
|
52
|
+
test('accepts 0 (minimum)', () => {
|
|
53
|
+
expect(validate(0)).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
test('accepts Number.MAX_SAFE_INTEGER', () => {
|
|
56
|
+
expect(validate(Number.MAX_SAFE_INTEGER)).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
test('accepts typical block height', () => {
|
|
59
|
+
expect(validate(12_345_678)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
test('rejects -1 (negative)', () => {
|
|
62
|
+
expect(validate(-1)).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
test('rejects Number.MAX_SAFE_INTEGER + 1 (beyond safe range)', () => {
|
|
65
|
+
expect(validate(Number.MAX_SAFE_INTEGER + 1)).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
test('rejects non-integer float', () => {
|
|
68
|
+
expect(validate(1.1)).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Integration: format validation active in createMsgBuilder
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
describe('format validation integration', () => {
|
|
75
|
+
const cw20Msg = createMsgBuilder(cw20ExecuteSchema);
|
|
76
|
+
const cw20QueryMsg = createMsgBuilder(cw20QuerySchema);
|
|
77
|
+
test('valid uint64 at_height passes', () => {
|
|
78
|
+
const result = cw20Msg('increase_allowance', {
|
|
79
|
+
amount: '500',
|
|
80
|
+
spender: 'osmo1abc',
|
|
81
|
+
expires: { at_height: 100 },
|
|
82
|
+
});
|
|
83
|
+
expect(result).toEqual({
|
|
84
|
+
increase_allowance: {
|
|
85
|
+
amount: '500',
|
|
86
|
+
spender: 'osmo1abc',
|
|
87
|
+
expires: { at_height: 100 },
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
test('negative at_height fails (uint64 violation)', () => {
|
|
92
|
+
expect(() => cw20Msg('increase_allowance', {
|
|
93
|
+
amount: '500',
|
|
94
|
+
spender: 'osmo1abc',
|
|
95
|
+
expires: { at_height: -1 },
|
|
96
|
+
})).toThrow('Validation failed for "increase_allowance"');
|
|
97
|
+
});
|
|
98
|
+
test('float at_height fails (uint64 violation)', () => {
|
|
99
|
+
expect(() => cw20Msg('increase_allowance', {
|
|
100
|
+
amount: '500',
|
|
101
|
+
spender: 'osmo1abc',
|
|
102
|
+
expires: { at_height: 1.5 },
|
|
103
|
+
})).toThrow('Validation failed for "increase_allowance"');
|
|
104
|
+
});
|
|
105
|
+
test('valid uint32 limit in query passes', () => {
|
|
106
|
+
const result = cw20QueryMsg('all_accounts', { limit: 10 });
|
|
107
|
+
expect(result).toEqual({ all_accounts: { limit: 10 } });
|
|
108
|
+
});
|
|
109
|
+
test('null limit in query passes (nullable uint32)', () => {
|
|
110
|
+
const result = cw20QueryMsg('all_accounts', { limit: null });
|
|
111
|
+
expect(result).toEqual({ all_accounts: { limit: null } });
|
|
112
|
+
});
|
|
113
|
+
test('negative limit fails (uint32 violation)', () => {
|
|
114
|
+
expect(() => cw20QueryMsg('all_accounts', {
|
|
115
|
+
limit: -1,
|
|
116
|
+
})).toThrow('Validation failed for "all_accounts"');
|
|
117
|
+
});
|
|
118
|
+
test('float limit fails (uint32 violation)', () => {
|
|
119
|
+
expect(() => cw20QueryMsg('all_accounts', {
|
|
120
|
+
limit: 2.5,
|
|
121
|
+
})).toThrow('Validation failed for "all_accounts"');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=formats.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.test.js","sourceRoot":"","sources":["../src/formats.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export type { CosmWasmExecuteClient, CosmWasmQueryClient } from './client.js';
|
|
2
2
|
export type { TypedContract, TypedQueryContract } from './contract.js';
|
|
3
3
|
export { createTypedContract } from './contract.js';
|
|
4
|
+
export { Json } from './encoding/index.js';
|
|
5
|
+
export type { InferMsg, InferResponse, MessageArgs, MessageNames, MsgBuilder, MsgValidator, } from './msg.js';
|
|
6
|
+
export { createMsgBuilder, createMsgValidator } from './msg.js';
|
|
4
7
|
export type { Coin, StdFee } from './types.js';
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC7E,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC7E,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,YAAY,EACV,QAAQ,EACR,aAAa,EACb,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC/D,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAS1C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Level 2 (createMsgBuilder) output compatibility tests.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that the typed envelope from createMsgBuilder plugs directly
|
|
5
|
+
* into existing SDK APIs without needing a Level 3 adapter.
|
|
6
|
+
*
|
|
7
|
+
* Two integration patterns:
|
|
8
|
+
* 1. Convenience API (cosmjs, graz): envelope is the `msg` parameter as-is
|
|
9
|
+
* 2. Protobuf API (telescope, interchainjs): envelope goes through
|
|
10
|
+
* JSON.stringify → toUtf8 → MsgExecuteContract.fromPartial({ msg })
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=msg-compat.test-d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-compat.test-d.d.ts","sourceRoot":"","sources":["../src/msg-compat.test-d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Level 2 (createMsgBuilder) output compatibility tests.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that the typed envelope from createMsgBuilder plugs directly
|
|
5
|
+
* into existing SDK APIs without needing a Level 3 adapter.
|
|
6
|
+
*
|
|
7
|
+
* Two integration patterns:
|
|
8
|
+
* 1. Convenience API (cosmjs, graz): envelope is the `msg` parameter as-is
|
|
9
|
+
* 2. Protobuf API (telescope, interchainjs): envelope goes through
|
|
10
|
+
* JSON.stringify → toUtf8 → MsgExecuteContract.fromPartial({ msg })
|
|
11
|
+
*/
|
|
12
|
+
import { expectTypeOf, test } from 'vitest';
|
|
13
|
+
import { createMsgBuilder } from './msg.js';
|
|
14
|
+
import { cw20ExecuteSchema, cw20QuerySchema } from './schemas/cw20/index.js';
|
|
15
|
+
const cw20Msg = createMsgBuilder(cw20ExecuteSchema);
|
|
16
|
+
const cw20QueryMsg = createMsgBuilder(cw20QuerySchema);
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Pattern 1: Convenience APIs — envelope plugs in directly as `msg`
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// cosmjs: SigningCosmWasmClient.execute(sender, contract, msg: JsonObject, fee)
|
|
21
|
+
test('cosmjs: Level 2 output assignable to execute() msg parameter', () => {
|
|
22
|
+
const envelope = cw20Msg('transfer', {
|
|
23
|
+
amount: '1000',
|
|
24
|
+
recipient: 'osmo1abc',
|
|
25
|
+
});
|
|
26
|
+
expectTypeOf(envelope).toExtend();
|
|
27
|
+
});
|
|
28
|
+
// cosmjs: SigningCosmWasmClient.executeMultiple(sender, instructions, fee)
|
|
29
|
+
test('cosmjs: Level 2 output assignable to ExecuteInstruction.msg', () => {
|
|
30
|
+
const envelope = cw20Msg('burn', { amount: '500' });
|
|
31
|
+
expectTypeOf(envelope).toExtend();
|
|
32
|
+
});
|
|
33
|
+
// cosmjs: CosmWasmClient.queryContractSmart(address, query: JsonObject)
|
|
34
|
+
test('cosmjs: Level 2 output assignable to queryContractSmart() query parameter', () => {
|
|
35
|
+
const envelope = cw20QueryMsg('balance', { address: 'osmo1abc' });
|
|
36
|
+
expectTypeOf(envelope).toExtend();
|
|
37
|
+
});
|
|
38
|
+
// graz: executeContract({ msg: Message extends Record<string, unknown> })
|
|
39
|
+
test('graz: Level 2 output assignable to Record<string, unknown>', () => {
|
|
40
|
+
const envelope = cw20Msg('transfer', {
|
|
41
|
+
amount: '1000',
|
|
42
|
+
recipient: 'osmo1abc',
|
|
43
|
+
});
|
|
44
|
+
// graz's Message generic is constrained to Record<string, unknown>
|
|
45
|
+
expectTypeOf(envelope).toExtend();
|
|
46
|
+
});
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Pattern 2: Protobuf APIs — envelope goes into MsgExecuteContract.msg field
|
|
49
|
+
// after JSON.stringify → Uint8Array encoding (user handles this step)
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// interchainjs/telescope: MsgExecuteContract.msg is Uint8Array
|
|
52
|
+
test('telescope/interchainjs: Level 2 output is JSON-serializable for MsgExecuteContract.msg field', () => {
|
|
53
|
+
const envelope = cw20Msg('transfer', {
|
|
54
|
+
amount: '1000',
|
|
55
|
+
recipient: 'osmo1abc',
|
|
56
|
+
});
|
|
57
|
+
// The envelope is a plain object that can be JSON.stringify'd
|
|
58
|
+
// User does: toUtf8(JSON.stringify(envelope)) → Uint8Array → MsgExecuteContract.msg
|
|
59
|
+
const serialized = JSON.stringify(envelope);
|
|
60
|
+
expectTypeOf(serialized).toBeString();
|
|
61
|
+
expectTypeOf().toEqualTypeOf();
|
|
62
|
+
});
|
|
63
|
+
// interchainjs: signAndBroadcast expects Message<any>[] (= { typeUrl, value }[])
|
|
64
|
+
// User builds the full message using telescope codegen, Level 2 only provides the msg field
|
|
65
|
+
test('interchainjs: Message<any> is { typeUrl: string, value: any }', () => {
|
|
66
|
+
expectTypeOf().toEqualTypeOf();
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=msg-compat.test-d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-compat.test-d.js","sourceRoot":"","sources":["../src/msg-compat.test-d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAE5E,MAAM,OAAO,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAA;AACnD,MAAM,YAAY,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAA;AAEtD,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAE9E,gFAAgF;AAChF,IAAI,CAAC,8DAA8D,EAAE,GAAG,EAAE;IACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE;QACnC,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,UAAU;KACtB,CAAC,CAAA;IAEF,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAc,CAAA;AAC/C,CAAC,CAAC,CAAA;AAEF,2EAA2E;AAC3E,IAAI,CAAC,6DAA6D,EAAE,GAAG,EAAE;IACvE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAGnD,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAkB,CAAA;AACnD,CAAC,CAAC,CAAA;AAEF,wEAAwE;AACxE,IAAI,CAAC,2EAA2E,EAAE,GAAG,EAAE;IACrF,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAA;IAEjE,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAY,CAAA;AAC7C,CAAC,CAAC,CAAA;AAEF,0EAA0E;AAC1E,IAAI,CAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE;QACnC,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,UAAU;KACtB,CAAC,CAAA;IACF,mEAAmE;IACnE,YAAY,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAA2B,CAAA;AAC5D,CAAC,CAAC,CAAA;AAEF,8EAA8E;AAC9E,6EAA6E;AAC7E,sEAAsE;AACtE,8EAA8E;AAE9E,+DAA+D;AAC/D,IAAI,CAAC,8FAA8F,EAAE,GAAG,EAAE;IACxG,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE;QACnC,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,UAAU;KACtB,CAAC,CAAA;IAEF,8DAA8D;IAC9D,oFAAoF;IACpF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC3C,YAAY,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAA;IAIrC,YAAY,EAAY,CAAC,aAAa,EAAc,CAAA;AACtD,CAAC,CAAC,CAAA;AAEF,iFAAiF;AACjF,4FAA4F;AAC5F,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IAEzE,YAAY,EAAqB,CAAC,aAAa,EAG3C,CAAA;AACN,CAAC,CAAC,CAAA"}
|
package/dist/msg.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
|
2
|
+
/** Infer the TypeScript message type from a JSON Schema definition. */
|
|
3
|
+
export type InferMsg<TSchema extends JSONSchema> = FromSchema<TSchema>;
|
|
4
|
+
/** Extract all top-level message names from a union of single-key objects. */
|
|
5
|
+
export type MessageNames<T> = T extends Record<string, unknown> ? keyof T & string : never;
|
|
6
|
+
/** Extract the args type for a specific message name from a union. */
|
|
7
|
+
export type MessageArgs<T, K extends string> = T extends Record<K, infer V> ? V : never;
|
|
8
|
+
/** Infer a specific response type from a responses schema map. */
|
|
9
|
+
export type InferResponse<TResponses extends Record<string, JSONSchema>, K extends keyof TResponses & string> = FromSchema<TResponses[K]>;
|
|
10
|
+
/** Typed callable interface returned by createMsgBuilder. */
|
|
11
|
+
export type MsgBuilder<TMsg> = <K extends MessageNames<TMsg>>(msg: K, args: MessageArgs<TMsg, K>, options?: {
|
|
12
|
+
context?: string;
|
|
13
|
+
}) => {
|
|
14
|
+
[P in K]: MessageArgs<TMsg, K>;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Create a typed message builder from a JSON Schema.
|
|
18
|
+
*
|
|
19
|
+
* Returns a callable that builds validated `{ [msgName]: args }` envelopes.
|
|
20
|
+
* The schema is compiled once and cached — safe for batch usage.
|
|
21
|
+
*
|
|
22
|
+
* This follows the same pattern as `createTypedContract`: the schema type
|
|
23
|
+
* is resolved once at factory level, avoiding expensive repeated evaluation
|
|
24
|
+
* of `FromSchema` on complex schemas (12+ oneOf branches with $ref).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { createMsgBuilder } from 'schemos/msg'
|
|
29
|
+
* import { cw20 } from 'schemos/schemas'
|
|
30
|
+
*
|
|
31
|
+
* const cw20Msg = createMsgBuilder(cw20.execute)
|
|
32
|
+
* const msg = cw20Msg('transfer', { amount: '1000', recipient: 'osmo1...' })
|
|
33
|
+
* // msg is typed as { transfer: { amount: string; recipient: string } }
|
|
34
|
+
*
|
|
35
|
+
* // Batch usage — schema compiled once, reused across calls:
|
|
36
|
+
* const msgs = [
|
|
37
|
+
* cw20Msg('transfer', { amount: '100', recipient: addr1 }),
|
|
38
|
+
* cw20Msg('transfer', { amount: '200', recipient: addr2 }),
|
|
39
|
+
* ]
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function createMsgBuilder<const TSchema extends JSONSchema>(schema: TSchema): MsgBuilder<FromSchema<TSchema>>;
|
|
43
|
+
/** Typed callable interface returned by createMsgValidator. */
|
|
44
|
+
export type MsgValidator<TMsg> = (data: TMsg, options?: {
|
|
45
|
+
context?: string;
|
|
46
|
+
}) => TMsg;
|
|
47
|
+
/**
|
|
48
|
+
* Create a typed message validator from a JSON Schema.
|
|
49
|
+
*
|
|
50
|
+
* Returns a callable that validates data and returns it with the inferred
|
|
51
|
+
* type. The schema type is resolved once at factory level — same pattern
|
|
52
|
+
* as `createTypedContract` and `createMsgBuilder`.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* import { createMsgValidator } from 'schemos'
|
|
57
|
+
* import { cw20 } from 'schemos/schemas'
|
|
58
|
+
*
|
|
59
|
+
* const validateInit = createMsgValidator(cw20.instantiate)
|
|
60
|
+
* const msg = validateInit({
|
|
61
|
+
* name: 'Token', symbol: 'TKN', decimals: 6, initial_balances: []
|
|
62
|
+
* })
|
|
63
|
+
* // msg type is inferred from cw20.instantiate schema
|
|
64
|
+
*
|
|
65
|
+
* await client.instantiate(sender, codeId, msg, 'label', 'auto')
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function createMsgValidator<const TSchema extends JSONSchema>(schema: TSchema): MsgValidator<FromSchema<TSchema>>;
|
|
69
|
+
/**
|
|
70
|
+
* Validate data against a JSON Schema. Returns the data as-is if valid,
|
|
71
|
+
* throws a descriptive error if invalid.
|
|
72
|
+
*
|
|
73
|
+
* Reuses the same WeakMap-based validator cache as `buildMsg` — safe for
|
|
74
|
+
* repeated calls with the same schema reference.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { validateMsg } from 'schemos'
|
|
79
|
+
*
|
|
80
|
+
* const initMsg = validateMsg(cw20InstantiateSchema, {
|
|
81
|
+
* name: 'Token', symbol: 'TKN', decimals: 6, initial_balances: []
|
|
82
|
+
* })
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function validateMsg<T>(schema: JSONSchema, data: unknown, options?: {
|
|
86
|
+
context?: string;
|
|
87
|
+
}): T;
|
|
88
|
+
/**
|
|
89
|
+
* Build a validated message envelope. Used internally by createMsgBuilder
|
|
90
|
+
* and createTypedContract. Accepts loose types — prefer createMsgBuilder
|
|
91
|
+
* for type-safe usage.
|
|
92
|
+
*/
|
|
93
|
+
export declare function buildMsg(schema: JSONSchema, msg: string, args: unknown, options?: {
|
|
94
|
+
context?: string;
|
|
95
|
+
}): Record<string, unknown>;
|
|
96
|
+
//# sourceMappingURL=msg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg.d.ts","sourceRoot":"","sources":["../src/msg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAO/D,uEAAuE;AACvE,MAAM,MAAM,QAAQ,CAAC,OAAO,SAAS,UAAU,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;AAEtE,8EAA8E;AAC9E,MAAM,MAAM,YAAY,CAAC,CAAC,IACxB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAA;AAE9D,sEAAsE;AACtE,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IACzC,CAAC,SAAS,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE1C,kEAAkE;AAClE,MAAM,MAAM,aAAa,CACvB,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAC7C,CAAC,SAAS,MAAM,UAAU,GAAG,MAAM,IACjC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;AA8B7B,6DAA6D;AAC7D,MAAM,MAAM,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,YAAY,CAAC,IAAI,CAAC,EAC1D,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAC3B;KAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;CAAE,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,OAAO,SAAS,UAAU,EAC/D,MAAM,EAAE,OAAO,GACd,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAIjC;AAED,+DAA+D;AAC/D,MAAM,MAAM,YAAY,CAAC,IAAI,IAAI,CAC/B,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAC3B,IAAI,CAAA;AAET;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,OAAO,SAAS,UAAU,EACjE,MAAM,EAAE,OAAO,GACd,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;AAWpC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7B,CAAC,CAOH;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB"}
|