@xyo-network/chain-bridge 1.20.1 → 1.20.2

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 (24) hide show
  1. package/dist/node/index.mjs +55 -27
  2. package/dist/node/index.mjs.map +1 -1
  3. package/dist/node/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.d.ts.map +1 -0
  4. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts +14 -0
  5. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts.map +1 -0
  6. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.d.ts +4 -0
  7. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.d.ts.map +1 -0
  8. package/dist/node/queue/flows/createXl1ToEthBridgeJob/index.d.ts +4 -0
  9. package/dist/node/queue/flows/createXl1ToEthBridgeJob/index.d.ts.map +1 -0
  10. package/dist/node/queue/flows/index.d.ts +1 -1
  11. package/dist/node/queue/flows/index.d.ts.map +1 -1
  12. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.d.ts +27 -27
  13. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.d.ts.map +1 -1
  14. package/dist/node/validation/validateBridgeTransaction.d.ts.map +1 -1
  15. package/package.json +13 -13
  16. package/src/queue/flows/{createXl1ToEthBridgeJob.ts → createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.ts} +3 -3
  17. package/src/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.ts +18 -0
  18. package/src/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.ts +11 -0
  19. package/src/queue/flows/createXl1ToEthBridgeJob/index.ts +3 -0
  20. package/src/queue/flows/index.ts +1 -1
  21. package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts +13 -3
  22. package/src/validation/validateBridgeTransaction.ts +14 -6
  23. package/dist/node/queue/flows/createXl1ToEthBridgeJob.d.ts.map +0 -1
  24. /package/dist/node/queue/flows/{createXl1ToEthBridgeJob.d.ts → createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createXl1ToEthBridgeJob.d.ts","sourceRoot":"","sources":["../../../../../src/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAQ1C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,cAAc,YAAY,EAC1B,IAAI,yBAAyB,sCA+F9B,CAAA"}
@@ -0,0 +1,14 @@
1
+ import type { SignedHydratedTransaction } from '@xyo-network/xl1-sdk';
2
+ /**
3
+ * Returns a deterministic & repeatable job ID based off the Transaction hash. This is to ensure
4
+ * that if the same transaction is attempted to be bridged multiple times, it will have the same
5
+ * job ID and not create duplicate jobs.
6
+ * https://docs.bullmq.io/guide/jobs/job-ids
7
+ * "The main reason to be able to specify a custom id is in cases when you want to avoid duplicated
8
+ * jobs. Since ids must be unique, if you add a job with an existing id then that job will just be
9
+ * ignored and not added to the queue at all."
10
+ * @param tx The transaction to bridge from XL1 to ETH
11
+ * @returns A deterministic job ID for the bridge job
12
+ */
13
+ export declare const getJobIdForXl1ToEthBridgeJob: (tx: SignedHydratedTransaction) => Promise<import("@xylabs/hex").BrandedHash>;
14
+ //# sourceMappingURL=getJobIdForXl1ToEthBridgeJob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getJobIdForXl1ToEthBridgeJob.d.ts","sourceRoot":"","sources":["../../../../../src/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAErE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GAAU,IAAI,yBAAyB,+CAG/E,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { SignedHydratedTransaction } from '@xyo-network/xl1-sdk';
2
+ import type { FlowProducer } from 'bullmq';
3
+ export declare const getXl1ToEthBridgeJob: (flowProducer: FlowProducer, tx: SignedHydratedTransaction) => Promise<import("bullmq").JobNode>;
4
+ //# sourceMappingURL=getXl1ToEthBridgeJob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getXl1ToEthBridgeJob.d.ts","sourceRoot":"","sources":["../../../../../src/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAK1C,eAAO,MAAM,oBAAoB,GAAU,cAAc,YAAY,EAAE,IAAI,yBAAyB,sCAInG,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './createXl1ToEthBridgeJob.ts';
2
+ export * from './getJobIdForXl1ToEthBridgeJob.ts';
3
+ export * from './getXl1ToEthBridgeJob.ts';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/queue/flows/createXl1ToEthBridgeJob/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,mCAAmC,CAAA;AACjD,cAAc,2BAA2B,CAAA"}
@@ -1,3 +1,3 @@
1
1
  export * from './createEthToXl1BridgeJob.ts';
2
- export * from './createXl1ToEthBridgeJob.ts';
2
+ export * from './createXl1ToEthBridgeJob/index.ts';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/queue/flows/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,8BAA8B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/queue/flows/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oCAAoC,CAAA"}
@@ -10,25 +10,25 @@ export declare const BridgeToRemoteBodyZod: z.ZodTuple<[z.ZodObject<{
10
10
  } & {
11
11
  readonly __address: true;
12
12
  }, string>>>;
13
- payload_hashes: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHash, string>>>;
13
+ payload_hashes: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHash, string>>>;
14
14
  payload_schemas: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xyo-network/sdk-js").BrandedSchema<string>, string>>>;
15
- previous_hashes: z.ZodArray<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHash, string>>>>;
15
+ previous_hashes: z.ZodArray<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHash, string>>>>;
16
16
  $destination: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<Lowercase<string> & {
17
17
  readonly __hex: true;
18
18
  } & {
19
19
  readonly __address: true;
20
20
  }, string>>>;
21
- $sourceQuery: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHash, string>>>;
22
- $signatures: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>>;
21
+ $sourceQuery: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHash, string>>>;
22
+ $signatures: z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>>;
23
23
  nbf: z.ZodPipe<z.ZodNumber, z.ZodTransform<import("@xyo-network/xl1-sdk").XL1BlockNumber, number>>;
24
24
  exp: z.ZodPipe<z.ZodNumber, z.ZodTransform<import("@xyo-network/xl1-sdk").XL1BlockNumber, number>>;
25
25
  fees: z.ZodObject<{
26
- base: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
27
- gasLimit: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
28
- gasPrice: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
29
- priority: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
26
+ base: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
27
+ gasLimit: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
28
+ gasPrice: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
29
+ priority: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
30
30
  }, z.core.$strip>;
31
- chain: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
31
+ chain: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
32
32
  from: z.ZodPipe<z.ZodString, z.ZodTransform<Lowercase<string> & {
33
33
  readonly __hex: true;
34
34
  } & {
@@ -39,14 +39,14 @@ export declare const BridgeToRemoteBodyZod: z.ZodTuple<[z.ZodObject<{
39
39
  schema: z.ZodLiteral<"network.xyo.chain.bridge.intent" & {
40
40
  readonly __schema: true;
41
41
  }>;
42
- src: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
43
- srcAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
44
- srcAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
45
- srcToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
46
- dest: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
47
- destAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
48
- destAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
49
- destToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
42
+ src: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
43
+ srcAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
44
+ srcAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
45
+ srcToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
46
+ dest: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
47
+ destAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
48
+ destAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
49
+ destToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
50
50
  nonce: z.ZodString;
51
51
  }, z.core.$strict>, z.ZodObject<{
52
52
  schema: z.ZodLiteral<"network.xyo.transfer" & {
@@ -63,22 +63,22 @@ export declare const BridgeToRemoteBodyZod: z.ZodTuple<[z.ZodObject<{
63
63
  readonly __hex: true;
64
64
  } & {
65
65
  readonly __address: true;
66
- }, string>>, z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>>;
66
+ }, string>>, z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>>;
67
67
  }, z.core.$strip>], null>;
68
68
  export type BridgeToRemoteBody = z.infer<typeof BridgeToRemoteBodyZod>;
69
69
  export declare const BridgeToRemoteResponseZod: z.ZodObject<{
70
70
  schema: z.ZodLiteral<"network.xyo.chain.bridge.observation.source" & {
71
71
  readonly __schema: true;
72
72
  }>;
73
- src: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
74
- srcAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
75
- srcAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
76
- srcToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
77
- dest: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
78
- destAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
79
- destAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
80
- destToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>;
81
- srcConfirmation: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/hex").BrandedHex, string>>>;
73
+ src: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
74
+ srcAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
75
+ srcAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
76
+ srcToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
77
+ dest: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
78
+ destAddress: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
79
+ destAmount: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
80
+ destToken: z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>;
81
+ srcConfirmation: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@xylabs/sdk-js").BrandedHex, string>>>;
82
82
  }, z.core.$strict>;
83
83
  export type BridgeToRemoteResponse = z.infer<typeof BridgeToRemoteResponseZod>;
84
84
  export declare const makeBridgeToRemoteRoute: (config: BridgeConfig) => RouteDefinition;
@@ -1 +1 @@
1
- {"version":3,"file":"bridgeToRemote.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAUpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQvB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAIhC,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;kBAAyG,CAAA;AAC/I,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE9E,eAAO,MAAM,uBAAuB,GAAI,QAAQ,YAAY,KAAG,eAoD9D,CAAA"}
1
+ {"version":3,"file":"bridgeToRemote.d.ts","sourceRoot":"","sources":["../../../../../../../src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAUpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQvB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAIhC,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;kBAAyG,CAAA;AAC/I,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE9E,eAAO,MAAM,uBAAuB,GAAI,QAAQ,YAAY,KAAG,eA6D9D,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"validateBridgeTransaction.d.ts","sourceRoot":"","sources":["../../../src/validation/validateBridgeTransaction.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEpE,OAAO,KAAK,EACV,YAAY,EAAE,uBAAuB,EAAE,QAAQ,EAChD,MAAM,sBAAsB,CAAA;AAI7B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,GACpC,YAAY,uBAAuB,EACnC,QAAQ,YAAY,EACpB,UAAU,QAAQ,EAClB,QAAQ,YAAY,KACnB,OAAO,CAAC,OAAO,CAgBjB,CAAA"}
1
+ {"version":3,"file":"validateBridgeTransaction.d.ts","sourceRoot":"","sources":["../../../src/validation/validateBridgeTransaction.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEpE,OAAO,KAAK,EACV,YAAY,EAAE,uBAAuB,EAAE,QAAQ,EAChD,MAAM,sBAAsB,CAAA;AAK7B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,GACpC,YAAY,uBAAuB,EACnC,QAAQ,YAAY,EACpB,UAAU,QAAQ,EAClB,QAAQ,YAAY,KACnB,OAAO,CAAC,OAAO,CAuBjB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/chain-bridge",
3
- "version": "1.20.1",
3
+ "version": "1.20.2",
4
4
  "description": "XYO Layer One Bridge",
5
5
  "homepage": "https://xylabs.com",
6
6
  "bugs": {
@@ -56,15 +56,15 @@
56
56
  "@xylabs/mongo": "~5.0.80",
57
57
  "@xylabs/sdk-js": "~5.0.80",
58
58
  "@xyo-network/boundwitness-validator": "~5.3.15",
59
- "@xyo-network/chain-orchestration": "~1.20.1",
60
- "@xyo-network/chain-protocol": "~1.20.1",
61
- "@xyo-network/chain-services": "~1.20.1",
59
+ "@xyo-network/chain-orchestration": "~1.20.2",
60
+ "@xyo-network/chain-protocol": "~1.20.2",
61
+ "@xyo-network/chain-services": "~1.20.2",
62
62
  "@xyo-network/sdk-js": "~5.3.15",
63
63
  "@xyo-network/sentinel-abstract": "~5.3.15",
64
64
  "@xyo-network/sentinel-model": "~5.3.15",
65
65
  "@xyo-network/typechain": "~4.1.2",
66
66
  "@xyo-network/wallet-model": "~5.3.15",
67
- "@xyo-network/xl1-sdk": "~1.25.18",
67
+ "@xyo-network/xl1-sdk": "~1.25.19",
68
68
  "async-mutex": "~0.5.0",
69
69
  "bullmq": "~5.70.1",
70
70
  "bullmq-otel": "~1.3.0",
@@ -82,11 +82,11 @@
82
82
  "@types/cors": "~2.8.19",
83
83
  "@types/express": "5.0.6",
84
84
  "@types/express-serve-static-core": "~5.1.1",
85
- "@types/node": "~25.3.3",
85
+ "@types/node": "~25.3.5",
86
86
  "@xylabs/mongo": "~5.0.80",
87
87
  "@xylabs/sdk-js": "~5.0.80",
88
- "@xylabs/ts-scripts-yarn3": "~7.3.2",
89
- "@xylabs/tsconfig": "~7.3.2",
88
+ "@xylabs/ts-scripts-yarn3": "~7.4.9",
89
+ "@xylabs/tsconfig": "~7.4.9",
90
90
  "@xylabs/vitest-extended": "~5.0.80",
91
91
  "@xyo-network/account": "~5.3.15",
92
92
  "@xyo-network/account-model": "~5.3.15",
@@ -96,19 +96,19 @@
96
96
  "@xyo-network/bios": "~7.2.1",
97
97
  "@xyo-network/bios-model": "~7.2.1",
98
98
  "@xyo-network/boundwitness-builder": "~5.3.15",
99
- "@xyo-network/chain-protocol": "~1.20.1",
100
- "@xyo-network/chain-services": "~1.20.1",
101
- "@xyo-network/chain-telemetry": "~1.20.1",
99
+ "@xyo-network/chain-protocol": "~1.20.2",
100
+ "@xyo-network/chain-services": "~1.20.2",
101
+ "@xyo-network/chain-telemetry": "~1.20.2",
102
102
  "@xyo-network/module-abstract": "~5.3.15",
103
103
  "@xyo-network/module-abstract-mongodb": "~5.3.15",
104
104
  "@xyo-network/node-memory": "~5.3.15",
105
105
  "@xyo-network/sdk-js": "~5.3.15",
106
106
  "@xyo-network/sentinel-memory": "~5.3.15",
107
- "@xyo-network/xl1-sdk": "~1.25.18",
107
+ "@xyo-network/xl1-sdk": "~1.25.19",
108
108
  "async-mutex": "~0.5.0",
109
109
  "axios": "~1.13.6",
110
110
  "dotenv": "~17.3.1",
111
- "eslint": "^9.39.3",
111
+ "eslint": "^9.39.4",
112
112
  "ethers": "^6.16.0",
113
113
  "http-status-codes": "~2.3.0",
114
114
  "mongodb": "~7.1.0",
@@ -1,11 +1,11 @@
1
- import { PayloadBuilder } from '@xyo-network/sdk-js'
2
1
  import type { SignedHydratedTransaction } from '@xyo-network/xl1-sdk'
3
2
  import type { FlowProducer } from 'bullmq'
4
3
 
5
4
  import {
6
5
  EthTransactionMonitor, EthTransactionPreparation, EthTransactionSubmission, EthTransactionSubmissionStorage, Xl1ToEthBridgeParent, Xl1TransactionMonitor,
7
6
  Xl1TransactionPreparation, Xl1TransactionSubmission, Xl1TransactionSubmissionStorage,
8
- } from '../workers/index.ts'
7
+ } from '../../workers/index.ts'
8
+ import { getJobIdForXl1ToEthBridgeJob } from './getJobIdForXl1ToEthBridgeJob.ts'
9
9
 
10
10
  /**
11
11
  * Creates a job flow for bridging a transaction from XL1 to Ethereum.
@@ -17,7 +17,7 @@ export const createXl1ToEthBridgeJob = async (
17
17
  flowProducer: FlowProducer,
18
18
  tx: SignedHydratedTransaction,
19
19
  ) => {
20
- const jobId = await PayloadBuilder.hash(tx[0])
20
+ const jobId = await getJobIdForXl1ToEthBridgeJob(tx)
21
21
  const flow = await flowProducer.add({
22
22
  // Step 0 (runs first as parent job)
23
23
  name: Xl1ToEthBridgeParent.name,
@@ -0,0 +1,18 @@
1
+ import { PayloadBuilder } from '@xyo-network/sdk-js'
2
+ import type { SignedHydratedTransaction } from '@xyo-network/xl1-sdk'
3
+
4
+ /**
5
+ * Returns a deterministic & repeatable job ID based off the Transaction hash. This is to ensure
6
+ * that if the same transaction is attempted to be bridged multiple times, it will have the same
7
+ * job ID and not create duplicate jobs.
8
+ * https://docs.bullmq.io/guide/jobs/job-ids
9
+ * "The main reason to be able to specify a custom id is in cases when you want to avoid duplicated
10
+ * jobs. Since ids must be unique, if you add a job with an existing id then that job will just be
11
+ * ignored and not added to the queue at all."
12
+ * @param tx The transaction to bridge from XL1 to ETH
13
+ * @returns A deterministic job ID for the bridge job
14
+ */
15
+ export const getJobIdForXl1ToEthBridgeJob = async (tx: SignedHydratedTransaction) => {
16
+ const jobId = await PayloadBuilder.hash(tx[0])
17
+ return jobId
18
+ }
@@ -0,0 +1,11 @@
1
+ import type { SignedHydratedTransaction } from '@xyo-network/xl1-sdk'
2
+ import type { FlowProducer } from 'bullmq'
3
+
4
+ import { Xl1ToEthBridgeParent } from '../../workers/index.ts'
5
+ import { getJobIdForXl1ToEthBridgeJob } from './getJobIdForXl1ToEthBridgeJob.ts'
6
+
7
+ export const getXl1ToEthBridgeJob = async (flowProducer: FlowProducer, tx: SignedHydratedTransaction) => {
8
+ const id = await getJobIdForXl1ToEthBridgeJob(tx)
9
+ const flow = await flowProducer.getFlow({ queueName: Xl1ToEthBridgeParent.queueName, id })
10
+ return flow
11
+ }
@@ -0,0 +1,3 @@
1
+ export * from './createXl1ToEthBridgeJob.ts'
2
+ export * from './getJobIdForXl1ToEthBridgeJob.ts'
3
+ export * from './getXl1ToEthBridgeJob.ts'
@@ -1,2 +1,2 @@
1
1
  export * from './createEthToXl1BridgeJob.ts'
2
- export * from './createXl1ToEthBridgeJob.ts'
2
+ export * from './createXl1ToEthBridgeJob/index.ts'
@@ -1,5 +1,6 @@
1
1
  import type { RouteDefinition } from '@xylabs/express'
2
2
  import { requestHandlerValidator } from '@xylabs/express'
3
+ import { isDefined } from '@xylabs/sdk-js'
3
4
  import type { BridgeConfig } from '@xyo-network/chain-orchestration'
4
5
  import {
5
6
  PayloadBuilder, PayloadZodLooseOfSchema, PayloadZodStrictOfSchema,
@@ -12,7 +13,7 @@ import {
12
13
  } from '@xyo-network/xl1-sdk'
13
14
  import { z } from 'zod'
14
15
 
15
- import { createXl1ToEthBridgeJob } from '../../../../../queue/index.ts'
16
+ import { createXl1ToEthBridgeJob, getXl1ToEthBridgeJob } from '../../../../../queue/index.ts'
16
17
  import {
17
18
  validateBridgeEstimateExact, validateBridgeTransaction, validateSufficientXL1SourceAddressBalance,
18
19
  } from '../../../../../validation/index.ts'
@@ -63,8 +64,17 @@ export const makeBridgeToRemoteRoute = (config: BridgeConfig): RouteDefinition =
63
64
  return
64
65
  }
65
66
 
66
- // Submit to job queue
67
+ // Create the signed hydrated transaction for the job
67
68
  const singedHydratedTransaction: SignedHydratedTransaction = [signedTxBw, [transfer, bridgeIntent]]
69
+
70
+ // Check if a job already exists for this transaction
71
+ const existingFlow = await getXl1ToEthBridgeJob(flowProducer, singedHydratedTransaction)
72
+ if (isDefined(existingFlow)) {
73
+ res.status(200).send()
74
+ return
75
+ }
76
+
77
+ // Submit to job queue
68
78
  await createXl1ToEthBridgeJob(flowProducer, singedHydratedTransaction)
69
79
 
70
80
  // Create BridgeObservation
@@ -77,7 +87,7 @@ export const makeBridgeToRemoteRoute = (config: BridgeConfig): RouteDefinition =
77
87
  ).fields(bridgeObservationFields).build()
78
88
 
79
89
  // Return bridge observation to caller
80
- res.json(bridgeObservation)
90
+ res.status(202).json(bridgeObservation)
81
91
  }),
82
92
  }
83
93
  }
@@ -1,12 +1,13 @@
1
- import { asAddress, isDefined } from '@xylabs/sdk-js'
1
+ import { asAddress } from '@xylabs/sdk-js'
2
2
  import {
3
- addressesContains, BoundWitnessValidator, payloadHashesContainsAll,
3
+ addressesContains, BoundWitnessValidator, payloadHashesContainsAll, payloadSchemasContainsAll,
4
4
  } from '@xyo-network/boundwitness-validator'
5
5
  import type { BridgeConfig } from '@xyo-network/chain-orchestration'
6
6
  import { PayloadBuilder } from '@xyo-network/sdk-js'
7
7
  import type {
8
8
  BridgeIntent, TransactionBoundWitness, Transfer,
9
9
  } from '@xyo-network/xl1-sdk'
10
+ import { BridgeIntentSchema, TransferSchema } from '@xyo-network/xl1-sdk'
10
11
 
11
12
  import { getXl1ChainId } from '../config/index.ts'
12
13
 
@@ -29,17 +30,24 @@ export const validateBridgeTransaction = async (
29
30
  ): Promise<boolean> => {
30
31
  const { srcAddress } = intent
31
32
 
33
+ // Ensure the transaction is for the correct source chain
32
34
  const chainId = getXl1ChainId(config)
33
35
  if (signedTxBw.chain !== chainId) return false
34
36
 
37
+ // Ensure only the expected number of payloads exist (do not allow ambiguous extras)
38
+ if (signedTxBw.payload_hashes.length != 2) return false
39
+ // Ensure the payloads match the expected schemas
40
+ if (!payloadSchemasContainsAll(signedTxBw, [BridgeIntentSchema, TransferSchema])) return false
41
+ // Ensure the hashes match the intent and transfer
42
+ const hashes = await PayloadBuilder.hashes([intent, transfer])
43
+ if (!payloadHashesContainsAll(signedTxBw, hashes)) return false
44
+ // Ensure the BoundWitness is valid and signed by the sender
35
45
  const errors = await new BoundWitnessValidator(signedTxBw).validate()
36
- if (isDefined(errors) && errors.length > 0) return false
46
+ if (errors.length > 0) return false
37
47
 
48
+ // Ensure the sender's address is included in the addresses
38
49
  const sender = asAddress(srcAddress, true)
39
50
  if (!addressesContains(signedTxBw, sender)) return false
40
51
 
41
- const hashes = await PayloadBuilder.hashes([intent, transfer])
42
- if (!payloadHashesContainsAll(signedTxBw, hashes)) return false
43
-
44
52
  return true
45
53
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"createXl1ToEthBridgeJob.d.ts","sourceRoot":"","sources":["../../../../src/queue/flows/createXl1ToEthBridgeJob.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAO1C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,cAAc,YAAY,EAC1B,IAAI,yBAAyB,sCA+F9B,CAAA"}