@latticexyz/common 2.2.18-8d0ce55e964e646a1c804c401df01c4deb866f30 → 2.2.18-9fa07c8489f1fbf167d0db01cd9aaa645a29c8e2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/actions.cjs +334 -0
  2. package/dist/actions.cjs.map +1 -0
  3. package/dist/actions.d.cts +27 -0
  4. package/dist/actions.js +39 -1
  5. package/dist/actions.js.map +1 -1
  6. package/dist/chains.cjs +106 -0
  7. package/dist/chains.cjs.map +1 -0
  8. package/dist/chains.d.cts +968 -0
  9. package/dist/chains.js +75 -1
  10. package/dist/chains.js.map +1 -1
  11. package/dist/chunk-D4GDXAMP.js +64 -0
  12. package/dist/{chunk-ZIUX7JCQ.js.map → chunk-D4GDXAMP.js.map} +1 -1
  13. package/dist/chunk-IYZZFDNO.js +16 -0
  14. package/dist/{chunk-ZV2KGJCD.js.map → chunk-IYZZFDNO.js.map} +1 -1
  15. package/dist/chunk-MF5NFUW7.js +12 -0
  16. package/dist/{chunk-QQCZY3XJ.js.map → chunk-MF5NFUW7.js.map} +1 -1
  17. package/dist/chunk-MK6UECU7.js +11 -0
  18. package/dist/{chunk-TCWGPC6G.js.map → chunk-MK6UECU7.js.map} +1 -1
  19. package/dist/chunk-MYWRXQQH.js +208 -0
  20. package/dist/{chunk-6FIKI2CG.js.map → chunk-MYWRXQQH.js.map} +1 -1
  21. package/dist/chunk-Z6SVAIZN.js +70 -0
  22. package/dist/{chunk-DPUUE7NM.js.map → chunk-Z6SVAIZN.js.map} +1 -1
  23. package/dist/codegen.cjs +889 -0
  24. package/dist/codegen.cjs.map +1 -0
  25. package/dist/codegen.d.cts +228 -0
  26. package/dist/codegen.js +706 -49
  27. package/dist/codegen.js.map +1 -1
  28. package/dist/errors.cjs +38 -0
  29. package/dist/errors.cjs.map +1 -0
  30. package/dist/errors.d.cts +5 -0
  31. package/dist/errors.js +6 -1
  32. package/dist/foundry.cjs +105 -0
  33. package/dist/foundry.cjs.map +1 -0
  34. package/dist/foundry.d.cts +69 -0
  35. package/dist/foundry.js +71 -2
  36. package/dist/foundry.js.map +1 -1
  37. package/dist/getContract-CA0EdVg6.d.cts +20 -0
  38. package/dist/index.cjs +597 -0
  39. package/dist/index.cjs.map +1 -0
  40. package/dist/index.d.cts +160 -0
  41. package/dist/index.js +233 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/internal.cjs +459 -0
  44. package/dist/internal.cjs.map +1 -0
  45. package/dist/internal.d.cts +36 -0
  46. package/dist/internal.js +205 -9
  47. package/dist/internal.js.map +1 -1
  48. package/dist/kms.cjs +204 -0
  49. package/dist/kms.cjs.map +1 -0
  50. package/dist/kms.d.cts +18 -0
  51. package/dist/kms.js +168 -1
  52. package/dist/kms.js.map +1 -1
  53. package/dist/type-utils.cjs +19 -0
  54. package/dist/type-utils.cjs.map +1 -0
  55. package/dist/type-utils.d.cts +19 -0
  56. package/dist/utils.cjs +174 -0
  57. package/dist/utils.cjs.map +1 -0
  58. package/dist/utils.d.cts +40 -0
  59. package/dist/utils.js +122 -1
  60. package/dist/utils.js.map +1 -1
  61. package/package.json +102 -12
  62. package/dist/chunk-6FIKI2CG.js +0 -2
  63. package/dist/chunk-DPUUE7NM.js +0 -2
  64. package/dist/chunk-QQCZY3XJ.js +0 -2
  65. package/dist/chunk-TCWGPC6G.js +0 -2
  66. package/dist/chunk-ZIUX7JCQ.js +0 -2
  67. package/dist/chunk-ZV2KGJCD.js +0 -2
package/dist/chains.js CHANGED
@@ -1,2 +1,76 @@
1
- import{foundry as t}from"viem/chains";var s={...t,fees:{defaultPriorityFee:0n}};import{redstone as n}from"viem/chains";var i={...n,iconUrls:["https://redstone.xyz/chain-icons/redstone.png"],indexerUrl:"https://indexer.mud.redstonechain.com"};import{garnet as a}from"viem/chains";var c={...a,iconUrls:["https://redstone.xyz/chain-icons/garnet.png"],indexerUrl:"https://indexer.mud.garnetchain.com"};import{chainConfig as e}from"viem/op-stack";var o=17e3,r={http:["https://rpc.rhodolitechain.com"],webSocket:["wss://rpc.rhodolitechain.com"]},d={...e,name:"Rhodolite Devnet",testnet:!0,id:17420,sourceId:o,nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:{default:r,bundler:r,quarryPassIssuer:r,wiresaw:r},contracts:{...e.contracts,l1StandardBridge:{[o]:{address:"0x6487446e0B9FAEa90F6a9772A6448cFa780E30F9"}},quarryPaymaster:{address:"0x7ca1b85aca23fccf2fbac14c02b5e8a6432639b9"}},blockExplorers:{default:{name:"Blockscout",url:"https://explorer.rhodolitechain.com"},worldsExplorer:{name:"MUD Worlds Explorer",url:"https://explorer.mud.dev/rhodolite/worlds"}},iconUrls:["https://redstone.xyz/chain-icons/rhodolite.png"],indexerUrl:"https://indexer.mud.rhodolitechain.com"};export{c as garnet,s as mudFoundry,i as redstone,d as rhodolite};
1
+ // src/chains/mudFoundry.ts
2
+ import { foundry } from "viem/chains";
3
+ var mudFoundry = {
4
+ ...foundry,
5
+ fees: {
6
+ defaultPriorityFee: 0n
7
+ }
8
+ };
9
+
10
+ // src/chains/redstone.ts
11
+ import { redstone as redstoneConfig } from "viem/chains";
12
+ var redstone = {
13
+ ...redstoneConfig,
14
+ iconUrls: ["https://redstone.xyz/chain-icons/redstone.png"],
15
+ indexerUrl: "https://indexer.mud.redstonechain.com"
16
+ };
17
+
18
+ // src/chains/garnet.ts
19
+ import { garnet as garnetConfig } from "viem/chains";
20
+ var garnet = {
21
+ ...garnetConfig,
22
+ iconUrls: ["https://redstone.xyz/chain-icons/garnet.png"],
23
+ indexerUrl: "https://indexer.mud.garnetchain.com"
24
+ };
25
+
26
+ // src/chains/rhodolite.ts
27
+ import { chainConfig } from "viem/op-stack";
28
+ var sourceId = 17e3;
29
+ var defaultRpcUrls = {
30
+ http: ["https://rpc.rhodolitechain.com"],
31
+ webSocket: ["wss://rpc.rhodolitechain.com"]
32
+ };
33
+ var rhodolite = {
34
+ ...chainConfig,
35
+ name: "Rhodolite Devnet",
36
+ testnet: true,
37
+ id: 17420,
38
+ sourceId,
39
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
40
+ rpcUrls: {
41
+ default: defaultRpcUrls,
42
+ bundler: defaultRpcUrls,
43
+ quarryPassIssuer: defaultRpcUrls,
44
+ wiresaw: defaultRpcUrls
45
+ },
46
+ contracts: {
47
+ ...chainConfig.contracts,
48
+ l1StandardBridge: {
49
+ [sourceId]: {
50
+ address: "0x6487446e0B9FAEa90F6a9772A6448cFa780E30F9"
51
+ }
52
+ },
53
+ quarryPaymaster: {
54
+ address: "0x7ca1b85aca23fccf2fbac14c02b5e8a6432639b9"
55
+ }
56
+ },
57
+ blockExplorers: {
58
+ default: {
59
+ name: "Blockscout",
60
+ url: "https://explorer.rhodolitechain.com"
61
+ },
62
+ worldsExplorer: {
63
+ name: "MUD Worlds Explorer",
64
+ url: "https://explorer.mud.dev/rhodolite/worlds"
65
+ }
66
+ },
67
+ iconUrls: ["https://redstone.xyz/chain-icons/rhodolite.png"],
68
+ indexerUrl: "https://indexer.mud.rhodolitechain.com"
69
+ };
70
+ export {
71
+ garnet,
72
+ mudFoundry,
73
+ redstone,
74
+ rhodolite
75
+ };
2
76
  //# sourceMappingURL=chains.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chains/mudFoundry.ts","../src/chains/redstone.ts","../src/chains/garnet.ts","../src/chains/rhodolite.ts"],"sourcesContent":["import { foundry } from \"viem/chains\";\nimport { MUDChain } from \"./types\";\n\nexport const mudFoundry = {\n ...foundry,\n fees: {\n defaultPriorityFee: 0n,\n },\n} as const satisfies MUDChain;\n","import { redstone as redstoneConfig } from \"viem/chains\";\nimport type { MUDChain } from \"./types\";\n\nexport const redstone = {\n ...redstoneConfig,\n iconUrls: [\"https://redstone.xyz/chain-icons/redstone.png\"],\n indexerUrl: \"https://indexer.mud.redstonechain.com\",\n} as const satisfies MUDChain;\n","import { garnet as garnetConfig } from \"viem/chains\";\nimport type { MUDChain } from \"./types\";\n\nexport const garnet = {\n ...garnetConfig,\n iconUrls: [\"https://redstone.xyz/chain-icons/garnet.png\"],\n indexerUrl: \"https://indexer.mud.garnetchain.com\",\n} as const satisfies MUDChain;\n","import { chainConfig } from \"viem/op-stack\";\nimport { MUDChain } from \"./types\";\nimport { Chain } from \"viem\";\n\nconst sourceId = 17000;\n\nconst defaultRpcUrls = {\n http: [\"https://rpc.rhodolitechain.com\"],\n webSocket: [\"wss://rpc.rhodolitechain.com\"],\n} as const satisfies Chain[\"rpcUrls\"][\"default\"];\n\nexport const rhodolite = {\n ...chainConfig,\n name: \"Rhodolite Devnet\",\n testnet: true,\n id: 17420,\n sourceId,\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: defaultRpcUrls,\n bundler: defaultRpcUrls,\n quarryPassIssuer: defaultRpcUrls,\n wiresaw: defaultRpcUrls,\n },\n contracts: {\n ...chainConfig.contracts,\n l1StandardBridge: {\n [sourceId]: {\n address: \"0x6487446e0B9FAEa90F6a9772A6448cFa780E30F9\",\n },\n },\n quarryPaymaster: {\n address: \"0x7ca1b85aca23fccf2fbac14c02b5e8a6432639b9\",\n },\n },\n blockExplorers: {\n default: {\n name: \"Blockscout\",\n url: \"https://explorer.rhodolitechain.com\",\n },\n worldsExplorer: {\n name: \"MUD Worlds Explorer\",\n url: \"https://explorer.mud.dev/rhodolite/worlds\",\n },\n },\n iconUrls: [\"https://redstone.xyz/chain-icons/rhodolite.png\"],\n indexerUrl: \"https://indexer.mud.rhodolitechain.com\",\n} as const satisfies MUDChain;\n"],"mappings":"AAAA,OAAS,WAAAA,MAAe,cAGjB,IAAMC,EAAa,CACxB,GAAGD,EACH,KAAM,CACJ,mBAAoB,EACtB,CACF,ECRA,OAAS,YAAYE,MAAsB,cAGpC,IAAMC,EAAW,CACtB,GAAGD,EACH,SAAU,CAAC,+CAA+C,EAC1D,WAAY,uCACd,ECPA,OAAS,UAAUE,MAAoB,cAGhC,IAAMC,EAAS,CACpB,GAAGD,EACH,SAAU,CAAC,6CAA6C,EACxD,WAAY,qCACd,ECPA,OAAS,eAAAE,MAAmB,gBAI5B,IAAMC,EAAW,KAEXC,EAAiB,CACrB,KAAM,CAAC,gCAAgC,EACvC,UAAW,CAAC,8BAA8B,CAC5C,EAEaC,EAAY,CACvB,GAAGH,EACH,KAAM,mBACN,QAAS,GACT,GAAI,MACJ,SAAAC,EACA,eAAgB,CAAE,KAAM,QAAS,OAAQ,MAAO,SAAU,EAAG,EAC7D,QAAS,CACP,QAASC,EACT,QAASA,EACT,iBAAkBA,EAClB,QAASA,CACX,EACA,UAAW,CACT,GAAGF,EAAY,UACf,iBAAkB,CAChB,CAACC,CAAQ,EAAG,CACV,QAAS,4CACX,CACF,EACA,gBAAiB,CACf,QAAS,4CACX,CACF,EACA,eAAgB,CACd,QAAS,CACP,KAAM,aACN,IAAK,qCACP,EACA,eAAgB,CACd,KAAM,sBACN,IAAK,2CACP,CACF,EACA,SAAU,CAAC,gDAAgD,EAC3D,WAAY,wCACd","names":["foundry","mudFoundry","redstoneConfig","redstone","garnetConfig","garnet","chainConfig","sourceId","defaultRpcUrls","rhodolite"]}
1
+ {"version":3,"sources":["../src/chains/mudFoundry.ts","../src/chains/redstone.ts","../src/chains/garnet.ts","../src/chains/rhodolite.ts"],"sourcesContent":["import { foundry } from \"viem/chains\";\nimport { MUDChain } from \"./types\";\n\nexport const mudFoundry = {\n ...foundry,\n fees: {\n defaultPriorityFee: 0n,\n },\n} as const satisfies MUDChain;\n","import { redstone as redstoneConfig } from \"viem/chains\";\nimport type { MUDChain } from \"./types\";\n\nexport const redstone = {\n ...redstoneConfig,\n iconUrls: [\"https://redstone.xyz/chain-icons/redstone.png\"],\n indexerUrl: \"https://indexer.mud.redstonechain.com\",\n} as const satisfies MUDChain;\n","import { garnet as garnetConfig } from \"viem/chains\";\nimport type { MUDChain } from \"./types\";\n\nexport const garnet = {\n ...garnetConfig,\n iconUrls: [\"https://redstone.xyz/chain-icons/garnet.png\"],\n indexerUrl: \"https://indexer.mud.garnetchain.com\",\n} as const satisfies MUDChain;\n","import { chainConfig } from \"viem/op-stack\";\nimport { MUDChain } from \"./types\";\nimport { Chain } from \"viem\";\n\nconst sourceId = 17000;\n\nconst defaultRpcUrls = {\n http: [\"https://rpc.rhodolitechain.com\"],\n webSocket: [\"wss://rpc.rhodolitechain.com\"],\n} as const satisfies Chain[\"rpcUrls\"][\"default\"];\n\nexport const rhodolite = {\n ...chainConfig,\n name: \"Rhodolite Devnet\",\n testnet: true,\n id: 17420,\n sourceId,\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: defaultRpcUrls,\n bundler: defaultRpcUrls,\n quarryPassIssuer: defaultRpcUrls,\n wiresaw: defaultRpcUrls,\n },\n contracts: {\n ...chainConfig.contracts,\n l1StandardBridge: {\n [sourceId]: {\n address: \"0x6487446e0B9FAEa90F6a9772A6448cFa780E30F9\",\n },\n },\n quarryPaymaster: {\n address: \"0x7ca1b85aca23fccf2fbac14c02b5e8a6432639b9\",\n },\n },\n blockExplorers: {\n default: {\n name: \"Blockscout\",\n url: \"https://explorer.rhodolitechain.com\",\n },\n worldsExplorer: {\n name: \"MUD Worlds Explorer\",\n url: \"https://explorer.mud.dev/rhodolite/worlds\",\n },\n },\n iconUrls: [\"https://redstone.xyz/chain-icons/rhodolite.png\"],\n indexerUrl: \"https://indexer.mud.rhodolitechain.com\",\n} as const satisfies MUDChain;\n"],"mappings":";AAAA,SAAS,eAAe;AAGjB,IAAM,aAAa;AAAA,EACxB,GAAG;AAAA,EACH,MAAM;AAAA,IACJ,oBAAoB;AAAA,EACtB;AACF;;;ACRA,SAAS,YAAY,sBAAsB;AAGpC,IAAM,WAAW;AAAA,EACtB,GAAG;AAAA,EACH,UAAU,CAAC,+CAA+C;AAAA,EAC1D,YAAY;AACd;;;ACPA,SAAS,UAAU,oBAAoB;AAGhC,IAAM,SAAS;AAAA,EACpB,GAAG;AAAA,EACH,UAAU,CAAC,6CAA6C;AAAA,EACxD,YAAY;AACd;;;ACPA,SAAS,mBAAmB;AAI5B,IAAM,WAAW;AAEjB,IAAM,iBAAiB;AAAA,EACrB,MAAM,CAAC,gCAAgC;AAAA,EACvC,WAAW,CAAC,8BAA8B;AAC5C;AAEO,IAAM,YAAY;AAAA,EACvB,GAAG;AAAA,EACH,MAAM;AAAA,EACN,SAAS;AAAA,EACT,IAAI;AAAA,EACJ;AAAA,EACA,gBAAgB,EAAE,MAAM,SAAS,QAAQ,OAAO,UAAU,GAAG;AAAA,EAC7D,SAAS;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT,kBAAkB;AAAA,IAClB,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,GAAG,YAAY;AAAA,IACf,kBAAkB;AAAA,MAChB,CAAC,QAAQ,GAAG;AAAA,QACV,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,UAAU,CAAC,gDAAgD;AAAA,EAC3D,YAAY;AACd;","names":[]}
@@ -0,0 +1,64 @@
1
+ // src/resourceTypes.ts
2
+ var resourceTypes = ["table", "offchainTable", "namespace", "system"];
3
+
4
+ // src/resourceToHex.ts
5
+ import { stringToHex, concatHex } from "viem";
6
+ var resourceTypeIds = {
7
+ // keep these in sync with storeResourceTypes.sol
8
+ table: "tb",
9
+ offchainTable: "ot",
10
+ // keep these in sync with worldResourceTypes.sol
11
+ namespace: "ns",
12
+ system: "sy"
13
+ };
14
+ function resourceToHex(resource) {
15
+ const typeId = resourceTypeIds[resource.type];
16
+ if (resource.namespace.length > 14) {
17
+ throw new Error(`Namespaces must fit into \`bytes14\`, but "${resource.namespace}" is too long.`);
18
+ }
19
+ return concatHex([
20
+ stringToHex(typeId, { size: 2 }),
21
+ stringToHex(resource.namespace, { size: 14 }),
22
+ stringToHex(resource.name.slice(0, 16), { size: 16 })
23
+ ]);
24
+ }
25
+
26
+ // src/resourceToLabel.ts
27
+ var rootNamespace = "";
28
+ function resourceToLabel({
29
+ namespace,
30
+ name
31
+ }) {
32
+ return namespace === rootNamespace ? name : `${namespace}__${name}`;
33
+ }
34
+
35
+ // src/hexToResource.ts
36
+ import { hexToString, sliceHex } from "viem";
37
+ var resourceTypeIdToType = Object.fromEntries(
38
+ Object.entries(resourceTypeIds).map(([key, value]) => [value, key])
39
+ );
40
+ function getResourceType(resourceTypeId) {
41
+ const type = resourceTypeIdToType[resourceTypeId];
42
+ if (resourceTypes.includes(type)) {
43
+ return type;
44
+ }
45
+ }
46
+ function hexToResource(hex) {
47
+ const resourceTypeId = hexToString(sliceHex(hex, 0, 2)).replace(/\0+$/, "");
48
+ const type = getResourceType(resourceTypeId);
49
+ const namespace = hexToString(sliceHex(hex, 2, 16)).replace(/\0+$/, "");
50
+ const name = hexToString(sliceHex(hex, 16, 32)).replace(/\0+$/, "");
51
+ if (!type) {
52
+ throw new Error(`Unknown type (${resourceTypeId}) for resource (${resourceToLabel({ namespace, name })})`);
53
+ }
54
+ return { resourceId: hex, type, namespace, name };
55
+ }
56
+
57
+ export {
58
+ resourceTypes,
59
+ resourceTypeIds,
60
+ resourceToHex,
61
+ resourceToLabel,
62
+ hexToResource
63
+ };
64
+ //# sourceMappingURL=chunk-D4GDXAMP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resourceTypes.ts","../src/resourceToHex.ts","../src/resourceToLabel.ts","../src/hexToResource.ts"],"sourcesContent":["export const resourceTypes = [\"table\", \"offchainTable\", \"namespace\", \"system\"] as const;\n\nexport type ResourceType = (typeof resourceTypes)[number];\n","import { Hex, stringToHex, concatHex } from \"viem\";\nimport { Resource } from \"./common\";\nimport { ResourceType } from \"./resourceTypes\";\n\n/** @internal */\nexport const resourceTypeIds = {\n // keep these in sync with storeResourceTypes.sol\n table: \"tb\",\n offchainTable: \"ot\",\n // keep these in sync with worldResourceTypes.sol\n namespace: \"ns\",\n system: \"sy\",\n} as const satisfies Record<ResourceType, string>;\n\nexport function resourceToHex(resource: Omit<Resource, \"resourceId\">): Hex {\n const typeId = resourceTypeIds[resource.type];\n // Because namespaces are tied to access control, it's not safe to automatically truncate. Instead, we'll throw an error.\n if (resource.namespace.length > 14) {\n throw new Error(`Namespaces must fit into \\`bytes14\\`, but \"${resource.namespace}\" is too long.`);\n }\n return concatHex([\n stringToHex(typeId, { size: 2 }),\n stringToHex(resource.namespace, { size: 14 }),\n stringToHex(resource.name.slice(0, 16), { size: 16 }),\n ]);\n}\n","const rootNamespace = \"\";\n\nexport type ResourceLabel<\n namespace extends string = string,\n name extends string = string,\n> = namespace extends typeof rootNamespace ? name : `${namespace}__${name}`;\n\nexport function resourceToLabel<namespace extends string, name extends string>({\n namespace,\n name,\n}: {\n readonly namespace: namespace;\n readonly name: name;\n}): ResourceLabel<namespace, name> {\n return (namespace === rootNamespace ? name : `${namespace}__${name}`) as ResourceLabel<namespace, name>;\n}\n","import { Hex, hexToString, sliceHex } from \"viem\";\nimport { Resource } from \"./common\";\nimport { ResourceType, resourceTypes } from \"./resourceTypes\";\nimport { resourceTypeIds } from \"./resourceToHex\";\nimport { ReverseMap } from \"./type-utils/common\";\nimport { resourceToLabel } from \"./resourceToLabel\";\n\nconst resourceTypeIdToType = Object.fromEntries(\n Object.entries(resourceTypeIds).map(([key, value]) => [value, key]),\n) as ReverseMap<typeof resourceTypeIds>;\n\nfunction getResourceType(resourceTypeId: string): ResourceType | undefined {\n // TODO: replace Partial with `noUncheckedIndexedAccess`\n const type = (resourceTypeIdToType as Partial<Record<string, ResourceType>>)[resourceTypeId];\n if (resourceTypes.includes(type as ResourceType)) {\n return type;\n }\n}\n\nexport function hexToResource(hex: Hex): Resource {\n const resourceTypeId = hexToString(sliceHex(hex, 0, 2)).replace(/\\0+$/, \"\");\n const type = getResourceType(resourceTypeId);\n const namespace = hexToString(sliceHex(hex, 2, 16)).replace(/\\0+$/, \"\");\n const name = hexToString(sliceHex(hex, 16, 32)).replace(/\\0+$/, \"\");\n\n if (!type) {\n throw new Error(`Unknown type (${resourceTypeId}) for resource (${resourceToLabel({ namespace, name })})`);\n }\n\n return { resourceId: hex, type, namespace, name };\n}\n"],"mappings":"AAAO,IAAMA,EAAgB,CAAC,QAAS,gBAAiB,YAAa,QAAQ,ECA7E,OAAc,eAAAC,EAAa,aAAAC,MAAiB,OAKrC,IAAMC,EAAkB,CAE7B,MAAO,KACP,cAAe,KAEf,UAAW,KACX,OAAQ,IACV,EAEO,SAASC,EAAcC,EAA6C,CACzE,IAAMC,EAASH,EAAgBE,EAAS,IAAI,EAE5C,GAAIA,EAAS,UAAU,OAAS,GAC9B,MAAM,IAAI,MAAM,8CAA8CA,EAAS,SAAS,gBAAgB,EAElG,OAAOH,EAAU,CACfD,EAAYK,EAAQ,CAAE,KAAM,CAAE,CAAC,EAC/BL,EAAYI,EAAS,UAAW,CAAE,KAAM,EAAG,CAAC,EAC5CJ,EAAYI,EAAS,KAAK,MAAM,EAAG,EAAE,EAAG,CAAE,KAAM,EAAG,CAAC,CACtD,CAAC,CACH,CCzBA,IAAME,EAAgB,GAOf,SAASC,EAA+D,CAC7E,UAAAC,EACA,KAAAC,CACF,EAGmC,CACjC,OAAQD,IAAcF,EAAgBG,EAAO,GAAGD,CAAS,KAAKC,CAAI,EACpE,CCfA,OAAc,eAAAC,EAAa,YAAAC,MAAgB,OAO3C,IAAMC,EAAuB,OAAO,YAClC,OAAO,QAAQC,CAAe,EAAE,IAAI,CAAC,CAACC,EAAKC,CAAK,IAAM,CAACA,EAAOD,CAAG,CAAC,CACpE,EAEA,SAASE,EAAgBC,EAAkD,CAEzE,IAAMC,EAAQN,EAA+DK,CAAc,EAC3F,GAAIE,EAAc,SAASD,CAAoB,EAC7C,OAAOA,CAEX,CAEO,SAASE,EAAcC,EAAoB,CAChD,IAAMJ,EAAiBK,EAAYC,EAASF,EAAK,EAAG,CAAC,CAAC,EAAE,QAAQ,OAAQ,EAAE,EACpEH,EAAOF,EAAgBC,CAAc,EACrCO,EAAYF,EAAYC,EAASF,EAAK,EAAG,EAAE,CAAC,EAAE,QAAQ,OAAQ,EAAE,EAChEI,EAAOH,EAAYC,EAASF,EAAK,GAAI,EAAE,CAAC,EAAE,QAAQ,OAAQ,EAAE,EAElE,GAAI,CAACH,EACH,MAAM,IAAI,MAAM,iBAAiBD,CAAc,mBAAmBS,EAAgB,CAAE,UAAAF,EAAW,KAAAC,CAAK,CAAC,CAAC,GAAG,EAG3G,MAAO,CAAE,WAAYJ,EAAK,KAAAH,EAAM,UAAAM,EAAW,KAAAC,CAAK,CAClD","names":["resourceTypes","stringToHex","concatHex","resourceTypeIds","resourceToHex","resource","typeId","rootNamespace","resourceToLabel","namespace","name","hexToString","sliceHex","resourceTypeIdToType","resourceTypeIds","key","value","getResourceType","resourceTypeId","type","resourceTypes","hexToResource","hex","hexToString","sliceHex","namespace","name","resourceToLabel"]}
1
+ {"version":3,"sources":["../src/resourceTypes.ts","../src/resourceToHex.ts","../src/resourceToLabel.ts","../src/hexToResource.ts"],"sourcesContent":["export const resourceTypes = [\"table\", \"offchainTable\", \"namespace\", \"system\"] as const;\n\nexport type ResourceType = (typeof resourceTypes)[number];\n","import { Hex, stringToHex, concatHex } from \"viem\";\nimport { Resource } from \"./common\";\nimport { ResourceType } from \"./resourceTypes\";\n\n/** @internal */\nexport const resourceTypeIds = {\n // keep these in sync with storeResourceTypes.sol\n table: \"tb\",\n offchainTable: \"ot\",\n // keep these in sync with worldResourceTypes.sol\n namespace: \"ns\",\n system: \"sy\",\n} as const satisfies Record<ResourceType, string>;\n\nexport function resourceToHex(resource: Omit<Resource, \"resourceId\">): Hex {\n const typeId = resourceTypeIds[resource.type];\n // Because namespaces are tied to access control, it's not safe to automatically truncate. Instead, we'll throw an error.\n if (resource.namespace.length > 14) {\n throw new Error(`Namespaces must fit into \\`bytes14\\`, but \"${resource.namespace}\" is too long.`);\n }\n return concatHex([\n stringToHex(typeId, { size: 2 }),\n stringToHex(resource.namespace, { size: 14 }),\n stringToHex(resource.name.slice(0, 16), { size: 16 }),\n ]);\n}\n","const rootNamespace = \"\";\n\nexport type ResourceLabel<\n namespace extends string = string,\n name extends string = string,\n> = namespace extends typeof rootNamespace ? name : `${namespace}__${name}`;\n\nexport function resourceToLabel<namespace extends string, name extends string>({\n namespace,\n name,\n}: {\n readonly namespace: namespace;\n readonly name: name;\n}): ResourceLabel<namespace, name> {\n return (namespace === rootNamespace ? name : `${namespace}__${name}`) as ResourceLabel<namespace, name>;\n}\n","import { Hex, hexToString, sliceHex } from \"viem\";\nimport { Resource } from \"./common\";\nimport { ResourceType, resourceTypes } from \"./resourceTypes\";\nimport { resourceTypeIds } from \"./resourceToHex\";\nimport { ReverseMap } from \"./type-utils/common\";\nimport { resourceToLabel } from \"./resourceToLabel\";\n\nconst resourceTypeIdToType = Object.fromEntries(\n Object.entries(resourceTypeIds).map(([key, value]) => [value, key]),\n) as ReverseMap<typeof resourceTypeIds>;\n\nfunction getResourceType(resourceTypeId: string): ResourceType | undefined {\n // TODO: replace Partial with `noUncheckedIndexedAccess`\n const type = (resourceTypeIdToType as Partial<Record<string, ResourceType>>)[resourceTypeId];\n if (resourceTypes.includes(type as ResourceType)) {\n return type;\n }\n}\n\nexport function hexToResource(hex: Hex): Resource {\n const resourceTypeId = hexToString(sliceHex(hex, 0, 2)).replace(/\\0+$/, \"\");\n const type = getResourceType(resourceTypeId);\n const namespace = hexToString(sliceHex(hex, 2, 16)).replace(/\\0+$/, \"\");\n const name = hexToString(sliceHex(hex, 16, 32)).replace(/\\0+$/, \"\");\n\n if (!type) {\n throw new Error(`Unknown type (${resourceTypeId}) for resource (${resourceToLabel({ namespace, name })})`);\n }\n\n return { resourceId: hex, type, namespace, name };\n}\n"],"mappings":";AAAO,IAAM,gBAAgB,CAAC,SAAS,iBAAiB,aAAa,QAAQ;;;ACA7E,SAAc,aAAa,iBAAiB;AAKrC,IAAM,kBAAkB;AAAA;AAAA,EAE7B,OAAO;AAAA,EACP,eAAe;AAAA;AAAA,EAEf,WAAW;AAAA,EACX,QAAQ;AACV;AAEO,SAAS,cAAc,UAA6C;AACzE,QAAM,SAAS,gBAAgB,SAAS,IAAI;AAE5C,MAAI,SAAS,UAAU,SAAS,IAAI;AAClC,UAAM,IAAI,MAAM,8CAA8C,SAAS,SAAS,gBAAgB;AAAA,EAClG;AACA,SAAO,UAAU;AAAA,IACf,YAAY,QAAQ,EAAE,MAAM,EAAE,CAAC;AAAA,IAC/B,YAAY,SAAS,WAAW,EAAE,MAAM,GAAG,CAAC;AAAA,IAC5C,YAAY,SAAS,KAAK,MAAM,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC;AAAA,EACtD,CAAC;AACH;;;ACzBA,IAAM,gBAAgB;AAOf,SAAS,gBAA+D;AAAA,EAC7E;AAAA,EACA;AACF,GAGmC;AACjC,SAAQ,cAAc,gBAAgB,OAAO,GAAG,SAAS,KAAK,IAAI;AACpE;;;ACfA,SAAc,aAAa,gBAAgB;AAO3C,IAAM,uBAAuB,OAAO;AAAA,EAClC,OAAO,QAAQ,eAAe,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC;AACpE;AAEA,SAAS,gBAAgB,gBAAkD;AAEzE,QAAM,OAAQ,qBAA+D,cAAc;AAC3F,MAAI,cAAc,SAAS,IAAoB,GAAG;AAChD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,KAAoB;AAChD,QAAM,iBAAiB,YAAY,SAAS,KAAK,GAAG,CAAC,CAAC,EAAE,QAAQ,QAAQ,EAAE;AAC1E,QAAM,OAAO,gBAAgB,cAAc;AAC3C,QAAM,YAAY,YAAY,SAAS,KAAK,GAAG,EAAE,CAAC,EAAE,QAAQ,QAAQ,EAAE;AACtE,QAAM,OAAO,YAAY,SAAS,KAAK,IAAI,EAAE,CAAC,EAAE,QAAQ,QAAQ,EAAE;AAElE,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,iBAAiB,cAAc,mBAAmB,gBAAgB,EAAE,WAAW,KAAK,CAAC,CAAC,GAAG;AAAA,EAC3G;AAEA,SAAO,EAAE,YAAY,KAAK,MAAM,WAAW,KAAK;AAClD;","names":[]}
@@ -0,0 +1,16 @@
1
+ // src/utils/uniqueBy.ts
2
+ function uniqueBy(values, getKey) {
3
+ const map = /* @__PURE__ */ new Map();
4
+ for (const value of values) {
5
+ const key = getKey(value);
6
+ if (!map.has(key)) {
7
+ map.set(key, value);
8
+ }
9
+ }
10
+ return Array.from(map.values());
11
+ }
12
+
13
+ export {
14
+ uniqueBy
15
+ };
16
+ //# sourceMappingURL=chunk-IYZZFDNO.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/uniqueBy.ts"],"sourcesContent":["export function uniqueBy<value, key>(values: readonly value[], getKey: (value: value) => key): readonly value[] {\n const map = new Map<key, value>();\n for (const value of values) {\n const key = getKey(value);\n if (!map.has(key)) {\n map.set(key, value);\n }\n }\n return Array.from(map.values());\n}\n"],"mappings":"AAAO,SAASA,EAAqBC,EAA0BC,EAAiD,CAC9G,IAAMC,EAAM,IAAI,IAChB,QAAWC,KAASH,EAAQ,CAC1B,IAAMI,EAAMH,EAAOE,CAAK,EACnBD,EAAI,IAAIE,CAAG,GACdF,EAAI,IAAIE,EAAKD,CAAK,CAEtB,CACA,OAAO,MAAM,KAAKD,EAAI,OAAO,CAAC,CAChC","names":["uniqueBy","values","getKey","map","value","key"]}
1
+ {"version":3,"sources":["../src/utils/uniqueBy.ts"],"sourcesContent":["export function uniqueBy<value, key>(values: readonly value[], getKey: (value: value) => key): readonly value[] {\n const map = new Map<key, value>();\n for (const value of values) {\n const key = getKey(value);\n if (!map.has(key)) {\n map.set(key, value);\n }\n }\n return Array.from(map.values());\n}\n"],"mappings":";AAAO,SAAS,SAAqB,QAA0B,QAAiD;AAC9G,QAAM,MAAM,oBAAI,IAAgB;AAChC,aAAW,SAAS,QAAQ;AAC1B,UAAM,MAAM,OAAO,KAAK;AACxB,QAAI,CAAC,IAAI,IAAI,GAAG,GAAG;AACjB,UAAI,IAAI,KAAK,KAAK;AAAA,IACpB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI,OAAO,CAAC;AAChC;","names":[]}
@@ -0,0 +1,12 @@
1
+ // src/errors/MUDError.ts
2
+ var MUDError = class extends Error {
3
+ constructor() {
4
+ super(...arguments);
5
+ this.name = "MUDError";
6
+ }
7
+ };
8
+
9
+ export {
10
+ MUDError
11
+ };
12
+ //# sourceMappingURL=chunk-MF5NFUW7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/MUDError.ts"],"sourcesContent":["export class MUDError extends Error {\n name = \"MUDError\";\n}\n"],"mappings":"AAAO,IAAMA,EAAN,cAAuB,KAAM,CAA7B,kCACL,UAAO,WACT","names":["MUDError"]}
1
+ {"version":3,"sources":["../src/errors/MUDError.ts"],"sourcesContent":["export class MUDError extends Error {\n name = \"MUDError\";\n}\n"],"mappings":";AAAO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAA7B;AAAA;AACL,gBAAO;AAAA;AACT;","names":[]}
@@ -0,0 +1,11 @@
1
+ // src/debug.ts
2
+ import createDebug from "debug";
3
+ var debug = createDebug("mud:common");
4
+ var error = createDebug("mud:common");
5
+ debug.log = console.debug.bind(console);
6
+ error.log = console.error.bind(console);
7
+
8
+ export {
9
+ debug
10
+ };
11
+ //# sourceMappingURL=chunk-MK6UECU7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/debug.ts"],"sourcesContent":["import createDebug from \"debug\";\n\nexport const debug = createDebug(\"mud:common\");\nexport const error = createDebug(\"mud:common\");\n\n// Pipe debug output to stdout instead of stderr\ndebug.log = console.debug.bind(console);\n\n// Pipe error output to stderr\nerror.log = console.error.bind(console);\n"],"mappings":"AAAA,OAAOA,MAAiB,QAEjB,IAAMC,EAAQD,EAAY,YAAY,EAChCE,EAAQF,EAAY,YAAY,EAG7CC,EAAM,IAAM,QAAQ,MAAM,KAAK,OAAO,EAGtCC,EAAM,IAAM,QAAQ,MAAM,KAAK,OAAO","names":["createDebug","debug","error"]}
1
+ {"version":3,"sources":["../src/debug.ts"],"sourcesContent":["import createDebug from \"debug\";\n\nexport const debug = createDebug(\"mud:common\");\nexport const error = createDebug(\"mud:common\");\n\n// Pipe debug output to stdout instead of stderr\ndebug.log = console.debug.bind(console);\n\n// Pipe error output to stderr\nerror.log = console.error.bind(console);\n"],"mappings":";AAAA,OAAO,iBAAiB;AAEjB,IAAM,QAAQ,YAAY,YAAY;AACtC,IAAM,QAAQ,YAAY,YAAY;AAG7C,MAAM,MAAM,QAAQ,MAAM,KAAK,OAAO;AAGtC,MAAM,MAAM,QAAQ,MAAM,KAAK,OAAO;","names":[]}
@@ -0,0 +1,208 @@
1
+ import {
2
+ debug
3
+ } from "./chunk-MK6UECU7.js";
4
+
5
+ // src/getNonceManagerId.ts
6
+ import { getAddress } from "viem";
7
+ import { getChainId } from "viem/actions";
8
+ import { getAction } from "viem/utils";
9
+ async function getNonceManagerId({
10
+ client,
11
+ address,
12
+ blockTag
13
+ }) {
14
+ const chainId = client.chain?.id ?? await getAction(client, getChainId, "getChainId")({});
15
+ return `mud:createNonceManager:${chainId}:${getAddress(address)}:${blockTag}`;
16
+ }
17
+
18
+ // src/findCause.ts
19
+ function findCause(error, fn) {
20
+ if (fn?.(error)) return error;
21
+ if (error.cause instanceof Error) return findCause(error.cause, fn);
22
+ return fn ? null : error;
23
+ }
24
+
25
+ // src/createNonceManager.ts
26
+ import { getTransactionCount } from "viem/actions";
27
+ import PQueue from "p-queue";
28
+ import { getAction as getAction2 } from "viem/utils";
29
+ var debug2 = debug.extend("createNonceManager");
30
+ function createNonceManager({
31
+ client,
32
+ address,
33
+ // TODO: rename to account?
34
+ blockTag = "latest",
35
+ broadcastChannelName,
36
+ queueConcurrency = 1
37
+ }) {
38
+ const ref = { nonce: -1, noncePromise: null };
39
+ let channel = null;
40
+ if (typeof BroadcastChannel !== "undefined") {
41
+ const channelName = broadcastChannelName ? Promise.resolve(broadcastChannelName) : getNonceManagerId({ client, address, blockTag });
42
+ channelName.then((name) => {
43
+ channel = new BroadcastChannel(name);
44
+ channel.addEventListener("message", (event) => {
45
+ const nonce = JSON.parse(event.data);
46
+ debug2("got nonce from broadcast channel", nonce);
47
+ ref.nonce = nonce;
48
+ });
49
+ });
50
+ }
51
+ function hasNonce() {
52
+ return ref.nonce >= 0;
53
+ }
54
+ function getNonce() {
55
+ if (!hasNonce()) throw new Error("call resetNonce before using getNonce");
56
+ return ref.nonce;
57
+ }
58
+ function nextNonce() {
59
+ if (!hasNonce()) throw new Error("call resetNonce before using nextNonce");
60
+ const nonce = ref.nonce++;
61
+ channel?.postMessage(JSON.stringify(ref.nonce));
62
+ return nonce;
63
+ }
64
+ async function resetNonce() {
65
+ ref.noncePromise ??= (async () => {
66
+ ref.nonce = await getAction2(client, getTransactionCount, "getTransactionCount")({ address, blockTag });
67
+ ref.noncePromise = null;
68
+ channel?.postMessage(JSON.stringify(ref.nonce));
69
+ debug2("reset nonce to", ref.nonce);
70
+ })();
71
+ await ref.noncePromise;
72
+ }
73
+ function shouldResetNonce(error) {
74
+ const nonceError = findCause(error, ({ name }) => name === "NonceTooLowError" || name === "NonceTooHighError");
75
+ return nonceError != null;
76
+ }
77
+ const mempoolQueue = new PQueue({ concurrency: queueConcurrency });
78
+ return {
79
+ hasNonce,
80
+ getNonce,
81
+ nextNonce,
82
+ resetNonce,
83
+ shouldResetNonce,
84
+ mempoolQueue
85
+ };
86
+ }
87
+
88
+ // src/getNonceManager.ts
89
+ var nonceManagers = /* @__PURE__ */ new Map();
90
+ async function getNonceManager({
91
+ client,
92
+ address,
93
+ // TODO: rename to account?
94
+ blockTag = "latest",
95
+ ...opts
96
+ }) {
97
+ const id = await getNonceManagerId({ client, address, blockTag });
98
+ const nonceManager = nonceManagers.get(id) ?? createNonceManager({ client, address, blockTag, ...opts });
99
+ if (!nonceManagers.has(id)) {
100
+ nonceManagers.set(id, nonceManager);
101
+ }
102
+ if (!nonceManager.hasNonce()) {
103
+ await nonceManager.resetNonce();
104
+ }
105
+ return nonceManager;
106
+ }
107
+
108
+ // src/sendTransaction.ts
109
+ import { sendTransaction as viem_sendTransaction } from "viem/actions";
110
+ import pRetry from "p-retry";
111
+ import { parseAccount } from "viem/accounts";
112
+
113
+ // src/getFeeRef.ts
114
+ import { getChainId as getChainId2 } from "viem/actions";
115
+
116
+ // src/createFeeRef.ts
117
+ import { estimateFeesPerGas } from "viem/actions";
118
+ import { getAction as getAction3 } from "viem/utils";
119
+ async function createFeeRef({ client, args, refreshInterval }) {
120
+ const feeRef = { fees: {}, lastUpdatedTimestamp: 0 };
121
+ async function updateFees() {
122
+ const fees = await getAction3(client, estimateFeesPerGas, "estimateFeesPerGas")(args);
123
+ feeRef.fees = fees;
124
+ feeRef.lastUpdatedTimestamp = Date.now();
125
+ }
126
+ setInterval(updateFees, refreshInterval);
127
+ await updateFees();
128
+ return feeRef;
129
+ }
130
+
131
+ // src/getFeeRef.ts
132
+ import { getAction as getAction4 } from "viem/utils";
133
+ var feeRefs = /* @__PURE__ */ new Map();
134
+ async function getFeeRef(opts) {
135
+ const chainId = opts.args?.chain?.id ?? opts.client.chain?.id ?? await getAction4(opts.client, getChainId2, "getChainId")({});
136
+ const existingFeeRef = feeRefs.get(chainId);
137
+ if (existingFeeRef) {
138
+ return existingFeeRef;
139
+ }
140
+ const feeRef = await createFeeRef(opts);
141
+ feeRefs.set(chainId, feeRef);
142
+ return feeRef;
143
+ }
144
+
145
+ // src/sendTransaction.ts
146
+ import { getAction as getAction5 } from "viem/utils";
147
+ var debug3 = debug.extend("sendTransaction");
148
+ async function sendTransaction(client, request, opts = {}) {
149
+ const rawAccount = request.account ?? client.account;
150
+ if (!rawAccount) {
151
+ throw new Error("No account provided");
152
+ }
153
+ const account = parseAccount(rawAccount);
154
+ const chain = client.chain;
155
+ const nonceManager = await getNonceManager({
156
+ client: opts.publicClient ?? client,
157
+ address: account.address,
158
+ queueConcurrency: opts.queueConcurrency
159
+ });
160
+ const feeRef = await getFeeRef({
161
+ client: opts.publicClient ?? client,
162
+ refreshInterval: 1e4,
163
+ args: { chain }
164
+ });
165
+ return await nonceManager.mempoolQueue.add(
166
+ () => pRetry(
167
+ async () => {
168
+ const nonce = nonceManager.nextNonce();
169
+ const params = {
170
+ // viem_sendTransaction internally estimates gas, which we want to happen on the pending block
171
+ blockTag: "pending",
172
+ ...feeRef.fees,
173
+ ...request,
174
+ nonce
175
+ };
176
+ debug3("sending tx to", request.to, "with nonce", nonce);
177
+ return await getAction5(client, viem_sendTransaction, "sendTransaction")(params);
178
+ },
179
+ {
180
+ retries: 3,
181
+ onFailedAttempt: async (error) => {
182
+ debug3("failed, resetting nonce");
183
+ await nonceManager.resetNonce();
184
+ if (nonceManager.shouldResetNonce(error)) {
185
+ debug3("got nonce error, retrying", error.message);
186
+ return;
187
+ }
188
+ if (String(error).includes("transaction underpriced")) {
189
+ debug3("got transaction underpriced error, retrying", error.message);
190
+ return;
191
+ }
192
+ throw error;
193
+ }
194
+ }
195
+ ),
196
+ { throwOnTimeout: true }
197
+ );
198
+ }
199
+
200
+ export {
201
+ getNonceManagerId,
202
+ findCause,
203
+ createNonceManager,
204
+ getNonceManager,
205
+ getFeeRef,
206
+ sendTransaction
207
+ };
208
+ //# sourceMappingURL=chunk-MYWRXQQH.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/getNonceManagerId.ts","../src/findCause.ts","../src/createNonceManager.ts","../src/getNonceManager.ts","../src/sendTransaction.ts","../src/getFeeRef.ts","../src/createFeeRef.ts"],"sourcesContent":["import { BlockTag, Client, Hex, getAddress } from \"viem\";\nimport { getChainId } from \"viem/actions\";\nimport { getAction } from \"viem/utils\";\n\nexport async function getNonceManagerId({\n client,\n address,\n blockTag,\n}: {\n client: Client;\n address: Hex;\n blockTag: BlockTag;\n}): Promise<string> {\n // TODO: improve this so we don't have to call getChainId every time\n const chainId = client.chain?.id ?? (await getAction(client, getChainId, \"getChainId\")({}));\n return `mud:createNonceManager:${chainId}:${getAddress(address)}:${blockTag}`;\n}\n","export function findCause(error: Error, fn?: (error: Error) => boolean): Error | null {\n if (fn?.(error)) return error;\n if (error.cause instanceof Error) return findCause(error.cause, fn);\n return fn ? null : error;\n}\n","import { BlockTag, Client, Hex } from \"viem\";\nimport { debug as parentDebug } from \"./debug\";\nimport { getNonceManagerId } from \"./getNonceManagerId\";\nimport { getTransactionCount } from \"viem/actions\";\nimport PQueue from \"p-queue\";\nimport { getAction } from \"viem/utils\";\nimport { findCause } from \"./findCause\";\n\nconst debug = parentDebug.extend(\"createNonceManager\");\n\nexport type CreateNonceManagerOptions = {\n client: Client;\n address: Hex;\n blockTag?: BlockTag;\n broadcastChannelName?: string;\n queueConcurrency?: number;\n};\n\nexport type CreateNonceManagerResult = {\n hasNonce: () => boolean;\n getNonce: () => number;\n nextNonce: () => number;\n resetNonce: () => Promise<void>;\n shouldResetNonce: (error: Error) => boolean;\n mempoolQueue: PQueue;\n};\n\nexport function createNonceManager({\n client,\n address, // TODO: rename to account?\n blockTag = \"latest\",\n broadcastChannelName,\n queueConcurrency = 1,\n}: CreateNonceManagerOptions): CreateNonceManagerResult {\n const ref = { nonce: -1, noncePromise: null as Promise<void> | null };\n let channel: BroadcastChannel | null = null;\n\n if (typeof BroadcastChannel !== \"undefined\") {\n const channelName = broadcastChannelName\n ? Promise.resolve(broadcastChannelName)\n : getNonceManagerId({ client, address, blockTag });\n channelName.then((name) => {\n channel = new BroadcastChannel(name);\n // TODO: emit some sort of \"connected\" event so other channels can broadcast current nonce\n channel.addEventListener(\"message\", (event) => {\n const nonce = JSON.parse(event.data);\n debug(\"got nonce from broadcast channel\", nonce);\n ref.nonce = nonce;\n });\n });\n }\n\n function hasNonce(): boolean {\n return ref.nonce >= 0;\n }\n\n function getNonce(): number {\n if (!hasNonce()) throw new Error(\"call resetNonce before using getNonce\");\n return ref.nonce;\n }\n\n function nextNonce(): number {\n if (!hasNonce()) throw new Error(\"call resetNonce before using nextNonce\");\n const nonce = ref.nonce++;\n channel?.postMessage(JSON.stringify(ref.nonce));\n return nonce;\n }\n\n async function resetNonce(): Promise<void> {\n ref.noncePromise ??= (async (): Promise<void> => {\n ref.nonce = await getAction(client, getTransactionCount, \"getTransactionCount\")({ address, blockTag });\n ref.noncePromise = null;\n channel?.postMessage(JSON.stringify(ref.nonce));\n debug(\"reset nonce to\", ref.nonce);\n })();\n await ref.noncePromise;\n }\n\n function shouldResetNonce(error: Error): boolean {\n const nonceError = findCause(error, ({ name }) => name === \"NonceTooLowError\" || name === \"NonceTooHighError\");\n return nonceError != null;\n }\n\n const mempoolQueue = new PQueue({ concurrency: queueConcurrency });\n\n return {\n hasNonce,\n getNonce,\n nextNonce,\n resetNonce,\n shouldResetNonce,\n mempoolQueue,\n };\n}\n","import { CreateNonceManagerOptions, CreateNonceManagerResult, createNonceManager } from \"./createNonceManager\";\nimport { getNonceManagerId } from \"./getNonceManagerId\";\n\nconst nonceManagers = new Map<string, CreateNonceManagerResult>();\n\nexport async function getNonceManager({\n client,\n address, // TODO: rename to account?\n blockTag = \"latest\",\n ...opts\n}: CreateNonceManagerOptions): Promise<CreateNonceManagerResult> {\n const id = await getNonceManagerId({ client, address, blockTag });\n\n const nonceManager = nonceManagers.get(id) ?? createNonceManager({ client, address, blockTag, ...opts });\n if (!nonceManagers.has(id)) {\n nonceManagers.set(id, nonceManager);\n }\n\n if (!nonceManager.hasNonce()) {\n await nonceManager.resetNonce();\n }\n\n return nonceManager;\n}\n","import {\n Account,\n Chain,\n Client,\n SendTransactionParameters,\n Transport,\n SendTransactionReturnType,\n SendTransactionRequest,\n} from \"viem\";\nimport { sendTransaction as viem_sendTransaction } from \"viem/actions\";\nimport pRetry from \"p-retry\";\nimport { debug as parentDebug } from \"./debug\";\nimport { getNonceManager } from \"./getNonceManager\";\nimport { parseAccount } from \"viem/accounts\";\nimport { getFeeRef } from \"./getFeeRef\";\nimport { getAction } from \"viem/utils\";\n\nconst debug = parentDebug.extend(\"sendTransaction\");\n\nexport type SendTransactionExtraOptions<chain extends Chain | undefined> = {\n /**\n * `publicClient` can be provided to be used in place of the extended viem client for making public action calls\n * (`getChainId`, `getTransactionCount`, `call`). This helps in cases where the extended\n * viem client is a smart account client, like in [permissionless.js](https://github.com/pimlicolabs/permissionless.js),\n * where the transport is the bundler, not an RPC.\n */\n publicClient?: Client<Transport, chain>;\n /**\n * Adjust the number of concurrent calls to the mempool. This defaults to `1` to ensure transactions are ordered\n * and nonces are handled properly. Any number greater than that is likely to see nonce errors and/or transactions\n * arriving out of order, but this may be an acceptable trade-off for some applications that can safely retry.\n * @default 1\n */\n queueConcurrency?: number;\n};\n\n/** @deprecated Use `walletClient.extend(transactionQueue())` instead. */\nexport async function sendTransaction<\n chain extends Chain | undefined,\n account extends Account | undefined,\n const request extends SendTransactionRequest<chain, chainOverride>,\n chainOverride extends Chain | undefined = undefined,\n>(\n client: Client<Transport, chain, account>,\n request: SendTransactionParameters<chain, account, chainOverride, request>,\n opts: SendTransactionExtraOptions<chain> = {},\n): Promise<SendTransactionReturnType> {\n const rawAccount = request.account ?? client.account;\n if (!rawAccount) {\n // TODO: replace with viem AccountNotFoundError once its exported\n throw new Error(\"No account provided\");\n }\n const account = parseAccount(rawAccount);\n const chain = client.chain;\n\n const nonceManager = await getNonceManager({\n client: opts.publicClient ?? client,\n address: account.address,\n queueConcurrency: opts.queueConcurrency,\n });\n\n const feeRef = await getFeeRef({\n client: opts.publicClient ?? client,\n refreshInterval: 10000,\n args: { chain },\n });\n\n return await nonceManager.mempoolQueue.add(\n () =>\n pRetry(\n async () => {\n const nonce = nonceManager.nextNonce();\n const params = {\n // viem_sendTransaction internally estimates gas, which we want to happen on the pending block\n blockTag: \"pending\",\n ...feeRef.fees,\n ...request,\n nonce,\n } as const satisfies SendTransactionParameters<chain, account, chainOverride, request>;\n debug(\"sending tx to\", request.to, \"with nonce\", nonce);\n return await getAction(client, viem_sendTransaction, \"sendTransaction\")(params as never);\n },\n {\n retries: 3,\n onFailedAttempt: async (error) => {\n // in case this tx failed before hitting the mempool (i.e. gas estimation error), reset nonce so we don't skip past the unused nonce\n debug(\"failed, resetting nonce\");\n await nonceManager.resetNonce();\n // retry nonce errors\n // TODO: upgrade p-retry and move this to shouldRetry\n if (nonceManager.shouldResetNonce(error)) {\n debug(\"got nonce error, retrying\", error.message);\n return;\n }\n\n if (String(error).includes(\"transaction underpriced\")) {\n debug(\"got transaction underpriced error, retrying\", error.message);\n return;\n }\n\n throw error;\n },\n },\n ),\n { throwOnTimeout: true },\n );\n}\n","import { getChainId } from \"viem/actions\";\nimport { CreateFeeRefOptions, FeeRef, createFeeRef } from \"./createFeeRef\";\nimport { getAction } from \"viem/utils\";\n\nconst feeRefs = new Map<number, FeeRef>();\n\nexport async function getFeeRef(opts: CreateFeeRefOptions): Promise<FeeRef> {\n const chainId =\n opts.args?.chain?.id ?? opts.client.chain?.id ?? (await getAction(opts.client, getChainId, \"getChainId\")({}));\n\n const existingFeeRef = feeRefs.get(chainId);\n if (existingFeeRef) {\n return existingFeeRef;\n }\n\n const feeRef = await createFeeRef(opts);\n feeRefs.set(chainId, feeRef);\n return feeRef;\n}\n","import { EstimateFeesPerGasParameters, Client, EstimateFeesPerGasReturnType } from \"viem\";\nimport { estimateFeesPerGas } from \"viem/actions\";\nimport { getAction } from \"viem/utils\";\n\nexport type CreateFeeRefOptions = {\n client: Client;\n refreshInterval: number;\n args?: EstimateFeesPerGasParameters;\n};\n\nexport type FeeRef = {\n fees: EstimateFeesPerGasReturnType | {};\n lastUpdatedTimestamp: number;\n};\n\n/** Update fee values once every `refreshInterval` instead of right before every request */\nexport async function createFeeRef({ client, args, refreshInterval }: CreateFeeRefOptions): Promise<FeeRef> {\n const feeRef: FeeRef = { fees: {}, lastUpdatedTimestamp: 0 };\n\n async function updateFees(): Promise<void> {\n const fees = await getAction(client, estimateFeesPerGas, \"estimateFeesPerGas\")(args);\n feeRef.fees = fees;\n feeRef.lastUpdatedTimestamp = Date.now();\n }\n\n setInterval(updateFees, refreshInterval);\n await updateFees();\n\n return feeRef;\n}\n"],"mappings":"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","names":["getAddress","getChainId","getAction","getNonceManagerId","client","address","blockTag","findCause","error","fn","getTransactionCount","PQueue","getAction","debug","createNonceManager","client","address","blockTag","broadcastChannelName","queueConcurrency","ref","channel","getNonceManagerId","name","event","nonce","hasNonce","getNonce","nextNonce","resetNonce","getAction","getTransactionCount","shouldResetNonce","error","findCause","mempoolQueue","PQueue","nonceManagers","getNonceManager","client","address","blockTag","opts","id","getNonceManagerId","nonceManager","createNonceManager","viem_sendTransaction","pRetry","parseAccount","getChainId","estimateFeesPerGas","getAction","createFeeRef","client","args","refreshInterval","feeRef","updateFees","fees","getAction","feeRefs","getFeeRef","opts","chainId","getChainId","existingFeeRef","feeRef","createFeeRef","getAction","debug","sendTransaction","client","request","opts","rawAccount","account","parseAccount","chain","nonceManager","getNonceManager","feeRef","getFeeRef","pRetry","nonce","params","viem_sendTransaction","error"]}
1
+ {"version":3,"sources":["../src/getNonceManagerId.ts","../src/findCause.ts","../src/createNonceManager.ts","../src/getNonceManager.ts","../src/sendTransaction.ts","../src/getFeeRef.ts","../src/createFeeRef.ts"],"sourcesContent":["import { BlockTag, Client, Hex, getAddress } from \"viem\";\nimport { getChainId } from \"viem/actions\";\nimport { getAction } from \"viem/utils\";\n\nexport async function getNonceManagerId({\n client,\n address,\n blockTag,\n}: {\n client: Client;\n address: Hex;\n blockTag: BlockTag;\n}): Promise<string> {\n // TODO: improve this so we don't have to call getChainId every time\n const chainId = client.chain?.id ?? (await getAction(client, getChainId, \"getChainId\")({}));\n return `mud:createNonceManager:${chainId}:${getAddress(address)}:${blockTag}`;\n}\n","export function findCause(error: Error, fn?: (error: Error) => boolean): Error | null {\n if (fn?.(error)) return error;\n if (error.cause instanceof Error) return findCause(error.cause, fn);\n return fn ? null : error;\n}\n","import { BlockTag, Client, Hex } from \"viem\";\nimport { debug as parentDebug } from \"./debug\";\nimport { getNonceManagerId } from \"./getNonceManagerId\";\nimport { getTransactionCount } from \"viem/actions\";\nimport PQueue from \"p-queue\";\nimport { getAction } from \"viem/utils\";\nimport { findCause } from \"./findCause\";\n\nconst debug = parentDebug.extend(\"createNonceManager\");\n\nexport type CreateNonceManagerOptions = {\n client: Client;\n address: Hex;\n blockTag?: BlockTag;\n broadcastChannelName?: string;\n queueConcurrency?: number;\n};\n\nexport type CreateNonceManagerResult = {\n hasNonce: () => boolean;\n getNonce: () => number;\n nextNonce: () => number;\n resetNonce: () => Promise<void>;\n shouldResetNonce: (error: Error) => boolean;\n mempoolQueue: PQueue;\n};\n\nexport function createNonceManager({\n client,\n address, // TODO: rename to account?\n blockTag = \"latest\",\n broadcastChannelName,\n queueConcurrency = 1,\n}: CreateNonceManagerOptions): CreateNonceManagerResult {\n const ref = { nonce: -1, noncePromise: null as Promise<void> | null };\n let channel: BroadcastChannel | null = null;\n\n if (typeof BroadcastChannel !== \"undefined\") {\n const channelName = broadcastChannelName\n ? Promise.resolve(broadcastChannelName)\n : getNonceManagerId({ client, address, blockTag });\n channelName.then((name) => {\n channel = new BroadcastChannel(name);\n // TODO: emit some sort of \"connected\" event so other channels can broadcast current nonce\n channel.addEventListener(\"message\", (event) => {\n const nonce = JSON.parse(event.data);\n debug(\"got nonce from broadcast channel\", nonce);\n ref.nonce = nonce;\n });\n });\n }\n\n function hasNonce(): boolean {\n return ref.nonce >= 0;\n }\n\n function getNonce(): number {\n if (!hasNonce()) throw new Error(\"call resetNonce before using getNonce\");\n return ref.nonce;\n }\n\n function nextNonce(): number {\n if (!hasNonce()) throw new Error(\"call resetNonce before using nextNonce\");\n const nonce = ref.nonce++;\n channel?.postMessage(JSON.stringify(ref.nonce));\n return nonce;\n }\n\n async function resetNonce(): Promise<void> {\n ref.noncePromise ??= (async (): Promise<void> => {\n ref.nonce = await getAction(client, getTransactionCount, \"getTransactionCount\")({ address, blockTag });\n ref.noncePromise = null;\n channel?.postMessage(JSON.stringify(ref.nonce));\n debug(\"reset nonce to\", ref.nonce);\n })();\n await ref.noncePromise;\n }\n\n function shouldResetNonce(error: Error): boolean {\n const nonceError = findCause(error, ({ name }) => name === \"NonceTooLowError\" || name === \"NonceTooHighError\");\n return nonceError != null;\n }\n\n const mempoolQueue = new PQueue({ concurrency: queueConcurrency });\n\n return {\n hasNonce,\n getNonce,\n nextNonce,\n resetNonce,\n shouldResetNonce,\n mempoolQueue,\n };\n}\n","import { CreateNonceManagerOptions, CreateNonceManagerResult, createNonceManager } from \"./createNonceManager\";\nimport { getNonceManagerId } from \"./getNonceManagerId\";\n\nconst nonceManagers = new Map<string, CreateNonceManagerResult>();\n\nexport async function getNonceManager({\n client,\n address, // TODO: rename to account?\n blockTag = \"latest\",\n ...opts\n}: CreateNonceManagerOptions): Promise<CreateNonceManagerResult> {\n const id = await getNonceManagerId({ client, address, blockTag });\n\n const nonceManager = nonceManagers.get(id) ?? createNonceManager({ client, address, blockTag, ...opts });\n if (!nonceManagers.has(id)) {\n nonceManagers.set(id, nonceManager);\n }\n\n if (!nonceManager.hasNonce()) {\n await nonceManager.resetNonce();\n }\n\n return nonceManager;\n}\n","import {\n Account,\n Chain,\n Client,\n SendTransactionParameters,\n Transport,\n SendTransactionReturnType,\n SendTransactionRequest,\n} from \"viem\";\nimport { sendTransaction as viem_sendTransaction } from \"viem/actions\";\nimport pRetry from \"p-retry\";\nimport { debug as parentDebug } from \"./debug\";\nimport { getNonceManager } from \"./getNonceManager\";\nimport { parseAccount } from \"viem/accounts\";\nimport { getFeeRef } from \"./getFeeRef\";\nimport { getAction } from \"viem/utils\";\n\nconst debug = parentDebug.extend(\"sendTransaction\");\n\nexport type SendTransactionExtraOptions<chain extends Chain | undefined> = {\n /**\n * `publicClient` can be provided to be used in place of the extended viem client for making public action calls\n * (`getChainId`, `getTransactionCount`, `call`). This helps in cases where the extended\n * viem client is a smart account client, like in [permissionless.js](https://github.com/pimlicolabs/permissionless.js),\n * where the transport is the bundler, not an RPC.\n */\n publicClient?: Client<Transport, chain>;\n /**\n * Adjust the number of concurrent calls to the mempool. This defaults to `1` to ensure transactions are ordered\n * and nonces are handled properly. Any number greater than that is likely to see nonce errors and/or transactions\n * arriving out of order, but this may be an acceptable trade-off for some applications that can safely retry.\n * @default 1\n */\n queueConcurrency?: number;\n};\n\n/** @deprecated Use `walletClient.extend(transactionQueue())` instead. */\nexport async function sendTransaction<\n chain extends Chain | undefined,\n account extends Account | undefined,\n const request extends SendTransactionRequest<chain, chainOverride>,\n chainOverride extends Chain | undefined = undefined,\n>(\n client: Client<Transport, chain, account>,\n request: SendTransactionParameters<chain, account, chainOverride, request>,\n opts: SendTransactionExtraOptions<chain> = {},\n): Promise<SendTransactionReturnType> {\n const rawAccount = request.account ?? client.account;\n if (!rawAccount) {\n // TODO: replace with viem AccountNotFoundError once its exported\n throw new Error(\"No account provided\");\n }\n const account = parseAccount(rawAccount);\n const chain = client.chain;\n\n const nonceManager = await getNonceManager({\n client: opts.publicClient ?? client,\n address: account.address,\n queueConcurrency: opts.queueConcurrency,\n });\n\n const feeRef = await getFeeRef({\n client: opts.publicClient ?? client,\n refreshInterval: 10000,\n args: { chain },\n });\n\n return await nonceManager.mempoolQueue.add(\n () =>\n pRetry(\n async () => {\n const nonce = nonceManager.nextNonce();\n const params = {\n // viem_sendTransaction internally estimates gas, which we want to happen on the pending block\n blockTag: \"pending\",\n ...feeRef.fees,\n ...request,\n nonce,\n } as const satisfies SendTransactionParameters<chain, account, chainOverride, request>;\n debug(\"sending tx to\", request.to, \"with nonce\", nonce);\n return await getAction(client, viem_sendTransaction, \"sendTransaction\")(params as never);\n },\n {\n retries: 3,\n onFailedAttempt: async (error) => {\n // in case this tx failed before hitting the mempool (i.e. gas estimation error), reset nonce so we don't skip past the unused nonce\n debug(\"failed, resetting nonce\");\n await nonceManager.resetNonce();\n // retry nonce errors\n // TODO: upgrade p-retry and move this to shouldRetry\n if (nonceManager.shouldResetNonce(error)) {\n debug(\"got nonce error, retrying\", error.message);\n return;\n }\n\n if (String(error).includes(\"transaction underpriced\")) {\n debug(\"got transaction underpriced error, retrying\", error.message);\n return;\n }\n\n throw error;\n },\n },\n ),\n { throwOnTimeout: true },\n );\n}\n","import { getChainId } from \"viem/actions\";\nimport { CreateFeeRefOptions, FeeRef, createFeeRef } from \"./createFeeRef\";\nimport { getAction } from \"viem/utils\";\n\nconst feeRefs = new Map<number, FeeRef>();\n\nexport async function getFeeRef(opts: CreateFeeRefOptions): Promise<FeeRef> {\n const chainId =\n opts.args?.chain?.id ?? opts.client.chain?.id ?? (await getAction(opts.client, getChainId, \"getChainId\")({}));\n\n const existingFeeRef = feeRefs.get(chainId);\n if (existingFeeRef) {\n return existingFeeRef;\n }\n\n const feeRef = await createFeeRef(opts);\n feeRefs.set(chainId, feeRef);\n return feeRef;\n}\n","import { EstimateFeesPerGasParameters, Client, EstimateFeesPerGasReturnType } from \"viem\";\nimport { estimateFeesPerGas } from \"viem/actions\";\nimport { getAction } from \"viem/utils\";\n\nexport type CreateFeeRefOptions = {\n client: Client;\n refreshInterval: number;\n args?: EstimateFeesPerGasParameters;\n};\n\nexport type FeeRef = {\n fees: EstimateFeesPerGasReturnType | {};\n lastUpdatedTimestamp: number;\n};\n\n/** Update fee values once every `refreshInterval` instead of right before every request */\nexport async function createFeeRef({ client, args, refreshInterval }: CreateFeeRefOptions): Promise<FeeRef> {\n const feeRef: FeeRef = { fees: {}, lastUpdatedTimestamp: 0 };\n\n async function updateFees(): Promise<void> {\n const fees = await getAction(client, estimateFeesPerGas, \"estimateFeesPerGas\")(args);\n feeRef.fees = fees;\n feeRef.lastUpdatedTimestamp = Date.now();\n }\n\n setInterval(updateFees, refreshInterval);\n await updateFees();\n\n return feeRef;\n}\n"],"mappings":";;;;;AAAA,SAAgC,kBAAkB;AAClD,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAE1B,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIoB;AAElB,QAAM,UAAU,OAAO,OAAO,MAAO,MAAM,UAAU,QAAQ,YAAY,YAAY,EAAE,CAAC,CAAC;AACzF,SAAO,0BAA0B,OAAO,IAAI,WAAW,OAAO,CAAC,IAAI,QAAQ;AAC7E;;;AChBO,SAAS,UAAU,OAAc,IAA8C;AACpF,MAAI,KAAK,KAAK,EAAG,QAAO;AACxB,MAAI,MAAM,iBAAiB,MAAO,QAAO,UAAU,MAAM,OAAO,EAAE;AAClE,SAAO,KAAK,OAAO;AACrB;;;ACDA,SAAS,2BAA2B;AACpC,OAAO,YAAY;AACnB,SAAS,aAAAA,kBAAiB;AAG1B,IAAMC,SAAQ,MAAY,OAAO,oBAAoB;AAmB9C,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,mBAAmB;AACrB,GAAwD;AACtD,QAAM,MAAM,EAAE,OAAO,IAAI,cAAc,KAA6B;AACpE,MAAI,UAAmC;AAEvC,MAAI,OAAO,qBAAqB,aAAa;AAC3C,UAAM,cAAc,uBAChB,QAAQ,QAAQ,oBAAoB,IACpC,kBAAkB,EAAE,QAAQ,SAAS,SAAS,CAAC;AACnD,gBAAY,KAAK,CAAC,SAAS;AACzB,gBAAU,IAAI,iBAAiB,IAAI;AAEnC,cAAQ,iBAAiB,WAAW,CAAC,UAAU;AAC7C,cAAM,QAAQ,KAAK,MAAM,MAAM,IAAI;AACnC,QAAAA,OAAM,oCAAoC,KAAK;AAC/C,YAAI,QAAQ;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,WAAS,WAAoB;AAC3B,WAAO,IAAI,SAAS;AAAA,EACtB;AAEA,WAAS,WAAmB;AAC1B,QAAI,CAAC,SAAS,EAAG,OAAM,IAAI,MAAM,uCAAuC;AACxE,WAAO,IAAI;AAAA,EACb;AAEA,WAAS,YAAoB;AAC3B,QAAI,CAAC,SAAS,EAAG,OAAM,IAAI,MAAM,wCAAwC;AACzE,UAAM,QAAQ,IAAI;AAClB,aAAS,YAAY,KAAK,UAAU,IAAI,KAAK,CAAC;AAC9C,WAAO;AAAA,EACT;AAEA,iBAAe,aAA4B;AACzC,QAAI,kBAAkB,YAA2B;AAC/C,UAAI,QAAQ,MAAMC,WAAU,QAAQ,qBAAqB,qBAAqB,EAAE,EAAE,SAAS,SAAS,CAAC;AACrG,UAAI,eAAe;AACnB,eAAS,YAAY,KAAK,UAAU,IAAI,KAAK,CAAC;AAC9C,MAAAD,OAAM,kBAAkB,IAAI,KAAK;AAAA,IACnC,GAAG;AACH,UAAM,IAAI;AAAA,EACZ;AAEA,WAAS,iBAAiB,OAAuB;AAC/C,UAAM,aAAa,UAAU,OAAO,CAAC,EAAE,KAAK,MAAM,SAAS,sBAAsB,SAAS,mBAAmB;AAC7G,WAAO,cAAc;AAAA,EACvB;AAEA,QAAM,eAAe,IAAI,OAAO,EAAE,aAAa,iBAAiB,CAAC;AAEjE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC1FA,IAAM,gBAAgB,oBAAI,IAAsC;AAEhE,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA;AAAA;AAAA,EACA,WAAW;AAAA,EACX,GAAG;AACL,GAAiE;AAC/D,QAAM,KAAK,MAAM,kBAAkB,EAAE,QAAQ,SAAS,SAAS,CAAC;AAEhE,QAAM,eAAe,cAAc,IAAI,EAAE,KAAK,mBAAmB,EAAE,QAAQ,SAAS,UAAU,GAAG,KAAK,CAAC;AACvG,MAAI,CAAC,cAAc,IAAI,EAAE,GAAG;AAC1B,kBAAc,IAAI,IAAI,YAAY;AAAA,EACpC;AAEA,MAAI,CAAC,aAAa,SAAS,GAAG;AAC5B,UAAM,aAAa,WAAW;AAAA,EAChC;AAEA,SAAO;AACT;;;ACdA,SAAS,mBAAmB,4BAA4B;AACxD,OAAO,YAAY;AAGnB,SAAS,oBAAoB;;;ACb7B,SAAS,cAAAE,mBAAkB;;;ACC3B,SAAS,0BAA0B;AACnC,SAAS,aAAAC,kBAAiB;AAc1B,eAAsB,aAAa,EAAE,QAAQ,MAAM,gBAAgB,GAAyC;AAC1G,QAAM,SAAiB,EAAE,MAAM,CAAC,GAAG,sBAAsB,EAAE;AAE3D,iBAAe,aAA4B;AACzC,UAAM,OAAO,MAAMA,WAAU,QAAQ,oBAAoB,oBAAoB,EAAE,IAAI;AACnF,WAAO,OAAO;AACd,WAAO,uBAAuB,KAAK,IAAI;AAAA,EACzC;AAEA,cAAY,YAAY,eAAe;AACvC,QAAM,WAAW;AAEjB,SAAO;AACT;;;AD3BA,SAAS,aAAAC,kBAAiB;AAE1B,IAAM,UAAU,oBAAI,IAAoB;AAExC,eAAsB,UAAU,MAA4C;AAC1E,QAAM,UACJ,KAAK,MAAM,OAAO,MAAM,KAAK,OAAO,OAAO,MAAO,MAAMA,WAAU,KAAK,QAAQC,aAAY,YAAY,EAAE,CAAC,CAAC;AAE7G,QAAM,iBAAiB,QAAQ,IAAI,OAAO;AAC1C,MAAI,gBAAgB;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,aAAa,IAAI;AACtC,UAAQ,IAAI,SAAS,MAAM;AAC3B,SAAO;AACT;;;ADHA,SAAS,aAAAC,kBAAiB;AAE1B,IAAMC,SAAQ,MAAY,OAAO,iBAAiB;AAoBlD,eAAsB,gBAMpB,QACA,SACA,OAA2C,CAAC,GACR;AACpC,QAAM,aAAa,QAAQ,WAAW,OAAO;AAC7C,MAAI,CAAC,YAAY;AAEf,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AACA,QAAM,UAAU,aAAa,UAAU;AACvC,QAAM,QAAQ,OAAO;AAErB,QAAM,eAAe,MAAM,gBAAgB;AAAA,IACzC,QAAQ,KAAK,gBAAgB;AAAA,IAC7B,SAAS,QAAQ;AAAA,IACjB,kBAAkB,KAAK;AAAA,EACzB,CAAC;AAED,QAAM,SAAS,MAAM,UAAU;AAAA,IAC7B,QAAQ,KAAK,gBAAgB;AAAA,IAC7B,iBAAiB;AAAA,IACjB,MAAM,EAAE,MAAM;AAAA,EAChB,CAAC;AAED,SAAO,MAAM,aAAa,aAAa;AAAA,IACrC,MACE;AAAA,MACE,YAAY;AACV,cAAM,QAAQ,aAAa,UAAU;AACrC,cAAM,SAAS;AAAA;AAAA,UAEb,UAAU;AAAA,UACV,GAAG,OAAO;AAAA,UACV,GAAG;AAAA,UACH;AAAA,QACF;AACA,QAAAA,OAAM,iBAAiB,QAAQ,IAAI,cAAc,KAAK;AACtD,eAAO,MAAMD,WAAU,QAAQ,sBAAsB,iBAAiB,EAAE,MAAe;AAAA,MACzF;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,iBAAiB,OAAO,UAAU;AAEhC,UAAAC,OAAM,yBAAyB;AAC/B,gBAAM,aAAa,WAAW;AAG9B,cAAI,aAAa,iBAAiB,KAAK,GAAG;AACxC,YAAAA,OAAM,6BAA6B,MAAM,OAAO;AAChD;AAAA,UACF;AAEA,cAAI,OAAO,KAAK,EAAE,SAAS,yBAAyB,GAAG;AACrD,YAAAA,OAAM,+CAA+C,MAAM,OAAO;AAClE;AAAA,UACF;AAEA,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,IACF,EAAE,gBAAgB,KAAK;AAAA,EACzB;AACF;","names":["getAction","debug","getAction","getChainId","getAction","getAction","getChainId","getAction","debug"]}
@@ -0,0 +1,70 @@
1
+ import {
2
+ getFeeRef,
3
+ getNonceManager
4
+ } from "./chunk-MYWRXQQH.js";
5
+ import {
6
+ debug
7
+ } from "./chunk-MK6UECU7.js";
8
+
9
+ // src/writeContract.ts
10
+ import { writeContract as viem_writeContract } from "viem/actions";
11
+ import pRetry from "p-retry";
12
+ import { parseAccount } from "viem/accounts";
13
+ import { getAction } from "viem/utils";
14
+ var debug2 = debug.extend("writeContract");
15
+ async function writeContract(client, request, opts = {}) {
16
+ const rawAccount = request.account ?? client.account;
17
+ if (!rawAccount) {
18
+ throw new Error("No account provided");
19
+ }
20
+ const account = parseAccount(rawAccount);
21
+ const chain = client.chain;
22
+ const nonceManager = await getNonceManager({
23
+ client: opts.publicClient ?? client,
24
+ address: account.address,
25
+ queueConcurrency: opts.queueConcurrency
26
+ });
27
+ const feeRef = await getFeeRef({
28
+ client: opts.publicClient ?? client,
29
+ refreshInterval: 1e4,
30
+ args: { chain }
31
+ });
32
+ return nonceManager.mempoolQueue.add(
33
+ () => pRetry(
34
+ async () => {
35
+ const nonce = nonceManager.nextNonce();
36
+ const params = {
37
+ // viem_writeContract internally estimates gas, which we want to happen on the pending block
38
+ blockTag: "pending",
39
+ ...feeRef.fees,
40
+ ...request,
41
+ nonce
42
+ };
43
+ debug2("calling", params.functionName, "at", params.address, "with nonce", nonce);
44
+ return await getAction(client, viem_writeContract, "writeContract")(params);
45
+ },
46
+ {
47
+ retries: 3,
48
+ onFailedAttempt: async (error) => {
49
+ debug2("failed, resetting nonce");
50
+ await nonceManager.resetNonce();
51
+ if (nonceManager.shouldResetNonce(error)) {
52
+ debug2("got nonce error, retrying", error.message);
53
+ return;
54
+ }
55
+ if (String(error).includes("transaction underpriced")) {
56
+ debug2("got transaction underpriced error, retrying", error.message);
57
+ return;
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ ),
63
+ { throwOnTimeout: true }
64
+ );
65
+ }
66
+
67
+ export {
68
+ writeContract
69
+ };
70
+ //# sourceMappingURL=chunk-Z6SVAIZN.js.map