@latticexyz/protocol-parser 2.0.0-alpha.1.267 → 2.0.0-foundry-js-c7b0289b

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/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{hexToString as M,sliceHex as N}from"viem";import{assertExhaustive as R}from"@latticexyz/common/utils";import{arrayAbiTypeToStaticAbiType as K,staticAbiTypeToByteLength as O}from"@latticexyz/schema-type";import{getAddress as k,hexToBigInt as C,hexToBool as V}from"viem";import{assertExhaustive as U}from"@latticexyz/common/utils";import{staticAbiTypeToByteLength as j,staticAbiTypeToDefaultValue as z}from"@latticexyz/schema-type";import{MUDError as p}from"@latticexyz/common/errors";import{staticAbiTypeToByteLength as D}from"@latticexyz/schema-type";var u=class extends p{name="InvalidHexValueError";constructor(e){super(`Hex value "${e}" is an odd length (${e.length-2}). It must be an even length.`)}},T=class extends p{name="InvalidHexLengthForSchemaError";constructor(e){super(`Hex value "${e}" has length of ${e.length-2}, but expected length of 64 for a schema.`)}},x=class extends p{name="InvalidHexLengthForPackedCounterError";constructor(e){super(`Hex value "${e}" has length of ${e.length-2}, but expected length of 64 for a packed counter.`)}},f=class extends p{name="InvalidHexLengthForStaticFieldError";constructor(e,i){super(`Hex value "${i}" has length of ${i.length-2}, but expected length of ${D[e]*2} for ${e} type.`)}},g=class extends p{name="InvalidHexLengthForArrayFieldError";constructor(e,i){super(`Hex value "${i}" has length of ${i.length-2}, but expected a multiple of ${D[e]*2} for ${e}[] type.`)}},S=class extends p{name="SchemaStaticLengthMismatchError";constructor(e,i,s){super(`Schema "${e}" static data length (${i}) did not match the summed length of all static fields (${s}). Is \`staticAbiTypeToByteLength\` up to date with Solidity schema types?`)}},A=class extends p{name="PackedCounterLengthMismatchError";constructor(e,i,s){super(`PackedCounter "${e}" total bytes length (${i}) did not match the summed length of all field byte lengths (${s}).`)}};function d(t,e){if(e.length>3&&e.length%2!==0)throw new u(e);if((e.length-2)/2!==j[t])throw new f(t,e);switch(t){case"uint8":case"uint16":case"uint24":case"uint32":case"uint40":case"uint48":case"uint56":case"uint64":case"uint72":case"uint80":case"uint88":case"uint96":case"uint104":case"uint112":case"uint120":case"uint128":case"uint136":case"uint144":case"uint152":case"uint160":case"uint168":case"uint176":case"uint184":case"uint192":case"uint200":case"uint208":case"uint216":case"uint224":case"uint232":case"uint240":case"uint248":case"uint256":case"int8":case"int16":case"int24":case"int32":case"int40":case"int48":case"int56":case"int64":case"int72":case"int80":case"int88":case"int96":case"int104":case"int112":case"int120":case"int128":case"int136":case"int144":case"int152":case"int160":case"int168":case"int176":case"int184":case"int192":case"int200":case"int208":case"int216":case"int224":case"int232":case"int240":case"int248":case"int256":{let s=C(e,{signed:t.startsWith("int")}),a=typeof z[t];if(a==="number")return Number(s);if(a==="bigint")return s;throw new Error(`Unexpected default value type (${a}) for ABI type (${t})`)}case"bytes1":case"bytes2":case"bytes3":case"bytes4":case"bytes5":case"bytes6":case"bytes7":case"bytes8":case"bytes9":case"bytes10":case"bytes11":case"bytes12":case"bytes13":case"bytes14":case"bytes15":case"bytes16":case"bytes17":case"bytes18":case"bytes19":case"bytes20":case"bytes21":case"bytes22":case"bytes23":case"bytes24":case"bytes25":case"bytes26":case"bytes27":case"bytes28":case"bytes29":case"bytes30":case"bytes31":case"bytes32":return e;case"bool":return V(e);case"address":return k(e)}return U(t,`Unsupported static ABI type: ${t}`)}function v(t,e){if(t==="bytes")return e;if(t==="string")return M(e);if(e.length>3&&e.length%2!==0)throw new u(e);let i=(e.length-2)/2;switch(t){case"uint8[]":case"uint16[]":case"uint24[]":case"uint32[]":case"uint40[]":case"uint48[]":case"uint56[]":case"uint64[]":case"uint72[]":case"uint80[]":case"uint88[]":case"uint96[]":case"uint104[]":case"uint112[]":case"uint120[]":case"uint128[]":case"uint136[]":case"uint144[]":case"uint152[]":case"uint160[]":case"uint168[]":case"uint176[]":case"uint184[]":case"uint192[]":case"uint200[]":case"uint208[]":case"uint216[]":case"uint224[]":case"uint232[]":case"uint240[]":case"uint248[]":case"uint256[]":case"int8[]":case"int16[]":case"int24[]":case"int32[]":case"int40[]":case"int48[]":case"int56[]":case"int64[]":case"int72[]":case"int80[]":case"int88[]":case"int96[]":case"int104[]":case"int112[]":case"int120[]":case"int128[]":case"int136[]":case"int144[]":case"int152[]":case"int160[]":case"int168[]":case"int176[]":case"int184[]":case"int192[]":case"int200[]":case"int208[]":case"int216[]":case"int224[]":case"int232[]":case"int240[]":case"int248[]":case"int256[]":case"bytes1[]":case"bytes2[]":case"bytes3[]":case"bytes4[]":case"bytes5[]":case"bytes6[]":case"bytes7[]":case"bytes8[]":case"bytes9[]":case"bytes10[]":case"bytes11[]":case"bytes12[]":case"bytes13[]":case"bytes14[]":case"bytes15[]":case"bytes16[]":case"bytes17[]":case"bytes18[]":case"bytes19[]":case"bytes20[]":case"bytes21[]":case"bytes22[]":case"bytes23[]":case"bytes24[]":case"bytes25[]":case"bytes26[]":case"bytes27[]":case"bytes28[]":case"bytes29[]":case"bytes30[]":case"bytes31[]":case"bytes32[]":case"bool[]":case"address[]":{let s=K(t),a=O[s];if(i%a!==0)throw new g(s,e);return new Array(i/a).fill(void 0).map((n,c)=>{let r=N(e,c*a,(c+1)*a);return d(s,r)})}}return R(t,`Unsupported dynamic ABI type: ${t}`)}import{decodeAbiParameters as W}from"viem";function ge(t,e){return e.map((i,s)=>W([{type:t.staticFields[s]}],i)[0])}import{staticAbiTypeToByteLength as q}from"@latticexyz/schema-type";import{sliceHex as P}from"viem";import{sliceHex as F}from"viem";function $(t){if(t.length!==66)throw new x(t);let e=d("uint56",F(t,0,7)),i=v("uint40[]",F(t,7)),s=BigInt(i.reduce((a,o)=>a+o,0));if(s!==e)throw new A(t,e,s);return{totalByteLength:e,fieldByteLengths:i}}import{staticAbiTypeToByteLength as _}from"@latticexyz/schema-type";function B(t){return t.reduce((e,i)=>e+_[i],0)}function Me(t,e){let i=[],s=0;t.staticFields.forEach(n=>{let c=q[n],r=d(n,P(e,s,s+c));s+=c,i.push(r)});let a=B(t.staticFields),o=s;if(o!==a&&console.warn("Decoded static data length does not match schema's expected static data length. Data may get corrupted. Is `getStaticByteLength` outdated?",{expectedLength:a,actualLength:o,bytesOffset:s}),t.dynamicFields.length>0){let n=$(P(e,s,s+32));s+=32,t.dynamicFields.forEach((r,H)=>{let m=n.fieldByteLengths[H],y=v(r,P(e,s,s+m));s+=m,i.push(y)});let c=s-32-o;BigInt(c)!==n.totalByteLength&&console.warn("Decoded dynamic data length does not match data layout's expected data length. Data may get corrupted. Did the data layout change?",{expectedLength:n.totalByteLength,actualLength:c,bytesOffset:s})}return i}import{arrayAbiTypeToStaticAbiType as G,isArrayAbiType as J}from"@latticexyz/schema-type";import{encodePacked as w}from"viem";function h(t,e){if(J(t)&&Array.isArray(e)){let i=G(t);return w(e.map(()=>i),e)}return w([t],[e])}function Ge(t,e){let i=e.slice(0,t.staticFields.length),s=e.slice(t.staticFields.length),a=i.map((m,y)=>h(t.staticFields[y],m).replace(/^0x/,"")).join("");if(t.dynamicFields.length===0)return`0x${a}`;let o=s.map((m,y)=>h(t.dynamicFields[y],m).replace(/^0x/,"")),n=o.map(m=>m.length/2),c=n.reduce((m,y)=>m+BigInt(y),0n),r=o.join(""),H=`${h("uint56",c).replace(/^0x/,"")}${n.map(m=>h("uint40",m).replace(/^0x/,"")).join("")}`.padEnd(64,"0");return`0x${a}${H}${r}`}import{sliceHex as E}from"viem";import{schemaAbiTypes as I,staticAbiTypeToByteLength as Q}from"@latticexyz/schema-type";import{hexToNumber as l,sliceHex as b}from"viem";function L(t){if(t.length!==66)throw new T(t);let e=l(b(t,0,2)),i=l(b(t,2,3)),s=l(b(t,3,4)),a=[],o=[];for(let c=4;c<4+i;c++){let r=l(b(t,c,c+1));a.push(I[r])}for(let c=4+i;c<4+i+s;c++){let r=l(b(t,c,c+1));o.push(I[r])}let n=a.reduce((c,r)=>c+Q[r],0);if(n!==e)throw new S(t,e,n);return{staticFields:a,dynamicFields:o}}function nt(t){let e=L(E(t,0,32));return{keySchema:L(E(t,32,64)),valueSchema:e}}export{u as InvalidHexLengthError,g as InvalidHexLengthForArrayFieldError,x as InvalidHexLengthForPackedCounterError,T as InvalidHexLengthForSchemaError,f as InvalidHexLengthForStaticFieldError,A as PackedCounterLengthMismatchError,S as SchemaStaticLengthMismatchError,v as decodeDynamicField,ge as decodeKeyTuple,Me as decodeRecord,d as decodeStaticField,h as encodeField,Ge as encodeRecord,$ as hexToPackedCounter,nt as hexToTableSchema};
1
+ import{isDynamicAbiType as R}from"@latticexyz/schema-type";function we(e){let t=[],c=[];for(let i of e)R(i)?c.push(i):t.push(i);return{staticFields:t,dynamicFields:c}}import{hexToString as Q,sliceHex as X}from"viem";import{assertExhaustive as Y}from"@latticexyz/common/utils";import{arrayAbiTypeToStaticAbiType as Z,staticAbiTypeToByteLength as ee}from"@latticexyz/schema-type";import{getAddress as N,hexToBigInt as W,hexToBool as _}from"viem";import{assertExhaustive as q}from"@latticexyz/common/utils";import{staticAbiTypeToByteLength as G,staticAbiTypeToDefaultValue as J}from"@latticexyz/schema-type";import{MUDError as u}from"@latticexyz/common/errors";import{staticAbiTypeToByteLength as $}from"@latticexyz/schema-type";var l=class extends u{name="InvalidHexValueError";constructor(t){super(`Hex value "${t}" is an odd length (${t.length-2}). It must be an even length.`)}},S=class extends u{name="InvalidHexLengthForSchemaError";constructor(t){super(`Hex value "${t}" has length of ${t.length-2}, but expected length of 64 for a schema.`)}},g=class extends u{name="InvalidHexLengthForPackedCounterError";constructor(t){super(`Hex value "${t}" has length of ${t.length-2}, but expected length of 64 for a packed counter.`)}},A=class extends u{name="InvalidHexLengthForStaticFieldError";constructor(t,c){super(`Hex value "${c}" has length of ${c.length-2}, but expected length of ${$[t]*2} for ${t} type.`)}},v=class extends u{name="InvalidHexLengthForArrayFieldError";constructor(t,c){super(`Hex value "${c}" has length of ${c.length-2}, but expected a multiple of ${$[t]*2} for ${t}[] type.`)}},H=class extends u{name="SchemaStaticLengthMismatchError";constructor(t,c,i){super(`Schema "${t}" static data length (${c}) did not match the summed length of all static fields (${i}). Is \`staticAbiTypeToByteLength\` up to date with Solidity schema types?`)}},F=class extends u{name="PackedCounterLengthMismatchError";constructor(t,c,i){super(`PackedCounter "${t}" total bytes length (${c}) did not match the summed length of all field byte lengths (${i}).`)}};function y(e,t){if(t.length>3&&t.length%2!==0)throw new l(t);if((t.length-2)/2!==G[e])throw new A(e,t);switch(e){case"uint8":case"uint16":case"uint24":case"uint32":case"uint40":case"uint48":case"uint56":case"uint64":case"uint72":case"uint80":case"uint88":case"uint96":case"uint104":case"uint112":case"uint120":case"uint128":case"uint136":case"uint144":case"uint152":case"uint160":case"uint168":case"uint176":case"uint184":case"uint192":case"uint200":case"uint208":case"uint216":case"uint224":case"uint232":case"uint240":case"uint248":case"uint256":case"int8":case"int16":case"int24":case"int32":case"int40":case"int48":case"int56":case"int64":case"int72":case"int80":case"int88":case"int96":case"int104":case"int112":case"int120":case"int128":case"int136":case"int144":case"int152":case"int160":case"int168":case"int176":case"int184":case"int192":case"int200":case"int208":case"int216":case"int224":case"int232":case"int240":case"int248":case"int256":{let i=W(t,{signed:e.startsWith("int")}),a=typeof J[e];if(a==="number")return Number(i);if(a==="bigint")return i;throw new Error(`Unexpected default value type (${a}) for ABI type (${e})`)}case"bytes1":case"bytes2":case"bytes3":case"bytes4":case"bytes5":case"bytes6":case"bytes7":case"bytes8":case"bytes9":case"bytes10":case"bytes11":case"bytes12":case"bytes13":case"bytes14":case"bytes15":case"bytes16":case"bytes17":case"bytes18":case"bytes19":case"bytes20":case"bytes21":case"bytes22":case"bytes23":case"bytes24":case"bytes25":case"bytes26":case"bytes27":case"bytes28":case"bytes29":case"bytes30":case"bytes31":case"bytes32":return t;case"bool":return _(t);case"address":return N(t)}return q(e,`Unsupported static ABI type: ${e}`)}function f(e,t){if(e==="bytes")return t;if(e==="string")return Q(t);if(t.length>3&&t.length%2!==0)throw new l(t);let c=(t.length-2)/2;switch(e){case"uint8[]":case"uint16[]":case"uint24[]":case"uint32[]":case"uint40[]":case"uint48[]":case"uint56[]":case"uint64[]":case"uint72[]":case"uint80[]":case"uint88[]":case"uint96[]":case"uint104[]":case"uint112[]":case"uint120[]":case"uint128[]":case"uint136[]":case"uint144[]":case"uint152[]":case"uint160[]":case"uint168[]":case"uint176[]":case"uint184[]":case"uint192[]":case"uint200[]":case"uint208[]":case"uint216[]":case"uint224[]":case"uint232[]":case"uint240[]":case"uint248[]":case"uint256[]":case"int8[]":case"int16[]":case"int24[]":case"int32[]":case"int40[]":case"int48[]":case"int56[]":case"int64[]":case"int72[]":case"int80[]":case"int88[]":case"int96[]":case"int104[]":case"int112[]":case"int120[]":case"int128[]":case"int136[]":case"int144[]":case"int152[]":case"int160[]":case"int168[]":case"int176[]":case"int184[]":case"int192[]":case"int200[]":case"int208[]":case"int216[]":case"int224[]":case"int232[]":case"int240[]":case"int248[]":case"int256[]":case"bytes1[]":case"bytes2[]":case"bytes3[]":case"bytes4[]":case"bytes5[]":case"bytes6[]":case"bytes7[]":case"bytes8[]":case"bytes9[]":case"bytes10[]":case"bytes11[]":case"bytes12[]":case"bytes13[]":case"bytes14[]":case"bytes15[]":case"bytes16[]":case"bytes17[]":case"bytes18[]":case"bytes19[]":case"bytes20[]":case"bytes21[]":case"bytes22[]":case"bytes23[]":case"bytes24[]":case"bytes25[]":case"bytes26[]":case"bytes27[]":case"bytes28[]":case"bytes29[]":case"bytes30[]":case"bytes31[]":case"bytes32[]":case"bool[]":case"address[]":{let i=Z(e),a=ee[i];if(c%a!==0)throw new v(i,t);return new Array(c/a).fill(void 0).map((r,s)=>{let o=X(t,s*a,(s+1)*a);return y(i,o)})}}return Y(e,`Unsupported dynamic ABI type: ${e}`)}import{isDynamicAbiType as te}from"@latticexyz/schema-type";function rt(e,t){return te(e)?f(e,t):y(e,t)}import{decodeAbiParameters as ie}from"viem";function B(e,t){if(e.staticFields.length!==t.length)throw new Error(`key tuple length ${t.length} does not match key schema length ${e.staticFields.length}`);return t.map((c,i)=>ie([{type:e.staticFields[i]}],c)[0])}function dt(e,t){let c=B({staticFields:Object.values(e),dynamicFields:[]},t);return Object.fromEntries(Object.keys(e).map((i,a)=>[i,c[a]]))}import{staticAbiTypeToByteLength as ae,dynamicAbiTypeToDefaultValue as se}from"@latticexyz/schema-type";import{readHex as V}from"@latticexyz/common";function w(e){if(e.length!==66)throw new g(e);let t=y("uint56",V(e,32-7,32)),c=f("uint40[]",V(e,0,32-7)),i=Object.freeze([...c].reverse()),a=BigInt(i.reduce((n,r)=>n+r,0));if(a!==t)throw new F(e,t,a);return{totalByteLength:t,fieldByteLengths:i}}import{staticAbiTypeToByteLength as ce}from"@latticexyz/schema-type";function T(e){return e.reduce((t,c)=>t+ce[c],0)}import{readHex as D}from"@latticexyz/common";function j(e,t){let c=[],i=0;e.staticFields.forEach(r=>{let s=ae[r],o=y(r,D(t,i,i+s));i+=s,c.push(o)});let a=T(e.staticFields),n=i;if(n!==a&&console.warn("Decoded static data length does not match value schema's expected static data length. Data may get corrupted. Is `getStaticByteLength` outdated?",{expectedLength:a,actualLength:n,bytesOffset:i}),e.dynamicFields.length>0){let r=w(D(t,i,i+32));i+=32,e.dynamicFields.forEach((o,d)=>{let m=r.fieldByteLengths[d];if(m>0){let h=f(o,D(t,i,i+m));i+=m,c.push(h)}else c.push(se[o])});let s=i-32-n;BigInt(s)!==r.totalByteLength&&console.warn("Decoded dynamic data length does not match data layout's expected data length. Data may get corrupted. Did the data layout change?",{expectedLength:r.totalByteLength,actualLength:s,bytesOffset:i})}return c}import{isStaticAbiType as re,isDynamicAbiType as ne}from"@latticexyz/schema-type";function E(e,t){let c=Object.values(e).filter(re),i=Object.values(e).filter(ne),a=j({staticFields:c,dynamicFields:i},t);return Object.fromEntries(Object.keys(e).map((n,r)=>[n,a[r]]))}import{concatHex as oe}from"viem";import{isStaticAbiType as me}from"@latticexyz/schema-type";import{readHex as pe}from"@latticexyz/common";function zt(e,{staticData:t,encodedLengths:c,dynamicData:i}){return E(e,oe([pe(t,0,T(Object.values(e).filter(me))),c,i]))}import{arrayAbiTypeToStaticAbiType as ye,isArrayAbiType as de}from"@latticexyz/schema-type";import{encodePacked as I}from"viem";function p(e,t){if(de(e)&&Array.isArray(t)){let c=ye(e);return t.length===0?"0x":I(t.map(()=>c),t)}return I([e],[t])}import{isStaticAbiType as ue}from"@latticexyz/schema-type";import{encodeAbiParameters as he}from"viem";function O(e,t){return t.map((c,i)=>he([{type:e.staticFields[i]}],[c]))}function Xt(e,t){let c=Object.values(e).filter(ue);return O({staticFields:c,dynamicFields:[]},Object.values(t))}function ei(e,t){let c=t.slice(0,e.staticFields.length),i=t.slice(e.staticFields.length),a=c.map((m,h)=>p(e.staticFields[h],m).replace(/^0x/,"")).join("");if(e.dynamicFields.length===0)return`0x${a}`;let n=i.map((m,h)=>p(e.dynamicFields[h],m).replace(/^0x/,"")),r=n.map(m=>m.length/2).reverse(),s=r.reduce((m,h)=>m+BigInt(h),0n),o=n.join(""),d=`${r.map(m=>p("uint40",m).replace(/^0x/,"")).join("")}${p("uint56",s).replace(/^0x/,"")}`.padStart(64,"0");return`0x${a}${d}${o}`}import{concatHex as Se}from"viem";import{isStaticAbiType as xe,isDynamicAbiType as be}from"@latticexyz/schema-type";import{concatHex as k}from"viem";import{concatHex as le,padHex as fe,size as Te}from"viem";function K(e){let t=e.map(Te).reverse(),c=t.reduce((i,a)=>i+BigInt(a),0n);return fe(le([...t.map(i=>p("uint40",i)),p("uint56",c)]),{size:32,dir:"left"})}function z(e,t){let c=Object.entries(e),i=c.filter(([,o])=>xe(o)),a=c.filter(([,o])=>be(o)),n=i.map(([o,d])=>p(d,t[o])),r=a.map(([o,d])=>p(d,t[o])),s=K(r);return{staticData:k(n),encodedLengths:s,dynamicData:k(r)}}function xi(e,t){let{staticData:c,encodedLengths:i,dynamicData:a}=z(e,t);return Se([c,i,a])}function Si(e){return`0x${[e.staticFieldLengths.reduce((c,i)=>c+i,0).toString(16).padStart(4,"0"),e.staticFieldLengths.length.toString(16).padStart(2,"0"),e.numDynamicFields.toString(16).padStart(2,"0"),...e.staticFieldLengths.map(c=>c.toString(16).padStart(2,"0"))].join("").padEnd(64,"0")}`}import{schemaAbiTypes as C,staticAbiTypeToByteLength as ge}from"@latticexyz/schema-type";import{hexToNumber as x,sliceHex as b}from"viem";function L(e){if(e.length!==66)throw new S(e);let t=x(b(e,0,2)),c=x(b(e,2,3)),i=x(b(e,3,4)),a=[],n=[];for(let s=4;s<4+c;s++){let o=x(b(e,s,s+1));a.push(C[o])}for(let s=4+c;s<4+c+i;s++){let o=x(b(e,s,s+1));n.push(C[o])}let r=a.reduce((s,o)=>s+ge[o],0);if(r!==t)throw console.warn(`Schema "${e}" static data length (${t}) did not match the summed length of all static fields (${r}). Is \`staticAbiTypeToByteLength\` up to date with Solidity schema types?`),new H(e,t,r);return{staticFields:a,dynamicFields:n}}import{sliceHex as U}from"viem";function wi(e){let t=L(U(e,0,32));return{keySchema:L(U(e,32,64)),valueSchema:t}}import{isStaticAbiType as Ae}from"@latticexyz/schema-type";import{schemaAbiTypes as M}from"@latticexyz/schema-type";function P(e){let t=e.staticFields.map(i=>M.indexOf(i)),c=e.dynamicFields.map(i=>M.indexOf(i));return`0x${[T(e.staticFields).toString(16).padStart(4,"0"),e.staticFields.length.toString(16).padStart(2,"0"),e.dynamicFields.length.toString(16).padStart(2,"0"),...t.map(i=>i.toString(16).padStart(2,"0")),...c.map(i=>i.toString(16).padStart(2,"0"))].join("").padEnd(64,"0")}`}function zi(e){return P({staticFields:Object.values(e).filter(Ae),dynamicFields:[]})}function Ui(e,t){return t<e.staticFields.length?e.staticFields[t]:e.dynamicFields[t-e.staticFields.length]}import{isDynamicAbiType as ve,isStaticAbiType as He,staticAbiTypeToByteLength as Fe}from"@latticexyz/schema-type";function Ni(e){let t=Object.values(e).filter(He),c=Object.values(e).filter(ve),i=t.map(n=>Fe[n]);return`0x${[i.reduce((n,r)=>n+r,0).toString(16).padStart(4,"0"),t.length.toString(16).padStart(2,"0"),c.length.toString(16).padStart(2,"0"),...i.map(n=>n.toString(16).padStart(2,"0"))].join("").padEnd(64,"0")}`}import{isDynamicAbiType as Pe,isStaticAbiType as De}from"@latticexyz/schema-type";function Gi(e){return P({staticFields:Object.values(e).filter(De),dynamicFields:Object.values(e).filter(Pe)})}export{l as InvalidHexLengthError,v as InvalidHexLengthForArrayFieldError,g as InvalidHexLengthForPackedCounterError,S as InvalidHexLengthForSchemaError,A as InvalidHexLengthForStaticFieldError,F as PackedCounterLengthMismatchError,H as SchemaStaticLengthMismatchError,we as abiTypesToSchema,f as decodeDynamicField,rt as decodeField,dt as decodeKey,B as decodeKeyTuple,j as decodeRecord,y as decodeStaticField,E as decodeValue,zt as decodeValueArgs,p as encodeField,Xt as encodeKey,O as encodeKeyTuple,ei as encodeRecord,xi as encodeValue,z as encodeValueArgs,Si as fieldLayoutToHex,w as hexToPackedCounter,L as hexToSchema,wi as hexToTableSchema,zi as keySchemaToHex,Ui as schemaIndexToAbiType,P as schemaToHex,T as staticDataLength,Ni as valueSchemaToFieldLayoutHex,Gi as valueSchemaToHex};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/decodeDynamicField.ts","../src/decodeStaticField.ts","../src/errors.ts","../src/decodeKeyTuple.ts","../src/decodeRecord.ts","../src/hexToPackedCounter.ts","../src/staticDataLength.ts","../src/encodeField.ts","../src/encodeRecord.ts","../src/hexToTableSchema.ts","../src/hexToSchema.ts"],"sourcesContent":["import { Hex, hexToString, sliceHex } from \"viem\";\nimport { assertExhaustive } from \"@latticexyz/common/utils\";\nimport {\n DynamicAbiType,\n DynamicAbiTypeToPrimitiveType,\n arrayAbiTypeToStaticAbiType,\n staticAbiTypeToByteLength,\n} from \"@latticexyz/schema-type\";\nimport { decodeStaticField } from \"./decodeStaticField\";\nimport { InvalidHexLengthError, InvalidHexLengthForArrayFieldError } from \"./errors\";\n\n// TODO: require size/length for dynamic fields, because hex might be longer (sometimes we just move the length pointer of arrays without updating the value)\n// this means the error should probably change from \"invalid length\" to \"too short\", which viem has that we could reuse?\n\nexport function decodeDynamicField<\n TAbiType extends DynamicAbiType,\n TPrimitiveType extends DynamicAbiTypeToPrimitiveType<TAbiType>\n>(abiType: TAbiType, data: Hex): TPrimitiveType {\n if (abiType === \"bytes\") {\n return data as TPrimitiveType;\n }\n if (abiType === \"string\") {\n return hexToString(data) as TPrimitiveType;\n }\n\n if (data.length > 3 && data.length % 2 !== 0) {\n throw new InvalidHexLengthError(data);\n }\n\n const dataSize = (data.length - 2) / 2;\n\n switch (abiType) {\n case \"uint8[]\":\n case \"uint16[]\":\n case \"uint24[]\":\n case \"uint32[]\":\n case \"uint40[]\":\n case \"uint48[]\":\n case \"uint56[]\":\n case \"uint64[]\":\n case \"uint72[]\":\n case \"uint80[]\":\n case \"uint88[]\":\n case \"uint96[]\":\n case \"uint104[]\":\n case \"uint112[]\":\n case \"uint120[]\":\n case \"uint128[]\":\n case \"uint136[]\":\n case \"uint144[]\":\n case \"uint152[]\":\n case \"uint160[]\":\n case \"uint168[]\":\n case \"uint176[]\":\n case \"uint184[]\":\n case \"uint192[]\":\n case \"uint200[]\":\n case \"uint208[]\":\n case \"uint216[]\":\n case \"uint224[]\":\n case \"uint232[]\":\n case \"uint240[]\":\n case \"uint248[]\":\n case \"uint256[]\":\n case \"int8[]\":\n case \"int16[]\":\n case \"int24[]\":\n case \"int32[]\":\n case \"int40[]\":\n case \"int48[]\":\n case \"int56[]\":\n case \"int64[]\":\n case \"int72[]\":\n case \"int80[]\":\n case \"int88[]\":\n case \"int96[]\":\n case \"int104[]\":\n case \"int112[]\":\n case \"int120[]\":\n case \"int128[]\":\n case \"int136[]\":\n case \"int144[]\":\n case \"int152[]\":\n case \"int160[]\":\n case \"int168[]\":\n case \"int176[]\":\n case \"int184[]\":\n case \"int192[]\":\n case \"int200[]\":\n case \"int208[]\":\n case \"int216[]\":\n case \"int224[]\":\n case \"int232[]\":\n case \"int240[]\":\n case \"int248[]\":\n case \"int256[]\":\n case \"bytes1[]\":\n case \"bytes2[]\":\n case \"bytes3[]\":\n case \"bytes4[]\":\n case \"bytes5[]\":\n case \"bytes6[]\":\n case \"bytes7[]\":\n case \"bytes8[]\":\n case \"bytes9[]\":\n case \"bytes10[]\":\n case \"bytes11[]\":\n case \"bytes12[]\":\n case \"bytes13[]\":\n case \"bytes14[]\":\n case \"bytes15[]\":\n case \"bytes16[]\":\n case \"bytes17[]\":\n case \"bytes18[]\":\n case \"bytes19[]\":\n case \"bytes20[]\":\n case \"bytes21[]\":\n case \"bytes22[]\":\n case \"bytes23[]\":\n case \"bytes24[]\":\n case \"bytes25[]\":\n case \"bytes26[]\":\n case \"bytes27[]\":\n case \"bytes28[]\":\n case \"bytes29[]\":\n case \"bytes30[]\":\n case \"bytes31[]\":\n case \"bytes32[]\":\n case \"bool[]\":\n case \"address[]\": {\n const staticAbiType = arrayAbiTypeToStaticAbiType(abiType);\n const itemByteLength = staticAbiTypeToByteLength[staticAbiType];\n if (dataSize % itemByteLength !== 0) {\n throw new InvalidHexLengthForArrayFieldError(staticAbiType, data);\n }\n const items = new Array(dataSize / itemByteLength).fill(undefined).map((_, i) => {\n const itemData = sliceHex(data, i * itemByteLength, (i + 1) * itemByteLength);\n return decodeStaticField(staticAbiType, itemData);\n });\n return items as TPrimitiveType;\n }\n }\n\n return assertExhaustive(abiType, `Unsupported dynamic ABI type: ${abiType}`);\n}\n","import { Hex, getAddress, hexToBigInt, hexToBool } from \"viem\";\nimport { assertExhaustive } from \"@latticexyz/common/utils\";\nimport {\n StaticAbiType,\n StaticAbiTypeToPrimitiveType,\n staticAbiTypeToByteLength,\n staticAbiTypeToDefaultValue,\n} from \"@latticexyz/schema-type\";\nimport { InvalidHexLengthError, InvalidHexLengthForStaticFieldError } from \"./errors\";\n\nexport function decodeStaticField<\n TAbiType extends StaticAbiType,\n TPrimitiveType extends StaticAbiTypeToPrimitiveType<TAbiType>\n>(abiType: TAbiType, data: Hex): TPrimitiveType {\n if (data.length > 3 && data.length % 2 !== 0) {\n throw new InvalidHexLengthError(data);\n }\n\n const dataSize = (data.length - 2) / 2;\n if (dataSize !== staticAbiTypeToByteLength[abiType]) {\n throw new InvalidHexLengthForStaticFieldError(abiType, data);\n }\n\n switch (abiType) {\n case \"uint8\":\n case \"uint16\":\n case \"uint24\":\n case \"uint32\":\n case \"uint40\":\n case \"uint48\":\n case \"uint56\":\n case \"uint64\":\n case \"uint72\":\n case \"uint80\":\n case \"uint88\":\n case \"uint96\":\n case \"uint104\":\n case \"uint112\":\n case \"uint120\":\n case \"uint128\":\n case \"uint136\":\n case \"uint144\":\n case \"uint152\":\n case \"uint160\":\n case \"uint168\":\n case \"uint176\":\n case \"uint184\":\n case \"uint192\":\n case \"uint200\":\n case \"uint208\":\n case \"uint216\":\n case \"uint224\":\n case \"uint232\":\n case \"uint240\":\n case \"uint248\":\n case \"uint256\":\n case \"int8\":\n case \"int16\":\n case \"int24\":\n case \"int32\":\n case \"int40\":\n case \"int48\":\n case \"int56\":\n case \"int64\":\n case \"int72\":\n case \"int80\":\n case \"int88\":\n case \"int96\":\n case \"int104\":\n case \"int112\":\n case \"int120\":\n case \"int128\":\n case \"int136\":\n case \"int144\":\n case \"int152\":\n case \"int160\":\n case \"int168\":\n case \"int176\":\n case \"int184\":\n case \"int192\":\n case \"int200\":\n case \"int208\":\n case \"int216\":\n case \"int224\":\n case \"int232\":\n case \"int240\":\n case \"int248\":\n case \"int256\": {\n const value = hexToBigInt(data, { signed: abiType.startsWith(\"int\") });\n const defaultValueType = typeof staticAbiTypeToDefaultValue[abiType];\n if (defaultValueType === \"number\") {\n return Number(value) as TPrimitiveType;\n }\n if (defaultValueType === \"bigint\") {\n return value as TPrimitiveType;\n }\n throw new Error(`Unexpected default value type (${defaultValueType}) for ABI type (${abiType})`);\n }\n\n case \"bytes1\":\n case \"bytes2\":\n case \"bytes3\":\n case \"bytes4\":\n case \"bytes5\":\n case \"bytes6\":\n case \"bytes7\":\n case \"bytes8\":\n case \"bytes9\":\n case \"bytes10\":\n case \"bytes11\":\n case \"bytes12\":\n case \"bytes13\":\n case \"bytes14\":\n case \"bytes15\":\n case \"bytes16\":\n case \"bytes17\":\n case \"bytes18\":\n case \"bytes19\":\n case \"bytes20\":\n case \"bytes21\":\n case \"bytes22\":\n case \"bytes23\":\n case \"bytes24\":\n case \"bytes25\":\n case \"bytes26\":\n case \"bytes27\":\n case \"bytes28\":\n case \"bytes29\":\n case \"bytes30\":\n case \"bytes31\":\n case \"bytes32\": {\n return data as TPrimitiveType;\n }\n\n case \"bool\": {\n return hexToBool(data) as TPrimitiveType;\n }\n\n case \"address\": {\n return getAddress(data) as TPrimitiveType;\n }\n }\n\n return assertExhaustive(abiType, `Unsupported static ABI type: ${abiType}`);\n}\n","import { Hex } from \"viem\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { StaticAbiType, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\n\nexport class InvalidHexLengthError extends MUDError {\n override name = \"InvalidHexValueError\";\n constructor(value: Hex) {\n super(`Hex value \"${value}\" is an odd length (${value.length - 2}). It must be an even length.`);\n }\n}\n\nexport class InvalidHexLengthForSchemaError extends MUDError {\n override name = \"InvalidHexLengthForSchemaError\";\n constructor(value: Hex) {\n super(`Hex value \"${value}\" has length of ${value.length - 2}, but expected length of 64 for a schema.`);\n }\n}\n\nexport class InvalidHexLengthForPackedCounterError extends MUDError {\n override name = \"InvalidHexLengthForPackedCounterError\";\n constructor(value: Hex) {\n super(`Hex value \"${value}\" has length of ${value.length - 2}, but expected length of 64 for a packed counter.`);\n }\n}\n\nexport class InvalidHexLengthForStaticFieldError extends MUDError {\n override name = \"InvalidHexLengthForStaticFieldError\";\n constructor(abiType: StaticAbiType, value: Hex) {\n super(\n `Hex value \"${value}\" has length of ${value.length - 2}, but expected length of ${\n staticAbiTypeToByteLength[abiType] * 2\n } for ${abiType} type.`\n );\n }\n}\n\nexport class InvalidHexLengthForArrayFieldError extends MUDError {\n override name = \"InvalidHexLengthForArrayFieldError\";\n constructor(abiType: StaticAbiType, value: Hex) {\n super(\n `Hex value \"${value}\" has length of ${value.length - 2}, but expected a multiple of ${\n staticAbiTypeToByteLength[abiType] * 2\n } for ${abiType}[] type.`\n );\n }\n}\n\nexport class SchemaStaticLengthMismatchError extends MUDError {\n override name = \"SchemaStaticLengthMismatchError\";\n constructor(schemaData: Hex, definedLength: number, summedLength: number) {\n super(\n `Schema \"${schemaData}\" static data length (${definedLength}) did not match the summed length of all static fields (${summedLength}). Is \\`staticAbiTypeToByteLength\\` up to date with Solidity schema types?`\n );\n }\n}\n\nexport class PackedCounterLengthMismatchError extends MUDError {\n override name = \"PackedCounterLengthMismatchError\";\n constructor(packedCounterData: Hex, definedLength: bigint, summedLength: bigint) {\n super(\n `PackedCounter \"${packedCounterData}\" total bytes length (${definedLength}) did not match the summed length of all field byte lengths (${summedLength}).`\n );\n }\n}\n","import { Hex, decodeAbiParameters } from \"viem\";\nimport { StaticPrimitiveType } from \"@latticexyz/schema-type\";\nimport { Schema } from \"./common\";\n\n// key tuples are encoded in the same way as abi.encode, so we can decode them with viem\n\nexport function decodeKeyTuple(keySchema: Schema, keyTuple: readonly Hex[]): StaticPrimitiveType[] {\n return keyTuple.map(\n (key, index) => decodeAbiParameters([{ type: keySchema.staticFields[index] }], key)[0] as StaticPrimitiveType\n );\n}\n","import { StaticPrimitiveType, DynamicPrimitiveType, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\nimport { Hex, sliceHex } from \"viem\";\nimport { Schema } from \"./common\";\nimport { decodeDynamicField } from \"./decodeDynamicField\";\nimport { decodeStaticField } from \"./decodeStaticField\";\nimport { hexToPackedCounter } from \"./hexToPackedCounter\";\nimport { staticDataLength } from \"./staticDataLength\";\n\nexport function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] {\n const values: (StaticPrimitiveType | DynamicPrimitiveType)[] = [];\n\n let bytesOffset = 0;\n schema.staticFields.forEach((fieldType) => {\n const fieldByteLength = staticAbiTypeToByteLength[fieldType];\n const value = decodeStaticField(fieldType, sliceHex(data, bytesOffset, bytesOffset + fieldByteLength));\n bytesOffset += fieldByteLength;\n values.push(value);\n });\n\n // Warn user if static data length doesn't match the schema, because data corruption might be possible.\n const schemaStaticDataLength = staticDataLength(schema.staticFields);\n const actualStaticDataLength = bytesOffset;\n if (actualStaticDataLength !== schemaStaticDataLength) {\n console.warn(\n \"Decoded static data length does not match schema's expected static data length. Data may get corrupted. Is `getStaticByteLength` outdated?\",\n {\n expectedLength: schemaStaticDataLength,\n actualLength: actualStaticDataLength,\n bytesOffset,\n }\n );\n }\n\n if (schema.dynamicFields.length > 0) {\n const dataLayout = hexToPackedCounter(sliceHex(data, bytesOffset, bytesOffset + 32));\n bytesOffset += 32;\n\n schema.dynamicFields.forEach((fieldType, i) => {\n const dataLength = dataLayout.fieldByteLengths[i];\n const value = decodeDynamicField(fieldType, sliceHex(data, bytesOffset, bytesOffset + dataLength));\n bytesOffset += dataLength;\n values.push(value);\n });\n\n // Warn user if dynamic data length doesn't match the schema, because data corruption might be possible.\n const actualDynamicDataLength = bytesOffset - 32 - actualStaticDataLength;\n // TODO: refactor this so we don't break for bytes offsets >UINT40\n if (BigInt(actualDynamicDataLength) !== dataLayout.totalByteLength) {\n console.warn(\n \"Decoded dynamic data length does not match data layout's expected data length. Data may get corrupted. Did the data layout change?\",\n {\n expectedLength: dataLayout.totalByteLength,\n actualLength: actualDynamicDataLength,\n bytesOffset,\n }\n );\n }\n }\n\n return values;\n}\n","import { Hex, sliceHex } from \"viem\";\nimport { decodeStaticField } from \"./decodeStaticField\";\nimport { decodeDynamicField } from \"./decodeDynamicField\";\nimport { InvalidHexLengthForPackedCounterError, PackedCounterLengthMismatchError } from \"./errors\";\n\n// Keep this logic in sync with PackedCounter.sol\n\n// - First 7 bytes (uint56) are used for the total byte length of the dynamic data\n// - The next 5 byte (uint40) sections are used for the byte length of each field, in the same order as the schema's dynamic fields\n\n// We use byte lengths rather than item counts so that, on chain, we can slice without having to get the schema first (and thus the field lengths of each dynamic type)\n\nexport function hexToPackedCounter(data: Hex): {\n totalByteLength: bigint;\n fieldByteLengths: readonly number[];\n} {\n if (data.length !== 66) {\n throw new InvalidHexLengthForPackedCounterError(data);\n }\n const totalByteLength = decodeStaticField(\"uint56\", sliceHex(data, 0, 7));\n\n // TODO: use schema to make sure we only parse as many as we need (rather than zeroes at the end)?\n const fieldByteLengths = decodeDynamicField(\"uint40[]\", sliceHex(data, 7));\n\n const summedLength = BigInt(fieldByteLengths.reduce((total, length) => total + length, 0));\n if (summedLength !== totalByteLength) {\n throw new PackedCounterLengthMismatchError(data, totalByteLength, summedLength);\n }\n\n return { totalByteLength, fieldByteLengths };\n}\n","import { StaticAbiType, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\n\nexport function staticDataLength(staticFields: readonly StaticAbiType[]): number {\n return staticFields.reduce((length, fieldType) => length + staticAbiTypeToByteLength[fieldType], 0);\n}\n","import { SchemaAbiType, arrayAbiTypeToStaticAbiType, isArrayAbiType } from \"@latticexyz/schema-type\";\nimport { AbiParameterToPrimitiveType } from \"abitype\";\nimport { Hex, encodePacked } from \"viem\";\n\nexport function encodeField<TSchemaAbiType extends SchemaAbiType>(\n fieldType: TSchemaAbiType,\n value: AbiParameterToPrimitiveType<{ type: TSchemaAbiType }>\n): Hex {\n if (isArrayAbiType(fieldType) && Array.isArray(value)) {\n const staticFieldType = arrayAbiTypeToStaticAbiType(fieldType);\n return encodePacked(\n value.map(() => staticFieldType),\n value\n );\n }\n return encodePacked([fieldType], [value]);\n}\n","import { StaticPrimitiveType, DynamicPrimitiveType } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { encodeField } from \"./encodeField\";\nimport { Schema } from \"./common\";\n\nexport function encodeRecord(schema: Schema, values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[]): Hex {\n const staticValues = values.slice(0, schema.staticFields.length) as readonly StaticPrimitiveType[];\n const dynamicValues = values.slice(schema.staticFields.length) as readonly DynamicPrimitiveType[];\n\n const staticData = staticValues\n .map((value, i) => encodeField(schema.staticFields[i], value).replace(/^0x/, \"\"))\n .join(\"\");\n\n if (schema.dynamicFields.length === 0) return `0x${staticData}`;\n\n const dynamicDataItems = dynamicValues.map((value, i) =>\n encodeField(schema.dynamicFields[i], value).replace(/^0x/, \"\")\n );\n\n const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2);\n const dynamicTotalByteLength = dynamicFieldByteLengths.reduce((total, length) => total + BigInt(length), 0n);\n\n const dynamicData = dynamicDataItems.join(\"\");\n\n const packedCounter = `${encodeField(\"uint56\", dynamicTotalByteLength).replace(/^0x/, \"\")}${dynamicFieldByteLengths\n .map((length) => encodeField(\"uint40\", length).replace(/^0x/, \"\"))\n .join(\"\")}`.padEnd(64, \"0\");\n\n return `0x${staticData}${packedCounter}${dynamicData}`;\n}\n","import { Hex, sliceHex } from \"viem\";\nimport { TableSchema } from \"./common\";\nimport { hexToSchema } from \"./hexToSchema\";\n\nexport function hexToTableSchema(data: Hex): TableSchema {\n const valueSchema = hexToSchema(sliceHex(data, 0, 32));\n const keySchema = hexToSchema(sliceHex(data, 32, 64));\n return {\n keySchema,\n valueSchema,\n };\n}\n","import { StaticAbiType, DynamicAbiType, schemaAbiTypes, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\nimport { Hex, hexToNumber, sliceHex } from \"viem\";\nimport { Schema } from \"./common\";\nimport { InvalidHexLengthForSchemaError, SchemaStaticLengthMismatchError } from \"./errors\";\n\nexport function hexToSchema(data: Hex): Schema {\n if (data.length !== 66) {\n throw new InvalidHexLengthForSchemaError(data);\n }\n\n const staticDataLength = hexToNumber(sliceHex(data, 0, 2));\n const numStaticFields = hexToNumber(sliceHex(data, 2, 3));\n const numDynamicFields = hexToNumber(sliceHex(data, 3, 4));\n const staticFields: StaticAbiType[] = [];\n const dynamicFields: DynamicAbiType[] = [];\n\n for (let i = 4; i < 4 + numStaticFields; i++) {\n const schemaTypeIndex = hexToNumber(sliceHex(data, i, i + 1));\n staticFields.push(schemaAbiTypes[schemaTypeIndex] as StaticAbiType);\n }\n for (let i = 4 + numStaticFields; i < 4 + numStaticFields + numDynamicFields; i++) {\n const schemaTypeIndex = hexToNumber(sliceHex(data, i, i + 1));\n dynamicFields.push(schemaAbiTypes[schemaTypeIndex] as DynamicAbiType);\n }\n\n // validate static data length\n const actualStaticDataLength = staticFields.reduce((acc, fieldType) => acc + staticAbiTypeToByteLength[fieldType], 0);\n if (actualStaticDataLength !== staticDataLength) {\n throw new SchemaStaticLengthMismatchError(data, staticDataLength, actualStaticDataLength);\n }\n\n return { staticFields, dynamicFields };\n}\n"],"mappings":"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","names":["hexToString","sliceHex","assertExhaustive","arrayAbiTypeToStaticAbiType","staticAbiTypeToByteLength","getAddress","hexToBigInt","hexToBool","assertExhaustive","staticAbiTypeToByteLength","staticAbiTypeToDefaultValue","MUDError","staticAbiTypeToByteLength","InvalidHexLengthError","value","InvalidHexLengthForSchemaError","InvalidHexLengthForPackedCounterError","InvalidHexLengthForStaticFieldError","abiType","InvalidHexLengthForArrayFieldError","SchemaStaticLengthMismatchError","schemaData","definedLength","summedLength","PackedCounterLengthMismatchError","packedCounterData","decodeStaticField","abiType","data","InvalidHexLengthError","staticAbiTypeToByteLength","InvalidHexLengthForStaticFieldError","value","hexToBigInt","defaultValueType","staticAbiTypeToDefaultValue","hexToBool","getAddress","assertExhaustive","decodeDynamicField","abiType","data","hexToString","InvalidHexLengthError","dataSize","staticAbiType","arrayAbiTypeToStaticAbiType","itemByteLength","staticAbiTypeToByteLength","InvalidHexLengthForArrayFieldError","_","i","itemData","sliceHex","decodeStaticField","assertExhaustive","decodeAbiParameters","decodeKeyTuple","keySchema","keyTuple","key","index","staticAbiTypeToByteLength","sliceHex","sliceHex","hexToPackedCounter","data","InvalidHexLengthForPackedCounterError","totalByteLength","decodeStaticField","sliceHex","fieldByteLengths","decodeDynamicField","summedLength","total","length","PackedCounterLengthMismatchError","staticAbiTypeToByteLength","staticDataLength","staticFields","length","fieldType","decodeRecord","schema","data","values","bytesOffset","fieldType","fieldByteLength","staticAbiTypeToByteLength","value","decodeStaticField","sliceHex","schemaStaticDataLength","staticDataLength","actualStaticDataLength","dataLayout","hexToPackedCounter","i","dataLength","decodeDynamicField","actualDynamicDataLength","arrayAbiTypeToStaticAbiType","isArrayAbiType","encodePacked","encodeField","fieldType","value","staticFieldType","encodeRecord","schema","values","staticValues","dynamicValues","staticData","value","i","encodeField","dynamicDataItems","dynamicFieldByteLengths","dynamicTotalByteLength","total","length","dynamicData","packedCounter","sliceHex","schemaAbiTypes","staticAbiTypeToByteLength","hexToNumber","sliceHex","hexToSchema","data","InvalidHexLengthForSchemaError","staticDataLength","hexToNumber","sliceHex","numStaticFields","numDynamicFields","staticFields","dynamicFields","i","schemaTypeIndex","schemaAbiTypes","actualStaticDataLength","acc","fieldType","staticAbiTypeToByteLength","SchemaStaticLengthMismatchError","hexToTableSchema","data","valueSchema","hexToSchema","sliceHex"]}
1
+ {"version":3,"sources":["../src/abiTypesToSchema.ts","../src/decodeDynamicField.ts","../src/decodeStaticField.ts","../src/errors.ts","../src/decodeField.ts","../src/decodeKeyTuple.ts","../src/decodeKey.ts","../src/decodeRecord.ts","../src/hexToPackedCounter.ts","../src/staticDataLength.ts","../src/decodeValue.ts","../src/decodeValueArgs.ts","../src/encodeField.ts","../src/encodeKey.ts","../src/encodeKeyTuple.ts","../src/encodeRecord.ts","../src/encodeValue.ts","../src/encodeValueArgs.ts","../src/encodeLengths.ts","../src/fieldLayoutToHex.ts","../src/hexToSchema.ts","../src/hexToTableSchema.ts","../src/keySchemaToHex.ts","../src/schemaToHex.ts","../src/schemaIndexToAbiType.ts","../src/valueSchemaToFieldLayoutHex.ts","../src/valueSchemaToHex.ts"],"sourcesContent":["import { DynamicAbiType, SchemaAbiType, StaticAbiType, isDynamicAbiType } from \"@latticexyz/schema-type\";\nimport { Schema } from \"./common\";\n\nexport function abiTypesToSchema(abiTypes: SchemaAbiType[]): Schema {\n const staticFields: StaticAbiType[] = [];\n const dynamicFields: DynamicAbiType[] = [];\n for (const abiType of abiTypes) {\n if (isDynamicAbiType(abiType)) dynamicFields.push(abiType);\n else staticFields.push(abiType);\n }\n return { staticFields, dynamicFields };\n}\n","import { Hex, hexToString, sliceHex } from \"viem\";\nimport { assertExhaustive } from \"@latticexyz/common/utils\";\nimport {\n DynamicAbiType,\n DynamicAbiTypeToPrimitiveType,\n arrayAbiTypeToStaticAbiType,\n staticAbiTypeToByteLength,\n} from \"@latticexyz/schema-type\";\nimport { decodeStaticField } from \"./decodeStaticField\";\nimport { InvalidHexLengthError, InvalidHexLengthForArrayFieldError } from \"./errors\";\n\n// TODO: require size/length for dynamic fields, because hex might be longer (sometimes we just move the length pointer of arrays without updating the value)\n// this means the error should probably change from \"invalid length\" to \"too short\", which viem has that we could reuse?\n\nexport function decodeDynamicField<\n TAbiType extends DynamicAbiType,\n TPrimitiveType extends DynamicAbiTypeToPrimitiveType<TAbiType>\n>(abiType: TAbiType, data: Hex): TPrimitiveType {\n if (abiType === \"bytes\") {\n return data as TPrimitiveType;\n }\n if (abiType === \"string\") {\n return hexToString(data) as TPrimitiveType;\n }\n\n if (data.length > 3 && data.length % 2 !== 0) {\n throw new InvalidHexLengthError(data);\n }\n\n const dataSize = (data.length - 2) / 2;\n\n switch (abiType) {\n case \"uint8[]\":\n case \"uint16[]\":\n case \"uint24[]\":\n case \"uint32[]\":\n case \"uint40[]\":\n case \"uint48[]\":\n case \"uint56[]\":\n case \"uint64[]\":\n case \"uint72[]\":\n case \"uint80[]\":\n case \"uint88[]\":\n case \"uint96[]\":\n case \"uint104[]\":\n case \"uint112[]\":\n case \"uint120[]\":\n case \"uint128[]\":\n case \"uint136[]\":\n case \"uint144[]\":\n case \"uint152[]\":\n case \"uint160[]\":\n case \"uint168[]\":\n case \"uint176[]\":\n case \"uint184[]\":\n case \"uint192[]\":\n case \"uint200[]\":\n case \"uint208[]\":\n case \"uint216[]\":\n case \"uint224[]\":\n case \"uint232[]\":\n case \"uint240[]\":\n case \"uint248[]\":\n case \"uint256[]\":\n case \"int8[]\":\n case \"int16[]\":\n case \"int24[]\":\n case \"int32[]\":\n case \"int40[]\":\n case \"int48[]\":\n case \"int56[]\":\n case \"int64[]\":\n case \"int72[]\":\n case \"int80[]\":\n case \"int88[]\":\n case \"int96[]\":\n case \"int104[]\":\n case \"int112[]\":\n case \"int120[]\":\n case \"int128[]\":\n case \"int136[]\":\n case \"int144[]\":\n case \"int152[]\":\n case \"int160[]\":\n case \"int168[]\":\n case \"int176[]\":\n case \"int184[]\":\n case \"int192[]\":\n case \"int200[]\":\n case \"int208[]\":\n case \"int216[]\":\n case \"int224[]\":\n case \"int232[]\":\n case \"int240[]\":\n case \"int248[]\":\n case \"int256[]\":\n case \"bytes1[]\":\n case \"bytes2[]\":\n case \"bytes3[]\":\n case \"bytes4[]\":\n case \"bytes5[]\":\n case \"bytes6[]\":\n case \"bytes7[]\":\n case \"bytes8[]\":\n case \"bytes9[]\":\n case \"bytes10[]\":\n case \"bytes11[]\":\n case \"bytes12[]\":\n case \"bytes13[]\":\n case \"bytes14[]\":\n case \"bytes15[]\":\n case \"bytes16[]\":\n case \"bytes17[]\":\n case \"bytes18[]\":\n case \"bytes19[]\":\n case \"bytes20[]\":\n case \"bytes21[]\":\n case \"bytes22[]\":\n case \"bytes23[]\":\n case \"bytes24[]\":\n case \"bytes25[]\":\n case \"bytes26[]\":\n case \"bytes27[]\":\n case \"bytes28[]\":\n case \"bytes29[]\":\n case \"bytes30[]\":\n case \"bytes31[]\":\n case \"bytes32[]\":\n case \"bool[]\":\n case \"address[]\": {\n const staticAbiType = arrayAbiTypeToStaticAbiType(abiType);\n const itemByteLength = staticAbiTypeToByteLength[staticAbiType];\n if (dataSize % itemByteLength !== 0) {\n throw new InvalidHexLengthForArrayFieldError(staticAbiType, data);\n }\n const items = new Array(dataSize / itemByteLength).fill(undefined).map((_, i) => {\n const itemData = sliceHex(data, i * itemByteLength, (i + 1) * itemByteLength);\n return decodeStaticField(staticAbiType, itemData);\n });\n return items as TPrimitiveType;\n }\n }\n\n return assertExhaustive(abiType, `Unsupported dynamic ABI type: ${abiType}`);\n}\n","import { Hex, getAddress, hexToBigInt, hexToBool } from \"viem\";\nimport { assertExhaustive } from \"@latticexyz/common/utils\";\nimport {\n StaticAbiType,\n StaticAbiTypeToPrimitiveType,\n staticAbiTypeToByteLength,\n staticAbiTypeToDefaultValue,\n} from \"@latticexyz/schema-type\";\nimport { InvalidHexLengthError, InvalidHexLengthForStaticFieldError } from \"./errors\";\n\nexport function decodeStaticField<\n TAbiType extends StaticAbiType,\n TPrimitiveType extends StaticAbiTypeToPrimitiveType<TAbiType>\n>(abiType: TAbiType, data: Hex): TPrimitiveType {\n if (data.length > 3 && data.length % 2 !== 0) {\n throw new InvalidHexLengthError(data);\n }\n\n const dataSize = (data.length - 2) / 2;\n if (dataSize !== staticAbiTypeToByteLength[abiType]) {\n throw new InvalidHexLengthForStaticFieldError(abiType, data);\n }\n\n switch (abiType) {\n case \"uint8\":\n case \"uint16\":\n case \"uint24\":\n case \"uint32\":\n case \"uint40\":\n case \"uint48\":\n case \"uint56\":\n case \"uint64\":\n case \"uint72\":\n case \"uint80\":\n case \"uint88\":\n case \"uint96\":\n case \"uint104\":\n case \"uint112\":\n case \"uint120\":\n case \"uint128\":\n case \"uint136\":\n case \"uint144\":\n case \"uint152\":\n case \"uint160\":\n case \"uint168\":\n case \"uint176\":\n case \"uint184\":\n case \"uint192\":\n case \"uint200\":\n case \"uint208\":\n case \"uint216\":\n case \"uint224\":\n case \"uint232\":\n case \"uint240\":\n case \"uint248\":\n case \"uint256\":\n case \"int8\":\n case \"int16\":\n case \"int24\":\n case \"int32\":\n case \"int40\":\n case \"int48\":\n case \"int56\":\n case \"int64\":\n case \"int72\":\n case \"int80\":\n case \"int88\":\n case \"int96\":\n case \"int104\":\n case \"int112\":\n case \"int120\":\n case \"int128\":\n case \"int136\":\n case \"int144\":\n case \"int152\":\n case \"int160\":\n case \"int168\":\n case \"int176\":\n case \"int184\":\n case \"int192\":\n case \"int200\":\n case \"int208\":\n case \"int216\":\n case \"int224\":\n case \"int232\":\n case \"int240\":\n case \"int248\":\n case \"int256\": {\n const value = hexToBigInt(data, { signed: abiType.startsWith(\"int\") });\n const defaultValueType = typeof staticAbiTypeToDefaultValue[abiType];\n if (defaultValueType === \"number\") {\n return Number(value) as TPrimitiveType;\n }\n if (defaultValueType === \"bigint\") {\n return value as TPrimitiveType;\n }\n throw new Error(`Unexpected default value type (${defaultValueType}) for ABI type (${abiType})`);\n }\n\n case \"bytes1\":\n case \"bytes2\":\n case \"bytes3\":\n case \"bytes4\":\n case \"bytes5\":\n case \"bytes6\":\n case \"bytes7\":\n case \"bytes8\":\n case \"bytes9\":\n case \"bytes10\":\n case \"bytes11\":\n case \"bytes12\":\n case \"bytes13\":\n case \"bytes14\":\n case \"bytes15\":\n case \"bytes16\":\n case \"bytes17\":\n case \"bytes18\":\n case \"bytes19\":\n case \"bytes20\":\n case \"bytes21\":\n case \"bytes22\":\n case \"bytes23\":\n case \"bytes24\":\n case \"bytes25\":\n case \"bytes26\":\n case \"bytes27\":\n case \"bytes28\":\n case \"bytes29\":\n case \"bytes30\":\n case \"bytes31\":\n case \"bytes32\": {\n return data as TPrimitiveType;\n }\n\n case \"bool\": {\n return hexToBool(data) as TPrimitiveType;\n }\n\n case \"address\": {\n return getAddress(data) as TPrimitiveType;\n }\n }\n\n return assertExhaustive(abiType, `Unsupported static ABI type: ${abiType}`);\n}\n","import { Hex } from \"viem\";\nimport { MUDError } from \"@latticexyz/common/errors\";\nimport { StaticAbiType, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\n\nexport class InvalidHexLengthError extends MUDError {\n override name = \"InvalidHexValueError\";\n constructor(value: Hex) {\n super(`Hex value \"${value}\" is an odd length (${value.length - 2}). It must be an even length.`);\n }\n}\n\nexport class InvalidHexLengthForSchemaError extends MUDError {\n override name = \"InvalidHexLengthForSchemaError\";\n constructor(value: Hex) {\n super(`Hex value \"${value}\" has length of ${value.length - 2}, but expected length of 64 for a schema.`);\n }\n}\n\nexport class InvalidHexLengthForPackedCounterError extends MUDError {\n override name = \"InvalidHexLengthForPackedCounterError\";\n constructor(value: Hex) {\n super(`Hex value \"${value}\" has length of ${value.length - 2}, but expected length of 64 for a packed counter.`);\n }\n}\n\nexport class InvalidHexLengthForStaticFieldError extends MUDError {\n override name = \"InvalidHexLengthForStaticFieldError\";\n constructor(abiType: StaticAbiType, value: Hex) {\n super(\n `Hex value \"${value}\" has length of ${value.length - 2}, but expected length of ${\n staticAbiTypeToByteLength[abiType] * 2\n } for ${abiType} type.`\n );\n }\n}\n\nexport class InvalidHexLengthForArrayFieldError extends MUDError {\n override name = \"InvalidHexLengthForArrayFieldError\";\n constructor(abiType: StaticAbiType, value: Hex) {\n super(\n `Hex value \"${value}\" has length of ${value.length - 2}, but expected a multiple of ${\n staticAbiTypeToByteLength[abiType] * 2\n } for ${abiType}[] type.`\n );\n }\n}\n\nexport class SchemaStaticLengthMismatchError extends MUDError {\n override name = \"SchemaStaticLengthMismatchError\";\n constructor(schemaData: Hex, definedLength: number, summedLength: number) {\n super(\n `Schema \"${schemaData}\" static data length (${definedLength}) did not match the summed length of all static fields (${summedLength}). ` +\n `Is \\`staticAbiTypeToByteLength\\` up to date with Solidity schema types?`\n );\n }\n}\n\nexport class PackedCounterLengthMismatchError extends MUDError {\n override name = \"PackedCounterLengthMismatchError\";\n constructor(packedCounterData: Hex, definedLength: bigint, summedLength: bigint) {\n super(\n `PackedCounter \"${packedCounterData}\" total bytes length (${definedLength}) did not match the summed length of all field byte lengths (${summedLength}).`\n );\n }\n}\n","import { Hex } from \"viem\";\nimport { SchemaAbiType, SchemaAbiTypeToPrimitiveType, isDynamicAbiType } from \"@latticexyz/schema-type\";\nimport { decodeDynamicField } from \"./decodeDynamicField\";\nimport { decodeStaticField } from \"./decodeStaticField\";\n\nexport function decodeField<\n TAbiType extends SchemaAbiType,\n TPrimitiveType extends SchemaAbiTypeToPrimitiveType<TAbiType>\n>(abiType: TAbiType, data: Hex): TPrimitiveType {\n return (\n isDynamicAbiType(abiType) ? decodeDynamicField(abiType, data) : decodeStaticField(abiType, data)\n ) as TPrimitiveType;\n}\n","import { Hex, decodeAbiParameters } from \"viem\";\nimport { StaticPrimitiveType } from \"@latticexyz/schema-type\";\nimport { Schema } from \"./common\";\n\n// key tuples are encoded in the same way as abi.encode, so we can decode them with viem\n\n/** @deprecated use `decodeKey` instead */\nexport function decodeKeyTuple(keySchema: Schema, keyTuple: readonly Hex[]): StaticPrimitiveType[] {\n if (keySchema.staticFields.length !== keyTuple.length) {\n throw new Error(\n `key tuple length ${keyTuple.length} does not match key schema length ${keySchema.staticFields.length}`\n );\n }\n return keyTuple.map(\n (key, index) => decodeAbiParameters([{ type: keySchema.staticFields[index] }], key)[0] as StaticPrimitiveType\n );\n}\n","import { Hex } from \"viem\";\nimport { SchemaToPrimitives, KeySchema } from \"./common\";\nimport { decodeKeyTuple } from \"./decodeKeyTuple\";\n\nexport function decodeKey<TSchema extends KeySchema>(\n keySchema: TSchema,\n data: readonly Hex[]\n): SchemaToPrimitives<TSchema> {\n // TODO: refactor and move all decodeKeyTuple logic into this method so we can delete decodeKeyTuple\n const keyValues = decodeKeyTuple({ staticFields: Object.values(keySchema), dynamicFields: [] }, data);\n\n return Object.fromEntries(\n Object.keys(keySchema).map((name, i) => [name, keyValues[i]])\n ) as SchemaToPrimitives<TSchema>;\n}\n","import {\n StaticPrimitiveType,\n DynamicPrimitiveType,\n staticAbiTypeToByteLength,\n dynamicAbiTypeToDefaultValue,\n} from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { Schema } from \"./common\";\nimport { decodeDynamicField } from \"./decodeDynamicField\";\nimport { decodeStaticField } from \"./decodeStaticField\";\nimport { hexToPackedCounter } from \"./hexToPackedCounter\";\nimport { staticDataLength } from \"./staticDataLength\";\nimport { readHex } from \"@latticexyz/common\";\n\n/** @deprecated use `decodeValue` instead */\nexport function decodeRecord(valueSchema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] {\n const values: (StaticPrimitiveType | DynamicPrimitiveType)[] = [];\n\n let bytesOffset = 0;\n valueSchema.staticFields.forEach((fieldType) => {\n const fieldByteLength = staticAbiTypeToByteLength[fieldType];\n const value = decodeStaticField(fieldType, readHex(data, bytesOffset, bytesOffset + fieldByteLength));\n bytesOffset += fieldByteLength;\n values.push(value);\n });\n\n // Warn user if static data length doesn't match the value schema, because data corruption might be possible.\n const schemaStaticDataLength = staticDataLength(valueSchema.staticFields);\n const actualStaticDataLength = bytesOffset;\n if (actualStaticDataLength !== schemaStaticDataLength) {\n console.warn(\n \"Decoded static data length does not match value schema's expected static data length. Data may get corrupted. Is `getStaticByteLength` outdated?\",\n {\n expectedLength: schemaStaticDataLength,\n actualLength: actualStaticDataLength,\n bytesOffset,\n }\n );\n }\n\n if (valueSchema.dynamicFields.length > 0) {\n const dataLayout = hexToPackedCounter(readHex(data, bytesOffset, bytesOffset + 32));\n bytesOffset += 32;\n\n valueSchema.dynamicFields.forEach((fieldType, i) => {\n const dataLength = dataLayout.fieldByteLengths[i];\n if (dataLength > 0) {\n const value = decodeDynamicField(fieldType, readHex(data, bytesOffset, bytesOffset + dataLength));\n bytesOffset += dataLength;\n values.push(value);\n } else {\n values.push(dynamicAbiTypeToDefaultValue[fieldType]);\n }\n });\n\n // Warn user if dynamic data length doesn't match the dynamic data length, because data corruption might be possible.\n const actualDynamicDataLength = bytesOffset - 32 - actualStaticDataLength;\n // TODO: refactor this so we don't break for bytes offsets >UINT40\n if (BigInt(actualDynamicDataLength) !== dataLayout.totalByteLength) {\n console.warn(\n \"Decoded dynamic data length does not match data layout's expected data length. Data may get corrupted. Did the data layout change?\",\n {\n expectedLength: dataLayout.totalByteLength,\n actualLength: actualDynamicDataLength,\n bytesOffset,\n }\n );\n }\n }\n\n return values;\n}\n","import { Hex } from \"viem\";\nimport { decodeStaticField } from \"./decodeStaticField\";\nimport { decodeDynamicField } from \"./decodeDynamicField\";\nimport { InvalidHexLengthForPackedCounterError, PackedCounterLengthMismatchError } from \"./errors\";\nimport { readHex } from \"@latticexyz/common\";\n\n// Keep this logic in sync with PackedCounter.sol\n\n// - Last 7 bytes (uint56) are used for the total byte length of the dynamic data\n// - The next 5 byte (uint40) sections are used for the byte length of each field, indexed from right to left\n\n// We use byte lengths rather than item counts so that, on chain, we can slice without having to get the value schema first (and thus the field lengths of each dynamic type)\n\nexport function hexToPackedCounter(data: Hex): {\n totalByteLength: bigint;\n fieldByteLengths: readonly number[];\n} {\n if (data.length !== 66) {\n throw new InvalidHexLengthForPackedCounterError(data);\n }\n\n const totalByteLength = decodeStaticField(\"uint56\", readHex(data, 32 - 7, 32));\n // TODO: use value schema to make sure we only parse as many as we need (rather than zeroes at the end)?\n const reversedFieldByteLengths = decodeDynamicField(\"uint40[]\", readHex(data, 0, 32 - 7));\n // Reverse the lengths\n const fieldByteLengths = Object.freeze([...reversedFieldByteLengths].reverse());\n\n const summedLength = BigInt(fieldByteLengths.reduce((total, length) => total + length, 0));\n if (summedLength !== totalByteLength) {\n throw new PackedCounterLengthMismatchError(data, totalByteLength, summedLength);\n }\n\n return { totalByteLength, fieldByteLengths };\n}\n","import { StaticAbiType, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\n\nexport function staticDataLength(staticFields: readonly StaticAbiType[]): number {\n return staticFields.reduce((length, fieldType) => length + staticAbiTypeToByteLength[fieldType], 0);\n}\n","import { isStaticAbiType, isDynamicAbiType } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { SchemaToPrimitives, ValueSchema } from \"./common\";\nimport { decodeRecord } from \"./decodeRecord\";\n\nexport function decodeValue<TSchema extends ValueSchema>(valueSchema: TSchema, data: Hex): SchemaToPrimitives<TSchema> {\n const staticFields = Object.values(valueSchema).filter(isStaticAbiType);\n const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType);\n\n // TODO: refactor and move all decodeRecord logic into this method so we can delete decodeRecord\n const valueTuple = decodeRecord({ staticFields, dynamicFields }, data);\n\n return Object.fromEntries(\n Object.keys(valueSchema).map((name, i) => [name, valueTuple[i]])\n ) as SchemaToPrimitives<TSchema>;\n}\n","import { concatHex } from \"viem\";\nimport { isStaticAbiType } from \"@latticexyz/schema-type\";\nimport { SchemaToPrimitives, ValueArgs, ValueSchema } from \"./common\";\nimport { decodeValue } from \"./decodeValue\";\nimport { staticDataLength } from \"./staticDataLength\";\nimport { readHex } from \"@latticexyz/common\";\n\nexport function decodeValueArgs<TSchema extends ValueSchema>(\n valueSchema: TSchema,\n { staticData, encodedLengths, dynamicData }: ValueArgs\n): SchemaToPrimitives<TSchema> {\n return decodeValue(\n valueSchema,\n concatHex([\n readHex(staticData, 0, staticDataLength(Object.values(valueSchema).filter(isStaticAbiType))),\n encodedLengths,\n dynamicData,\n ])\n );\n}\n","import { SchemaAbiType, arrayAbiTypeToStaticAbiType, isArrayAbiType } from \"@latticexyz/schema-type\";\nimport { AbiParameterToPrimitiveType } from \"abitype\";\nimport { Hex, encodePacked } from \"viem\";\n\nexport function encodeField<TSchemaAbiType extends SchemaAbiType>(\n fieldType: TSchemaAbiType,\n value: AbiParameterToPrimitiveType<{ type: TSchemaAbiType }>\n): Hex {\n if (isArrayAbiType(fieldType) && Array.isArray(value)) {\n const staticFieldType = arrayAbiTypeToStaticAbiType(fieldType);\n // TODO: we can remove conditional once this is fixed: https://github.com/wagmi-dev/viem/pull/1147\n return value.length === 0\n ? \"0x\"\n : encodePacked(\n value.map(() => staticFieldType),\n value\n );\n }\n return encodePacked([fieldType], [value]);\n}\n","import { isStaticAbiType } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { SchemaToPrimitives, KeySchema } from \"./common\";\nimport { encodeKeyTuple } from \"./encodeKeyTuple\";\n\nexport function encodeKey<TSchema extends KeySchema>(keySchema: TSchema, key: SchemaToPrimitives<TSchema>): Hex[] {\n const staticFields = Object.values(keySchema).filter(isStaticAbiType);\n // TODO: refactor and move all encodeKeyTuple logic into this method so we can delete encodeKeyTuple\n return encodeKeyTuple({ staticFields, dynamicFields: [] }, Object.values(key));\n}\n","import { StaticPrimitiveType } from \"@latticexyz/schema-type\";\nimport { Hex, encodeAbiParameters } from \"viem\";\nimport { Schema } from \"./common\";\n\n/** @deprecated use `encodeKey` instead */\nexport function encodeKeyTuple(keySchema: Schema, keyTuple: StaticPrimitiveType[]): Hex[] {\n return keyTuple.map((key, index) => encodeAbiParameters([{ type: keySchema.staticFields[index] }], [key]));\n}\n","import { StaticPrimitiveType, DynamicPrimitiveType } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { encodeField } from \"./encodeField\";\nimport { Schema } from \"./common\";\n\n/** @deprecated use `encodeValue` instead */\nexport function encodeRecord(\n valueSchema: Schema,\n values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[]\n): Hex {\n const staticValues = values.slice(0, valueSchema.staticFields.length) as readonly StaticPrimitiveType[];\n const dynamicValues = values.slice(valueSchema.staticFields.length) as readonly DynamicPrimitiveType[];\n\n const staticData = staticValues\n .map((value, i) => encodeField(valueSchema.staticFields[i], value).replace(/^0x/, \"\"))\n .join(\"\");\n\n if (valueSchema.dynamicFields.length === 0) return `0x${staticData}`;\n\n const dynamicDataItems = dynamicValues.map((value, i) =>\n encodeField(valueSchema.dynamicFields[i], value).replace(/^0x/, \"\")\n );\n\n const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2).reverse();\n const dynamicTotalByteLength = dynamicFieldByteLengths.reduce((total, length) => total + BigInt(length), 0n);\n\n const dynamicData = dynamicDataItems.join(\"\");\n\n const packedCounter = `${dynamicFieldByteLengths\n .map((length) => encodeField(\"uint40\", length).replace(/^0x/, \"\"))\n .join(\"\")}${encodeField(\"uint56\", dynamicTotalByteLength).replace(/^0x/, \"\")}`.padStart(64, \"0\");\n\n return `0x${staticData}${packedCounter}${dynamicData}`;\n}\n","import { Hex, concatHex } from \"viem\";\nimport { SchemaToPrimitives, ValueSchema } from \"./common\";\nimport { encodeValueArgs } from \"./encodeValueArgs\";\n\nexport function encodeValue<TSchema extends ValueSchema>(\n valueSchema: TSchema,\n value: SchemaToPrimitives<TSchema>\n): Hex {\n const { staticData, encodedLengths, dynamicData } = encodeValueArgs(valueSchema, value);\n return concatHex([staticData, encodedLengths, dynamicData]);\n}\n","import {\n StaticPrimitiveType,\n DynamicPrimitiveType,\n isStaticAbiType,\n isDynamicAbiType,\n StaticAbiType,\n DynamicAbiType,\n} from \"@latticexyz/schema-type\";\nimport { concatHex } from \"viem\";\nimport { encodeField } from \"./encodeField\";\nimport { SchemaToPrimitives, ValueArgs, ValueSchema } from \"./common\";\nimport { encodeLengths } from \"./encodeLengths\";\n\nexport function encodeValueArgs<TSchema extends ValueSchema>(\n valueSchema: TSchema,\n value: SchemaToPrimitives<TSchema>\n): ValueArgs {\n const valueSchemaEntries = Object.entries(valueSchema);\n const staticFields = valueSchemaEntries.filter(([, type]) => isStaticAbiType(type)) as [string, StaticAbiType][];\n const dynamicFields = valueSchemaEntries.filter(([, type]) => isDynamicAbiType(type)) as [string, DynamicAbiType][];\n // TODO: validate <=5 dynamic fields\n // TODO: validate <=28 total fields\n\n const encodedStaticValues = staticFields.map(([name, type]) => encodeField(type, value[name] as StaticPrimitiveType));\n const encodedDynamicValues = dynamicFields.map(([name, type]) =>\n encodeField(type, value[name] as DynamicPrimitiveType)\n );\n\n const encodedLengths = encodeLengths(encodedDynamicValues);\n\n return {\n staticData: concatHex(encodedStaticValues),\n encodedLengths,\n dynamicData: concatHex(encodedDynamicValues),\n };\n}\n","import { Hex, concatHex, padHex, size } from \"viem\";\nimport { encodeField } from \"./encodeField\";\n\nexport function encodeLengths(values: Hex[]): Hex {\n const byteLengths = values.map(size).reverse();\n const totalByteLength = byteLengths.reduce((total, length) => total + BigInt(length), 0n);\n\n return padHex(\n concatHex([...byteLengths.map((length) => encodeField(\"uint40\", length)), encodeField(\"uint56\", totalByteLength)]),\n { size: 32, dir: \"left\" }\n );\n}\n","import { Hex } from \"viem\";\nimport { FieldLayout } from \"./common\";\n\n/** @deprecated use `valueSchemaToFieldLayoutHex` instead */\nexport function fieldLayoutToHex(fieldLayout: FieldLayout): Hex {\n const staticDataLength = fieldLayout.staticFieldLengths.reduce((totalLength, length) => totalLength + length, 0);\n return `0x${[\n staticDataLength.toString(16).padStart(4, \"0\"),\n fieldLayout.staticFieldLengths.length.toString(16).padStart(2, \"0\"),\n fieldLayout.numDynamicFields.toString(16).padStart(2, \"0\"),\n ...fieldLayout.staticFieldLengths.map((schemaType) => schemaType.toString(16).padStart(2, \"0\")),\n ]\n .join(\"\")\n .padEnd(64, \"0\")}`;\n}\n","import { StaticAbiType, DynamicAbiType, schemaAbiTypes, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\nimport { Hex, hexToNumber, sliceHex } from \"viem\";\nimport { Schema } from \"./common\";\nimport { InvalidHexLengthForSchemaError, SchemaStaticLengthMismatchError } from \"./errors\";\n\nexport function hexToSchema(data: Hex): Schema {\n if (data.length !== 66) {\n throw new InvalidHexLengthForSchemaError(data);\n }\n\n const staticDataLength = hexToNumber(sliceHex(data, 0, 2));\n const numStaticFields = hexToNumber(sliceHex(data, 2, 3));\n const numDynamicFields = hexToNumber(sliceHex(data, 3, 4));\n const staticFields: StaticAbiType[] = [];\n const dynamicFields: DynamicAbiType[] = [];\n\n for (let i = 4; i < 4 + numStaticFields; i++) {\n const schemaTypeIndex = hexToNumber(sliceHex(data, i, i + 1));\n staticFields.push(schemaAbiTypes[schemaTypeIndex] as StaticAbiType);\n }\n for (let i = 4 + numStaticFields; i < 4 + numStaticFields + numDynamicFields; i++) {\n const schemaTypeIndex = hexToNumber(sliceHex(data, i, i + 1));\n dynamicFields.push(schemaAbiTypes[schemaTypeIndex] as DynamicAbiType);\n }\n\n // validate static data length\n const actualStaticDataLength = staticFields.reduce((acc, fieldType) => acc + staticAbiTypeToByteLength[fieldType], 0);\n if (actualStaticDataLength !== staticDataLength) {\n console.warn(\n `Schema \"${data}\" static data length (${staticDataLength}) did not match the summed length of all static fields (${actualStaticDataLength}). ` +\n `Is \\`staticAbiTypeToByteLength\\` up to date with Solidity schema types?`\n );\n throw new SchemaStaticLengthMismatchError(data, staticDataLength, actualStaticDataLength);\n }\n\n return { staticFields, dynamicFields };\n}\n","import { Hex, sliceHex } from \"viem\";\nimport { TableSchema } from \"./common\";\nimport { hexToSchema } from \"./hexToSchema\";\n\nexport function hexToTableSchema(data: Hex): TableSchema {\n const valueSchema = hexToSchema(sliceHex(data, 0, 32));\n const keySchema = hexToSchema(sliceHex(data, 32, 64));\n return {\n keySchema,\n valueSchema,\n };\n}\n","import { isStaticAbiType } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { KeySchema } from \"./common\";\nimport { schemaToHex } from \"./schemaToHex\";\n\nexport function keySchemaToHex(keySchema: KeySchema): Hex {\n return schemaToHex({ staticFields: Object.values(keySchema).filter(isStaticAbiType), dynamicFields: [] });\n}\n","import { schemaAbiTypes } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { Schema } from \"./common\";\nimport { staticDataLength } from \"./staticDataLength\";\n\n/** @deprecated use `keySchemaToHex` or `valueSchemaToHex` instead */\nexport function schemaToHex(schema: Schema): Hex {\n const staticSchemaTypes = schema.staticFields.map((abiType) => schemaAbiTypes.indexOf(abiType));\n const dynamicSchemaTypes = schema.dynamicFields.map((abiType) => schemaAbiTypes.indexOf(abiType));\n return `0x${[\n staticDataLength(schema.staticFields).toString(16).padStart(4, \"0\"),\n schema.staticFields.length.toString(16).padStart(2, \"0\"),\n schema.dynamicFields.length.toString(16).padStart(2, \"0\"),\n ...staticSchemaTypes.map((schemaType) => schemaType.toString(16).padStart(2, \"0\")),\n ...dynamicSchemaTypes.map((schemaType) => schemaType.toString(16).padStart(2, \"0\")),\n ]\n .join(\"\")\n .padEnd(64, \"0\")}`;\n}\n","import { SchemaAbiType } from \"@latticexyz/schema-type\";\nimport { Schema } from \"./common\";\n\nexport function schemaIndexToAbiType(schema: Schema, schemaIndex: number): SchemaAbiType {\n if (schemaIndex < schema.staticFields.length) {\n return schema.staticFields[schemaIndex];\n }\n return schema.dynamicFields[schemaIndex - schema.staticFields.length];\n}\n","import { Hex } from \"viem\";\nimport { ValueSchema } from \"./common\";\nimport { isDynamicAbiType, isStaticAbiType, staticAbiTypeToByteLength } from \"@latticexyz/schema-type\";\n\n// TODO: add tests once we have corresponding tests for FieldLayout.sol (bytes32 -> FieldLayout and vice versa)\nexport function valueSchemaToFieldLayoutHex(valueSchema: ValueSchema): Hex {\n const staticFields = Object.values(valueSchema).filter(isStaticAbiType);\n const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType);\n\n const staticFieldLengths = staticFields.map((fieldType) => staticAbiTypeToByteLength[fieldType]);\n const staticDataLength = staticFieldLengths.reduce((dataLength, fieldLength) => dataLength + fieldLength, 0);\n\n return `0x${[\n staticDataLength.toString(16).padStart(4, \"0\"),\n staticFields.length.toString(16).padStart(2, \"0\"),\n dynamicFields.length.toString(16).padStart(2, \"0\"),\n ...staticFieldLengths.map((fieldLength) => fieldLength.toString(16).padStart(2, \"0\")),\n ]\n .join(\"\")\n .padEnd(64, \"0\")}`;\n}\n","import { isDynamicAbiType, isStaticAbiType } from \"@latticexyz/schema-type\";\nimport { Hex } from \"viem\";\nimport { ValueSchema } from \"./common\";\nimport { schemaToHex } from \"./schemaToHex\";\n\nexport function valueSchemaToHex(valueSchema: ValueSchema): Hex {\n return schemaToHex({\n staticFields: Object.values(valueSchema).filter(isStaticAbiType),\n dynamicFields: Object.values(valueSchema).filter(isDynamicAbiType),\n });\n}\n"],"mappings":"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","names":["isDynamicAbiType","abiTypesToSchema","abiTypes","staticFields","dynamicFields","abiType","hexToString","sliceHex","assertExhaustive","arrayAbiTypeToStaticAbiType","staticAbiTypeToByteLength","getAddress","hexToBigInt","hexToBool","assertExhaustive","staticAbiTypeToByteLength","staticAbiTypeToDefaultValue","MUDError","staticAbiTypeToByteLength","InvalidHexLengthError","value","InvalidHexLengthForSchemaError","InvalidHexLengthForPackedCounterError","InvalidHexLengthForStaticFieldError","abiType","InvalidHexLengthForArrayFieldError","SchemaStaticLengthMismatchError","schemaData","definedLength","summedLength","PackedCounterLengthMismatchError","packedCounterData","decodeStaticField","abiType","data","InvalidHexLengthError","staticAbiTypeToByteLength","InvalidHexLengthForStaticFieldError","value","hexToBigInt","defaultValueType","staticAbiTypeToDefaultValue","hexToBool","getAddress","assertExhaustive","decodeDynamicField","abiType","data","hexToString","InvalidHexLengthError","dataSize","staticAbiType","arrayAbiTypeToStaticAbiType","itemByteLength","staticAbiTypeToByteLength","InvalidHexLengthForArrayFieldError","_","i","itemData","sliceHex","decodeStaticField","assertExhaustive","isDynamicAbiType","decodeField","abiType","data","isDynamicAbiType","decodeDynamicField","decodeStaticField","decodeAbiParameters","decodeKeyTuple","keySchema","keyTuple","key","index","decodeKey","keySchema","data","keyValues","decodeKeyTuple","name","i","staticAbiTypeToByteLength","dynamicAbiTypeToDefaultValue","readHex","hexToPackedCounter","data","InvalidHexLengthForPackedCounterError","totalByteLength","decodeStaticField","reversedFieldByteLengths","decodeDynamicField","fieldByteLengths","summedLength","total","length","PackedCounterLengthMismatchError","staticAbiTypeToByteLength","staticDataLength","staticFields","length","fieldType","readHex","decodeRecord","valueSchema","data","values","bytesOffset","fieldType","fieldByteLength","staticAbiTypeToByteLength","value","decodeStaticField","schemaStaticDataLength","staticDataLength","actualStaticDataLength","dataLayout","hexToPackedCounter","i","dataLength","decodeDynamicField","dynamicAbiTypeToDefaultValue","actualDynamicDataLength","isStaticAbiType","isDynamicAbiType","decodeValue","valueSchema","data","staticFields","isStaticAbiType","dynamicFields","isDynamicAbiType","valueTuple","decodeRecord","name","i","concatHex","isStaticAbiType","readHex","decodeValueArgs","valueSchema","staticData","encodedLengths","dynamicData","decodeValue","concatHex","staticDataLength","isStaticAbiType","arrayAbiTypeToStaticAbiType","isArrayAbiType","encodePacked","encodeField","fieldType","value","staticFieldType","isStaticAbiType","encodeAbiParameters","encodeKeyTuple","keySchema","keyTuple","key","index","encodeKey","keySchema","key","staticFields","isStaticAbiType","encodeKeyTuple","encodeRecord","valueSchema","values","staticValues","dynamicValues","staticData","value","i","encodeField","dynamicDataItems","dynamicFieldByteLengths","dynamicTotalByteLength","total","length","dynamicData","packedCounter","concatHex","isStaticAbiType","isDynamicAbiType","concatHex","concatHex","padHex","size","encodeLengths","values","byteLengths","size","totalByteLength","total","length","padHex","concatHex","encodeField","encodeValueArgs","valueSchema","value","valueSchemaEntries","staticFields","type","isStaticAbiType","dynamicFields","isDynamicAbiType","encodedStaticValues","name","encodeField","encodedDynamicValues","encodedLengths","encodeLengths","concatHex","encodeValue","valueSchema","value","staticData","encodedLengths","dynamicData","encodeValueArgs","concatHex","fieldLayoutToHex","fieldLayout","totalLength","length","schemaType","schemaAbiTypes","staticAbiTypeToByteLength","hexToNumber","sliceHex","hexToSchema","data","InvalidHexLengthForSchemaError","staticDataLength","hexToNumber","sliceHex","numStaticFields","numDynamicFields","staticFields","dynamicFields","i","schemaTypeIndex","schemaAbiTypes","actualStaticDataLength","acc","fieldType","staticAbiTypeToByteLength","SchemaStaticLengthMismatchError","sliceHex","hexToTableSchema","data","valueSchema","hexToSchema","sliceHex","isStaticAbiType","schemaAbiTypes","schemaToHex","schema","staticSchemaTypes","abiType","schemaAbiTypes","dynamicSchemaTypes","staticDataLength","schemaType","keySchemaToHex","keySchema","schemaToHex","isStaticAbiType","schemaIndexToAbiType","schema","schemaIndex","isDynamicAbiType","isStaticAbiType","staticAbiTypeToByteLength","valueSchemaToFieldLayoutHex","valueSchema","staticFields","dynamicFields","staticFieldLengths","fieldType","dataLength","fieldLength","isDynamicAbiType","isStaticAbiType","valueSchemaToHex","valueSchema","schemaToHex","isStaticAbiType","isDynamicAbiType"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latticexyz/protocol-parser",
3
- "version": "2.0.0-alpha.1.267+8619d150",
3
+ "version": "2.0.0-foundry-js-c7b0289b",
4
4
  "description": "Parser utilities for the MUD protocol",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,20 +13,11 @@
13
13
  ".": "./dist/index.js"
14
14
  },
15
15
  "types": "src/index.ts",
16
- "scripts": {
17
- "build": "pnpm run build:js",
18
- "build:js": "tsup",
19
- "clean": "pnpm run clean:js",
20
- "clean:js": "rimraf dist",
21
- "dev": "tsup --watch",
22
- "lint": "eslint .",
23
- "test": "vitest typecheck --run && vitest --run"
24
- },
25
16
  "dependencies": {
26
- "@latticexyz/common": "2.0.0-alpha.1.267+8619d150",
27
- "@latticexyz/schema-type": "2.0.0-alpha.1.267+8619d150",
28
- "abitype": "0.8.7",
29
- "viem": "1.1.7"
17
+ "abitype": "0.9.8",
18
+ "viem": "1.14.0",
19
+ "@latticexyz/common": "2.0.0-foundry-js-c7b0289b",
20
+ "@latticexyz/schema-type": "2.0.0-foundry-js-c7b0289b"
30
21
  },
31
22
  "devDependencies": {
32
23
  "tsup": "^6.7.0",
@@ -35,5 +26,15 @@
35
26
  "publishConfig": {
36
27
  "access": "public"
37
28
  },
38
- "gitHead": "8619d1503c31aca32474d618a8a0eda650cb9d16"
39
- }
29
+ "gitHead": "914a1e0ae4a573d685841ca2ea921435057deb8f",
30
+ "scripts": {
31
+ "build": "pnpm run build:js",
32
+ "build:js": "tsup",
33
+ "clean": "pnpm run clean:js",
34
+ "clean:js": "rimraf dist",
35
+ "dev": "tsup --watch",
36
+ "lint": "eslint .",
37
+ "test": "vitest typecheck --run && vitest --run",
38
+ "test:ci": "pnpm run test"
39
+ }
40
+ }
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { abiTypesToSchema } from "./abiTypesToSchema";
3
+
4
+ describe("hexToSchema", () => {
5
+ it("converts hex to schema", () => {
6
+ expect(abiTypesToSchema(["bool"])).toMatchInlineSnapshot(`
7
+ {
8
+ "dynamicFields": [],
9
+ "staticFields": [
10
+ "bool",
11
+ ],
12
+ }
13
+ `);
14
+ expect(abiTypesToSchema(["bool", "bool[]"])).toMatchInlineSnapshot(`
15
+ {
16
+ "dynamicFields": [
17
+ "bool[]",
18
+ ],
19
+ "staticFields": [
20
+ "bool",
21
+ ],
22
+ }
23
+ `);
24
+ expect(abiTypesToSchema(["bytes32", "int32", "uint256[]", "address[]", "bytes", "string"])).toMatchInlineSnapshot(`
25
+ {
26
+ "dynamicFields": [
27
+ "uint256[]",
28
+ "address[]",
29
+ "bytes",
30
+ "string",
31
+ ],
32
+ "staticFields": [
33
+ "bytes32",
34
+ "int32",
35
+ ],
36
+ }
37
+ `);
38
+ });
39
+ });
@@ -0,0 +1,12 @@
1
+ import { DynamicAbiType, SchemaAbiType, StaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type";
2
+ import { Schema } from "./common";
3
+
4
+ export function abiTypesToSchema(abiTypes: SchemaAbiType[]): Schema {
5
+ const staticFields: StaticAbiType[] = [];
6
+ const dynamicFields: DynamicAbiType[] = [];
7
+ for (const abiType of abiTypes) {
8
+ if (isDynamicAbiType(abiType)) dynamicFields.push(abiType);
9
+ else staticFields.push(abiType);
10
+ }
11
+ return { staticFields, dynamicFields };
12
+ }
package/src/common.ts CHANGED
@@ -1,11 +1,47 @@
1
- import { DynamicAbiType, StaticAbiType } from "@latticexyz/schema-type";
1
+ import { DynamicAbiType, SchemaAbiType, SchemaAbiTypeToPrimitiveType, StaticAbiType } from "@latticexyz/schema-type";
2
+ import { Hex } from "viem";
2
3
 
4
+ /** @deprecated use `KeySchema` or `ValueSchema` instead */
3
5
  export type Schema = {
4
6
  readonly staticFields: readonly StaticAbiType[];
5
7
  readonly dynamicFields: readonly DynamicAbiType[];
6
8
  };
7
9
 
10
+ /** @deprecated use `KeySchema` and `ValueSchema` instead */
8
11
  export type TableSchema = {
9
12
  readonly keySchema: Schema; // TODO: refine to set dynamicFields to []
10
13
  readonly valueSchema: Schema;
11
14
  };
15
+
16
+ export type FieldLayout = {
17
+ readonly staticFieldLengths: readonly number[];
18
+ readonly numDynamicFields: number;
19
+ };
20
+
21
+ // TODO: helper to filter user types to StaticAbiType
22
+ export type UserTypes = Record<string, { internalType: SchemaAbiType }>;
23
+
24
+ export type KeySchema<userTypes extends UserTypes | undefined = undefined> = Record<
25
+ string,
26
+ userTypes extends UserTypes ? StaticAbiType | keyof userTypes : StaticAbiType
27
+ >;
28
+ export type ValueSchema<userTypes extends UserTypes | undefined = undefined> = Record<
29
+ string,
30
+ userTypes extends UserTypes ? SchemaAbiType | keyof userTypes : SchemaAbiType
31
+ >;
32
+
33
+ /** Map a table schema like `{ value: "uint256" }` to its primitive types like `{ value: bigint }` */
34
+ export type SchemaToPrimitives<TSchema extends ValueSchema> = {
35
+ [key in keyof TSchema]: SchemaAbiTypeToPrimitiveType<TSchema[key]>;
36
+ };
37
+
38
+ export type TableRecord<TKeySchema extends KeySchema = KeySchema, TValueSchema extends ValueSchema = ValueSchema> = {
39
+ key: SchemaToPrimitives<TKeySchema>;
40
+ value: SchemaToPrimitives<TValueSchema>;
41
+ };
42
+
43
+ export type ValueArgs = {
44
+ staticData: Hex;
45
+ encodedLengths: Hex;
46
+ dynamicData: Hex;
47
+ };
@@ -0,0 +1,13 @@
1
+ import { Hex } from "viem";
2
+ import { SchemaAbiType, SchemaAbiTypeToPrimitiveType, isDynamicAbiType } from "@latticexyz/schema-type";
3
+ import { decodeDynamicField } from "./decodeDynamicField";
4
+ import { decodeStaticField } from "./decodeStaticField";
5
+
6
+ export function decodeField<
7
+ TAbiType extends SchemaAbiType,
8
+ TPrimitiveType extends SchemaAbiTypeToPrimitiveType<TAbiType>
9
+ >(abiType: TAbiType, data: Hex): TPrimitiveType {
10
+ return (
11
+ isDynamicAbiType(abiType) ? decodeDynamicField(abiType, data) : decodeStaticField(abiType, data)
12
+ ) as TPrimitiveType;
13
+ }
@@ -0,0 +1,15 @@
1
+ import { Hex } from "viem";
2
+ import { SchemaToPrimitives, KeySchema } from "./common";
3
+ import { decodeKeyTuple } from "./decodeKeyTuple";
4
+
5
+ export function decodeKey<TSchema extends KeySchema>(
6
+ keySchema: TSchema,
7
+ data: readonly Hex[]
8
+ ): SchemaToPrimitives<TSchema> {
9
+ // TODO: refactor and move all decodeKeyTuple logic into this method so we can delete decodeKeyTuple
10
+ const keyValues = decodeKeyTuple({ staticFields: Object.values(keySchema), dynamicFields: [] }, data);
11
+
12
+ return Object.fromEntries(
13
+ Object.keys(keySchema).map((name, i) => [name, keyValues[i]])
14
+ ) as SchemaToPrimitives<TSchema>;
15
+ }
@@ -1,6 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { decodeKeyTuple } from "./decodeKeyTuple";
3
- import { Schema } from "./common";
4
3
 
5
4
  describe("decodeKeyTuple", () => {
6
5
  it("can decode bool key tuple", () => {
@@ -4,7 +4,13 @@ import { Schema } from "./common";
4
4
 
5
5
  // key tuples are encoded in the same way as abi.encode, so we can decode them with viem
6
6
 
7
+ /** @deprecated use `decodeKey` instead */
7
8
  export function decodeKeyTuple(keySchema: Schema, keyTuple: readonly Hex[]): StaticPrimitiveType[] {
9
+ if (keySchema.staticFields.length !== keyTuple.length) {
10
+ throw new Error(
11
+ `key tuple length ${keyTuple.length} does not match key schema length ${keySchema.staticFields.length}`
12
+ );
13
+ }
8
14
  return keyTuple.map(
9
15
  (key, index) => decodeAbiParameters([{ type: keySchema.staticFields[index] }], key)[0] as StaticPrimitiveType
10
16
  );
@@ -3,11 +3,34 @@ import { decodeRecord } from "./decodeRecord";
3
3
 
4
4
  describe("decodeRecord", () => {
5
5
  it("can decode hex to record values", () => {
6
- const schema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const;
6
+ const valueSchema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const;
7
7
  const values = decodeRecord(
8
- schema,
9
- "0x0000000100000000000000000000000000000002000000000000130000000008000000000b0000000000000000000000000000000000000300000004736f6d6520737472696e67"
8
+ valueSchema,
9
+ "0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67"
10
10
  );
11
11
  expect(values).toStrictEqual([1, 2n, [3, 4], "some string"]);
12
12
  });
13
+
14
+ it("can decode an empty record", () => {
15
+ const valueSchema = { staticFields: [], dynamicFields: ["string", "string"] } as const;
16
+ const values = decodeRecord(valueSchema, "0x0000000000000000000000000000000000000000000000000000000000000000");
17
+ expect(values).toMatchInlineSnapshot(`
18
+ [
19
+ "",
20
+ "",
21
+ ]
22
+ `);
23
+ });
24
+
25
+ it("can decode an out of bounds array", () => {
26
+ const valueSchema = { staticFields: [], dynamicFields: ["uint32[]"] } as const;
27
+ const values = decodeRecord(valueSchema, "0x0000000000000000000000000000000000000000000000000400000000000004");
28
+ expect(values).toMatchInlineSnapshot(`
29
+ [
30
+ [
31
+ 0,
32
+ ],
33
+ ]
34
+ `);
35
+ });
13
36
  });
@@ -1,28 +1,35 @@
1
- import { StaticPrimitiveType, DynamicPrimitiveType, staticAbiTypeToByteLength } from "@latticexyz/schema-type";
2
- import { Hex, sliceHex } from "viem";
1
+ import {
2
+ StaticPrimitiveType,
3
+ DynamicPrimitiveType,
4
+ staticAbiTypeToByteLength,
5
+ dynamicAbiTypeToDefaultValue,
6
+ } from "@latticexyz/schema-type";
7
+ import { Hex } from "viem";
3
8
  import { Schema } from "./common";
4
9
  import { decodeDynamicField } from "./decodeDynamicField";
5
10
  import { decodeStaticField } from "./decodeStaticField";
6
11
  import { hexToPackedCounter } from "./hexToPackedCounter";
7
12
  import { staticDataLength } from "./staticDataLength";
13
+ import { readHex } from "@latticexyz/common";
8
14
 
9
- export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] {
15
+ /** @deprecated use `decodeValue` instead */
16
+ export function decodeRecord(valueSchema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] {
10
17
  const values: (StaticPrimitiveType | DynamicPrimitiveType)[] = [];
11
18
 
12
19
  let bytesOffset = 0;
13
- schema.staticFields.forEach((fieldType) => {
20
+ valueSchema.staticFields.forEach((fieldType) => {
14
21
  const fieldByteLength = staticAbiTypeToByteLength[fieldType];
15
- const value = decodeStaticField(fieldType, sliceHex(data, bytesOffset, bytesOffset + fieldByteLength));
22
+ const value = decodeStaticField(fieldType, readHex(data, bytesOffset, bytesOffset + fieldByteLength));
16
23
  bytesOffset += fieldByteLength;
17
24
  values.push(value);
18
25
  });
19
26
 
20
- // Warn user if static data length doesn't match the schema, because data corruption might be possible.
21
- const schemaStaticDataLength = staticDataLength(schema.staticFields);
27
+ // Warn user if static data length doesn't match the value schema, because data corruption might be possible.
28
+ const schemaStaticDataLength = staticDataLength(valueSchema.staticFields);
22
29
  const actualStaticDataLength = bytesOffset;
23
30
  if (actualStaticDataLength !== schemaStaticDataLength) {
24
31
  console.warn(
25
- "Decoded static data length does not match schema's expected static data length. Data may get corrupted. Is `getStaticByteLength` outdated?",
32
+ "Decoded static data length does not match value schema's expected static data length. Data may get corrupted. Is `getStaticByteLength` outdated?",
26
33
  {
27
34
  expectedLength: schemaStaticDataLength,
28
35
  actualLength: actualStaticDataLength,
@@ -31,18 +38,22 @@ export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimiti
31
38
  );
32
39
  }
33
40
 
34
- if (schema.dynamicFields.length > 0) {
35
- const dataLayout = hexToPackedCounter(sliceHex(data, bytesOffset, bytesOffset + 32));
41
+ if (valueSchema.dynamicFields.length > 0) {
42
+ const dataLayout = hexToPackedCounter(readHex(data, bytesOffset, bytesOffset + 32));
36
43
  bytesOffset += 32;
37
44
 
38
- schema.dynamicFields.forEach((fieldType, i) => {
45
+ valueSchema.dynamicFields.forEach((fieldType, i) => {
39
46
  const dataLength = dataLayout.fieldByteLengths[i];
40
- const value = decodeDynamicField(fieldType, sliceHex(data, bytesOffset, bytesOffset + dataLength));
41
- bytesOffset += dataLength;
42
- values.push(value);
47
+ if (dataLength > 0) {
48
+ const value = decodeDynamicField(fieldType, readHex(data, bytesOffset, bytesOffset + dataLength));
49
+ bytesOffset += dataLength;
50
+ values.push(value);
51
+ } else {
52
+ values.push(dynamicAbiTypeToDefaultValue[fieldType]);
53
+ }
43
54
  });
44
55
 
45
- // Warn user if dynamic data length doesn't match the schema, because data corruption might be possible.
56
+ // Warn user if dynamic data length doesn't match the dynamic data length, because data corruption might be possible.
46
57
  const actualDynamicDataLength = bytesOffset - 32 - actualStaticDataLength;
47
58
  // TODO: refactor this so we don't break for bytes offsets >UINT40
48
59
  if (BigInt(actualDynamicDataLength) !== dataLayout.totalByteLength) {
@@ -0,0 +1,16 @@
1
+ import { isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type";
2
+ import { Hex } from "viem";
3
+ import { SchemaToPrimitives, ValueSchema } from "./common";
4
+ import { decodeRecord } from "./decodeRecord";
5
+
6
+ export function decodeValue<TSchema extends ValueSchema>(valueSchema: TSchema, data: Hex): SchemaToPrimitives<TSchema> {
7
+ const staticFields = Object.values(valueSchema).filter(isStaticAbiType);
8
+ const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType);
9
+
10
+ // TODO: refactor and move all decodeRecord logic into this method so we can delete decodeRecord
11
+ const valueTuple = decodeRecord({ staticFields, dynamicFields }, data);
12
+
13
+ return Object.fromEntries(
14
+ Object.keys(valueSchema).map((name, i) => [name, valueTuple[i]])
15
+ ) as SchemaToPrimitives<TSchema>;
16
+ }
@@ -0,0 +1,20 @@
1
+ import { concatHex } from "viem";
2
+ import { isStaticAbiType } from "@latticexyz/schema-type";
3
+ import { SchemaToPrimitives, ValueArgs, ValueSchema } from "./common";
4
+ import { decodeValue } from "./decodeValue";
5
+ import { staticDataLength } from "./staticDataLength";
6
+ import { readHex } from "@latticexyz/common";
7
+
8
+ export function decodeValueArgs<TSchema extends ValueSchema>(
9
+ valueSchema: TSchema,
10
+ { staticData, encodedLengths, dynamicData }: ValueArgs
11
+ ): SchemaToPrimitives<TSchema> {
12
+ return decodeValue(
13
+ valueSchema,
14
+ concatHex([
15
+ readHex(staticData, 0, staticDataLength(Object.values(valueSchema).filter(isStaticAbiType))),
16
+ encodedLengths,
17
+ dynamicData,
18
+ ])
19
+ );
20
+ }
@@ -8,10 +8,13 @@ export function encodeField<TSchemaAbiType extends SchemaAbiType>(
8
8
  ): Hex {
9
9
  if (isArrayAbiType(fieldType) && Array.isArray(value)) {
10
10
  const staticFieldType = arrayAbiTypeToStaticAbiType(fieldType);
11
- return encodePacked(
12
- value.map(() => staticFieldType),
13
- value
14
- );
11
+ // TODO: we can remove conditional once this is fixed: https://github.com/wagmi-dev/viem/pull/1147
12
+ return value.length === 0
13
+ ? "0x"
14
+ : encodePacked(
15
+ value.map(() => staticFieldType),
16
+ value
17
+ );
15
18
  }
16
19
  return encodePacked([fieldType], [value]);
17
20
  }
@@ -0,0 +1,10 @@
1
+ import { isStaticAbiType } from "@latticexyz/schema-type";
2
+ import { Hex } from "viem";
3
+ import { SchemaToPrimitives, KeySchema } from "./common";
4
+ import { encodeKeyTuple } from "./encodeKeyTuple";
5
+
6
+ export function encodeKey<TSchema extends KeySchema>(keySchema: TSchema, key: SchemaToPrimitives<TSchema>): Hex[] {
7
+ const staticFields = Object.values(keySchema).filter(isStaticAbiType);
8
+ // TODO: refactor and move all encodeKeyTuple logic into this method so we can delete encodeKeyTuple
9
+ return encodeKeyTuple({ staticFields, dynamicFields: [] }, Object.values(key));
10
+ }
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { encodeKeyTuple } from "./encodeKeyTuple";
3
+
4
+ describe("encodeKeyTuple", () => {
5
+ it("can encode bool key tuple", () => {
6
+ expect(encodeKeyTuple({ staticFields: ["bool"], dynamicFields: [] }, [false])).toStrictEqual([
7
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
8
+ ]);
9
+ expect(
10
+ encodeKeyTuple(
11
+ {
12
+ staticFields: ["bool"],
13
+ dynamicFields: [],
14
+ },
15
+ [true]
16
+ )
17
+ ).toStrictEqual(["0x0000000000000000000000000000000000000000000000000000000000000001"]);
18
+ });
19
+
20
+ it("can encode complex key tuple", () => {
21
+ expect(
22
+ encodeKeyTuple({ staticFields: ["uint256", "int32", "bytes16", "address", "bool", "int8"], dynamicFields: [] }, [
23
+ 42n,
24
+ -42,
25
+ "0x12340000000000000000000000000000",
26
+ "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF",
27
+ true,
28
+ 3,
29
+ ])
30
+ ).toStrictEqual([
31
+ "0x000000000000000000000000000000000000000000000000000000000000002a",
32
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6",
33
+ "0x1234000000000000000000000000000000000000000000000000000000000000",
34
+ "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff",
35
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
36
+ "0x0000000000000000000000000000000000000000000000000000000000000003",
37
+ ]);
38
+ });
39
+ });
@@ -0,0 +1,8 @@
1
+ import { StaticPrimitiveType } from "@latticexyz/schema-type";
2
+ import { Hex, encodeAbiParameters } from "viem";
3
+ import { Schema } from "./common";
4
+
5
+ /** @deprecated use `encodeKey` instead */
6
+ export function encodeKeyTuple(keySchema: Schema, keyTuple: StaticPrimitiveType[]): Hex[] {
7
+ return keyTuple.map((key, index) => encodeAbiParameters([{ type: keySchema.staticFields[index] }], [key]));
8
+ }
@@ -0,0 +1,16 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { encodeLengths } from "./encodeLengths";
3
+
4
+ describe("encodeLengths", () => {
5
+ it("can encode empty tuple", () => {
6
+ expect(encodeLengths([])).toMatchInlineSnapshot(
7
+ '"0x0000000000000000000000000000000000000000000000000000000000000000"'
8
+ );
9
+ });
10
+
11
+ it("can encode bool key tuple", () => {
12
+ expect(encodeLengths(["0x1234", "0x12345678"])).toMatchInlineSnapshot(
13
+ '"0x0000000000000000000000000000000000000004000000000200000000000006"'
14
+ );
15
+ });
16
+ });
@@ -0,0 +1,12 @@
1
+ import { Hex, concatHex, padHex, size } from "viem";
2
+ import { encodeField } from "./encodeField";
3
+
4
+ export function encodeLengths(values: Hex[]): Hex {
5
+ const byteLengths = values.map(size).reverse();
6
+ const totalByteLength = byteLengths.reduce((total, length) => total + BigInt(length), 0n);
7
+
8
+ return padHex(
9
+ concatHex([...byteLengths.map((length) => encodeField("uint40", length)), encodeField("uint56", totalByteLength)]),
10
+ { size: 32, dir: "left" }
11
+ );
12
+ }
@@ -2,17 +2,23 @@ import { describe, expect, it } from "vitest";
2
2
  import { encodeRecord } from "./encodeRecord";
3
3
 
4
4
  describe("encodeRecord", () => {
5
- it("can encode a schema and record values to hex", () => {
6
- const schema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const;
7
- const hex = encodeRecord(schema, [1, 2n, [3, 4], "some string"]);
5
+ it("can encode a value schema and record values to hex", () => {
6
+ const valueSchema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const;
7
+ const hex = encodeRecord(valueSchema, [1, 2n, [3, 4], "some string"]);
8
8
  expect(hex).toBe(
9
- "0x0000000100000000000000000000000000000002000000000000130000000008000000000b0000000000000000000000000000000000000300000004736f6d6520737472696e67"
9
+ "0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67"
10
10
  );
11
11
  });
12
12
 
13
13
  it("should not include the packed dynamic lengths if there are no dynamic fields", () => {
14
- const schema = { staticFields: ["uint32", "uint128"], dynamicFields: [] } as const;
15
- const hex = encodeRecord(schema, [1, 2n]);
14
+ const valueSchema = { staticFields: ["uint32", "uint128"], dynamicFields: [] } as const;
15
+ const hex = encodeRecord(valueSchema, [1, 2n]);
16
16
  expect(hex).toBe("0x0000000100000000000000000000000000000002");
17
17
  });
18
+
19
+ it("can encode an array to hex", () => {
20
+ const valueSchema = { staticFields: [], dynamicFields: ["uint32[]"] } as const;
21
+ const hex = encodeRecord(valueSchema, [[42]]);
22
+ expect(hex).toBe("0x00000000000000000000000000000000000000000000000004000000000000040000002a");
23
+ });
18
24
  });
@@ -3,28 +3,32 @@ import { Hex } from "viem";
3
3
  import { encodeField } from "./encodeField";
4
4
  import { Schema } from "./common";
5
5
 
6
- export function encodeRecord(schema: Schema, values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[]): Hex {
7
- const staticValues = values.slice(0, schema.staticFields.length) as readonly StaticPrimitiveType[];
8
- const dynamicValues = values.slice(schema.staticFields.length) as readonly DynamicPrimitiveType[];
6
+ /** @deprecated use `encodeValue` instead */
7
+ export function encodeRecord(
8
+ valueSchema: Schema,
9
+ values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[]
10
+ ): Hex {
11
+ const staticValues = values.slice(0, valueSchema.staticFields.length) as readonly StaticPrimitiveType[];
12
+ const dynamicValues = values.slice(valueSchema.staticFields.length) as readonly DynamicPrimitiveType[];
9
13
 
10
14
  const staticData = staticValues
11
- .map((value, i) => encodeField(schema.staticFields[i], value).replace(/^0x/, ""))
15
+ .map((value, i) => encodeField(valueSchema.staticFields[i], value).replace(/^0x/, ""))
12
16
  .join("");
13
17
 
14
- if (schema.dynamicFields.length === 0) return `0x${staticData}`;
18
+ if (valueSchema.dynamicFields.length === 0) return `0x${staticData}`;
15
19
 
16
20
  const dynamicDataItems = dynamicValues.map((value, i) =>
17
- encodeField(schema.dynamicFields[i], value).replace(/^0x/, "")
21
+ encodeField(valueSchema.dynamicFields[i], value).replace(/^0x/, "")
18
22
  );
19
23
 
20
- const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2);
24
+ const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2).reverse();
21
25
  const dynamicTotalByteLength = dynamicFieldByteLengths.reduce((total, length) => total + BigInt(length), 0n);
22
26
 
23
27
  const dynamicData = dynamicDataItems.join("");
24
28
 
25
- const packedCounter = `${encodeField("uint56", dynamicTotalByteLength).replace(/^0x/, "")}${dynamicFieldByteLengths
29
+ const packedCounter = `${dynamicFieldByteLengths
26
30
  .map((length) => encodeField("uint40", length).replace(/^0x/, ""))
27
- .join("")}`.padEnd(64, "0");
31
+ .join("")}${encodeField("uint56", dynamicTotalByteLength).replace(/^0x/, "")}`.padStart(64, "0");
28
32
 
29
33
  return `0x${staticData}${packedCounter}${dynamicData}`;
30
34
  }
@@ -0,0 +1,11 @@
1
+ import { Hex, concatHex } from "viem";
2
+ import { SchemaToPrimitives, ValueSchema } from "./common";
3
+ import { encodeValueArgs } from "./encodeValueArgs";
4
+
5
+ export function encodeValue<TSchema extends ValueSchema>(
6
+ valueSchema: TSchema,
7
+ value: SchemaToPrimitives<TSchema>
8
+ ): Hex {
9
+ const { staticData, encodedLengths, dynamicData } = encodeValueArgs(valueSchema, value);
10
+ return concatHex([staticData, encodedLengths, dynamicData]);
11
+ }
@@ -0,0 +1,53 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { encodeValueArgs } from "./encodeValueArgs";
3
+ import { stringToHex } from "viem";
4
+
5
+ describe("encodeValueArgs", () => {
6
+ it("can encode record value to hex", () => {
7
+ const valueSchema = {
8
+ entityId: "bytes32",
9
+ exists: "bool",
10
+ playerName: "string",
11
+ badges: "uint256[]",
12
+ } as const;
13
+
14
+ const result = encodeValueArgs(valueSchema, {
15
+ entityId: stringToHex("hello", { size: 32 }),
16
+ exists: true,
17
+ playerName: "henry",
18
+ badges: [42n],
19
+ });
20
+
21
+ expect(result).toMatchInlineSnapshot(`
22
+ {
23
+ "dynamicData": "0x68656e7279000000000000000000000000000000000000000000000000000000000000002a",
24
+ "encodedLengths": "0x0000000000000000000000000000000000000020000000000500000000000025",
25
+ "staticData": "0x68656c6c6f00000000000000000000000000000000000000000000000000000001",
26
+ }
27
+ `);
28
+ });
29
+
30
+ it("encodes record when key order of value and valueSchema do not match", () => {
31
+ const valueSchema = {
32
+ entityId: "bytes32",
33
+ playerName: "string",
34
+ exists: "bool",
35
+ badges: "uint256[]",
36
+ } as const;
37
+
38
+ const result = encodeValueArgs(valueSchema, {
39
+ exists: true,
40
+ playerName: "henry",
41
+ entityId: stringToHex("hello", { size: 32 }),
42
+ badges: [42n],
43
+ });
44
+
45
+ expect(result).toMatchInlineSnapshot(`
46
+ {
47
+ "dynamicData": "0x68656e7279000000000000000000000000000000000000000000000000000000000000002a",
48
+ "encodedLengths": "0x0000000000000000000000000000000000000020000000000500000000000025",
49
+ "staticData": "0x68656c6c6f00000000000000000000000000000000000000000000000000000001",
50
+ }
51
+ `);
52
+ });
53
+ });
@@ -0,0 +1,36 @@
1
+ import {
2
+ StaticPrimitiveType,
3
+ DynamicPrimitiveType,
4
+ isStaticAbiType,
5
+ isDynamicAbiType,
6
+ StaticAbiType,
7
+ DynamicAbiType,
8
+ } from "@latticexyz/schema-type";
9
+ import { concatHex } from "viem";
10
+ import { encodeField } from "./encodeField";
11
+ import { SchemaToPrimitives, ValueArgs, ValueSchema } from "./common";
12
+ import { encodeLengths } from "./encodeLengths";
13
+
14
+ export function encodeValueArgs<TSchema extends ValueSchema>(
15
+ valueSchema: TSchema,
16
+ value: SchemaToPrimitives<TSchema>
17
+ ): ValueArgs {
18
+ const valueSchemaEntries = Object.entries(valueSchema);
19
+ const staticFields = valueSchemaEntries.filter(([, type]) => isStaticAbiType(type)) as [string, StaticAbiType][];
20
+ const dynamicFields = valueSchemaEntries.filter(([, type]) => isDynamicAbiType(type)) as [string, DynamicAbiType][];
21
+ // TODO: validate <=5 dynamic fields
22
+ // TODO: validate <=28 total fields
23
+
24
+ const encodedStaticValues = staticFields.map(([name, type]) => encodeField(type, value[name] as StaticPrimitiveType));
25
+ const encodedDynamicValues = dynamicFields.map(([name, type]) =>
26
+ encodeField(type, value[name] as DynamicPrimitiveType)
27
+ );
28
+
29
+ const encodedLengths = encodeLengths(encodedDynamicValues);
30
+
31
+ return {
32
+ staticData: concatHex(encodedStaticValues),
33
+ encodedLengths,
34
+ dynamicData: concatHex(encodedDynamicValues),
35
+ };
36
+ }
package/src/errors.ts CHANGED
@@ -49,7 +49,8 @@ export class SchemaStaticLengthMismatchError extends MUDError {
49
49
  override name = "SchemaStaticLengthMismatchError";
50
50
  constructor(schemaData: Hex, definedLength: number, summedLength: number) {
51
51
  super(
52
- `Schema "${schemaData}" static data length (${definedLength}) did not match the summed length of all static fields (${summedLength}). Is \`staticAbiTypeToByteLength\` up to date with Solidity schema types?`
52
+ `Schema "${schemaData}" static data length (${definedLength}) did not match the summed length of all static fields (${summedLength}). ` +
53
+ `Is \`staticAbiTypeToByteLength\` up to date with Solidity schema types?`
53
54
  );
54
55
  }
55
56
  }
@@ -0,0 +1,15 @@
1
+ import { Hex } from "viem";
2
+ import { FieldLayout } from "./common";
3
+
4
+ /** @deprecated use `valueSchemaToFieldLayoutHex` instead */
5
+ export function fieldLayoutToHex(fieldLayout: FieldLayout): Hex {
6
+ const staticDataLength = fieldLayout.staticFieldLengths.reduce((totalLength, length) => totalLength + length, 0);
7
+ return `0x${[
8
+ staticDataLength.toString(16).padStart(4, "0"),
9
+ fieldLayout.staticFieldLengths.length.toString(16).padStart(2, "0"),
10
+ fieldLayout.numDynamicFields.toString(16).padStart(2, "0"),
11
+ ...fieldLayout.staticFieldLengths.map((schemaType) => schemaType.toString(16).padStart(2, "0")),
12
+ ]
13
+ .join("")
14
+ .padEnd(64, "0")}`;
15
+ }
@@ -3,7 +3,7 @@ import { hexToPackedCounter } from "./hexToPackedCounter";
3
3
 
4
4
  describe("hexToPackedCounter", () => {
5
5
  it("decodes hex data to packed counter", () => {
6
- expect(hexToPackedCounter("0x0000000000008000000000200000000020000000004000000000000000000000"))
6
+ expect(hexToPackedCounter("0x0000000000000000000000000000400000000020000000002000000000000080"))
7
7
  .toMatchInlineSnapshot(`
8
8
  {
9
9
  "fieldByteLengths": [
@@ -26,9 +26,10 @@ describe("hexToPackedCounter", () => {
26
26
 
27
27
  it("throws if packed counter total byte length doesn't match summed byte length of fields", () => {
28
28
  expect(() =>
29
- hexToPackedCounter("0x0000000000004000000000200000000020000000004000000000000000000000")
29
+ hexToPackedCounter("0x0000000000000000000000000000400000000020000000002000000000000040")
30
30
  ).toThrowErrorMatchingInlineSnapshot(
31
- '"PackedCounter \\"0x0000000000004000000000200000000020000000004000000000000000000000\\" total bytes length (64) did not match the summed length of all field byte lengths (128)."'
31
+ // eslint-disable-next-line max-len
32
+ '"PackedCounter \\"0x0000000000000000000000000000400000000020000000002000000000000040\\" total bytes length (64) did not match the summed length of all field byte lengths (128)."'
32
33
  );
33
34
  });
34
35
  });
@@ -1,14 +1,15 @@
1
- import { Hex, sliceHex } from "viem";
1
+ import { Hex } from "viem";
2
2
  import { decodeStaticField } from "./decodeStaticField";
3
3
  import { decodeDynamicField } from "./decodeDynamicField";
4
4
  import { InvalidHexLengthForPackedCounterError, PackedCounterLengthMismatchError } from "./errors";
5
+ import { readHex } from "@latticexyz/common";
5
6
 
6
7
  // Keep this logic in sync with PackedCounter.sol
7
8
 
8
- // - First 7 bytes (uint56) are used for the total byte length of the dynamic data
9
- // - The next 5 byte (uint40) sections are used for the byte length of each field, in the same order as the schema's dynamic fields
9
+ // - Last 7 bytes (uint56) are used for the total byte length of the dynamic data
10
+ // - The next 5 byte (uint40) sections are used for the byte length of each field, indexed from right to left
10
11
 
11
- // We use byte lengths rather than item counts so that, on chain, we can slice without having to get the schema first (and thus the field lengths of each dynamic type)
12
+ // We use byte lengths rather than item counts so that, on chain, we can slice without having to get the value schema first (and thus the field lengths of each dynamic type)
12
13
 
13
14
  export function hexToPackedCounter(data: Hex): {
14
15
  totalByteLength: bigint;
@@ -17,10 +18,12 @@ export function hexToPackedCounter(data: Hex): {
17
18
  if (data.length !== 66) {
18
19
  throw new InvalidHexLengthForPackedCounterError(data);
19
20
  }
20
- const totalByteLength = decodeStaticField("uint56", sliceHex(data, 0, 7));
21
21
 
22
- // TODO: use schema to make sure we only parse as many as we need (rather than zeroes at the end)?
23
- const fieldByteLengths = decodeDynamicField("uint40[]", sliceHex(data, 7));
22
+ const totalByteLength = decodeStaticField("uint56", readHex(data, 32 - 7, 32));
23
+ // TODO: use value schema to make sure we only parse as many as we need (rather than zeroes at the end)?
24
+ const reversedFieldByteLengths = decodeDynamicField("uint40[]", readHex(data, 0, 32 - 7));
25
+ // Reverse the lengths
26
+ const fieldByteLengths = Object.freeze([...reversedFieldByteLengths].reverse());
24
27
 
25
28
  const summedLength = BigInt(fieldByteLengths.reduce((total, length) => total + length, 0));
26
29
  if (summedLength !== totalByteLength) {
@@ -35,6 +35,22 @@ describe("hexToSchema", () => {
35
35
  ],
36
36
  }
37
37
  `);
38
+
39
+ expect(hexToSchema("0x00570800616100030700001f0000000000000000000000000000000000000000")).toMatchInlineSnapshot(`
40
+ {
41
+ "dynamicFields": [],
42
+ "staticFields": [
43
+ "address",
44
+ "address",
45
+ "uint8",
46
+ "uint32",
47
+ "uint64",
48
+ "uint8",
49
+ "uint8",
50
+ "uint256",
51
+ ],
52
+ }
53
+ `);
38
54
  });
39
55
 
40
56
  it("throws if schema hex data is not bytes32", () => {
@@ -45,6 +61,7 @@ describe("hexToSchema", () => {
45
61
 
46
62
  it("throws if schema static field lengths do not match", () => {
47
63
  expect(() => hexToSchema("0x002502045f2381c3c4c500000000000000000000000000000000000000000000")).toThrow(
64
+ // eslint-disable-next-line max-len
48
65
  'Schema "0x002502045f2381c3c4c500000000000000000000000000000000000000000000" static data length (37) did not match the summed length of all static fields (36). Is `staticAbiTypeToByteLength` up to date with Solidity schema types?'
49
66
  );
50
67
  });
@@ -26,6 +26,10 @@ export function hexToSchema(data: Hex): Schema {
26
26
  // validate static data length
27
27
  const actualStaticDataLength = staticFields.reduce((acc, fieldType) => acc + staticAbiTypeToByteLength[fieldType], 0);
28
28
  if (actualStaticDataLength !== staticDataLength) {
29
+ console.warn(
30
+ `Schema "${data}" static data length (${staticDataLength}) did not match the summed length of all static fields (${actualStaticDataLength}). ` +
31
+ `Is \`staticAbiTypeToByteLength\` up to date with Solidity schema types?`
32
+ );
29
33
  throw new SchemaStaticLengthMismatchError(data, staticDataLength, actualStaticDataLength);
30
34
  }
31
35
 
package/src/index.ts CHANGED
@@ -1,10 +1,27 @@
1
+ export * from "./abiTypesToSchema";
1
2
  export * from "./common";
2
3
  export * from "./decodeDynamicField";
4
+ export * from "./decodeField";
5
+ export * from "./decodeKey";
3
6
  export * from "./decodeKeyTuple";
4
7
  export * from "./decodeRecord";
5
8
  export * from "./decodeStaticField";
9
+ export * from "./decodeValue";
10
+ export * from "./decodeValueArgs";
6
11
  export * from "./encodeField";
12
+ export * from "./encodeKey";
13
+ export * from "./encodeKeyTuple";
7
14
  export * from "./encodeRecord";
15
+ export * from "./encodeValue";
16
+ export * from "./encodeValueArgs";
8
17
  export * from "./errors";
18
+ export * from "./fieldLayoutToHex";
9
19
  export * from "./hexToPackedCounter";
20
+ export * from "./hexToSchema";
10
21
  export * from "./hexToTableSchema";
22
+ export * from "./keySchemaToHex";
23
+ export * from "./schemaIndexToAbiType";
24
+ export * from "./schemaToHex";
25
+ export * from "./staticDataLength";
26
+ export * from "./valueSchemaToFieldLayoutHex";
27
+ export * from "./valueSchemaToHex";
@@ -0,0 +1,8 @@
1
+ import { isStaticAbiType } from "@latticexyz/schema-type";
2
+ import { Hex } from "viem";
3
+ import { KeySchema } from "./common";
4
+ import { schemaToHex } from "./schemaToHex";
5
+
6
+ export function keySchemaToHex(keySchema: KeySchema): Hex {
7
+ return schemaToHex({ staticFields: Object.values(keySchema).filter(isStaticAbiType), dynamicFields: [] });
8
+ }
@@ -0,0 +1,9 @@
1
+ import { SchemaAbiType } from "@latticexyz/schema-type";
2
+ import { Schema } from "./common";
3
+
4
+ export function schemaIndexToAbiType(schema: Schema, schemaIndex: number): SchemaAbiType {
5
+ if (schemaIndex < schema.staticFields.length) {
6
+ return schema.staticFields[schemaIndex];
7
+ }
8
+ return schema.dynamicFields[schemaIndex - schema.staticFields.length];
9
+ }
@@ -3,6 +3,7 @@ import { Hex } from "viem";
3
3
  import { Schema } from "./common";
4
4
  import { staticDataLength } from "./staticDataLength";
5
5
 
6
+ /** @deprecated use `keySchemaToHex` or `valueSchemaToHex` instead */
6
7
  export function schemaToHex(schema: Schema): Hex {
7
8
  const staticSchemaTypes = schema.staticFields.map((abiType) => schemaAbiTypes.indexOf(abiType));
8
9
  const dynamicSchemaTypes = schema.dynamicFields.map((abiType) => schemaAbiTypes.indexOf(abiType));
@@ -0,0 +1,21 @@
1
+ import { Hex } from "viem";
2
+ import { ValueSchema } from "./common";
3
+ import { isDynamicAbiType, isStaticAbiType, staticAbiTypeToByteLength } from "@latticexyz/schema-type";
4
+
5
+ // TODO: add tests once we have corresponding tests for FieldLayout.sol (bytes32 -> FieldLayout and vice versa)
6
+ export function valueSchemaToFieldLayoutHex(valueSchema: ValueSchema): Hex {
7
+ const staticFields = Object.values(valueSchema).filter(isStaticAbiType);
8
+ const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType);
9
+
10
+ const staticFieldLengths = staticFields.map((fieldType) => staticAbiTypeToByteLength[fieldType]);
11
+ const staticDataLength = staticFieldLengths.reduce((dataLength, fieldLength) => dataLength + fieldLength, 0);
12
+
13
+ return `0x${[
14
+ staticDataLength.toString(16).padStart(4, "0"),
15
+ staticFields.length.toString(16).padStart(2, "0"),
16
+ dynamicFields.length.toString(16).padStart(2, "0"),
17
+ ...staticFieldLengths.map((fieldLength) => fieldLength.toString(16).padStart(2, "0")),
18
+ ]
19
+ .join("")
20
+ .padEnd(64, "0")}`;
21
+ }
@@ -0,0 +1,11 @@
1
+ import { isDynamicAbiType, isStaticAbiType } from "@latticexyz/schema-type";
2
+ import { Hex } from "viem";
3
+ import { ValueSchema } from "./common";
4
+ import { schemaToHex } from "./schemaToHex";
5
+
6
+ export function valueSchemaToHex(valueSchema: ValueSchema): Hex {
7
+ return schemaToHex({
8
+ staticFields: Object.values(valueSchema).filter(isStaticAbiType),
9
+ dynamicFields: Object.values(valueSchema).filter(isDynamicAbiType),
10
+ });
11
+ }