@sundaeswap/sprinkles 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +451 -210
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/cjs/Sprinkle/index.js +333 -86
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +451 -210
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/esm/Sprinkle/index.js +334 -87
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/types/Sprinkle/index.d.ts +40 -3
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/src/Sprinkle/__tests__/tx-dialog.test.ts +517 -234
- package/src/Sprinkle/index.ts +347 -109
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tx-dialog.test.js","names":["_bunTest","require","_typebox","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","selectCalls","selectResponses","mock","module","input","password","select","opts","push","response","shift","undefined","search","clipboardContent","clipboardShouldFail","writeSync","content","Error","Sprinkle","Promise","resolve","then","TestSchema","Type","name","String","describe","beforeEach","test","sprinkle","logs","origLog","console","log","args","join","mockTx","toCbor","repeat","body","requiredSigners","certs","withdrawals","mockBlaze","wallet","getUsedAddresses","TxDialog","cborLog","find","l","includes","expect","toBeDefined","length","toBeLessThan","toContain","menuCall","choiceNames","choices","map","c","not","HotWallet","hotWalletProto","prototype","mockWallet","create","txCbor","toBe","some","truncatedLog","fullLog","origWarn","warn","beforeSignCalled","signTransaction","tx","submitTransaction","beforeSign"],"sources":["../../../../src/Sprinkle/__tests__/tx-dialog.test.ts"],"sourcesContent":["import { describe, test, expect, mock, beforeEach } from \"bun:test\";\nimport { Type } from \"@sinclair/typebox\";\n\n// Track select calls\nlet selectCalls: any[] = [];\nlet selectResponses: any[] = [];\n\n// Mock @inquirer/prompts\nmock.module(\"@inquirer/prompts\", () => ({\n input: mock(async () => \"test\"),\n password: mock(async () => \"secret\"),\n select: mock(async (opts: any) => {\n selectCalls.push(opts);\n const response = selectResponses.shift();\n if (response === undefined) {\n // Default: return -1 (Back/Exit)\n return -1;\n }\n return response;\n }),\n search: mock(async () => \"result\"),\n}));\n\n// Mock clipboardy\nlet clipboardContent = \"\";\nlet clipboardShouldFail = false;\nmock.module(\"clipboardy\", () => ({\n default: {\n writeSync: (content: string) => {\n if (clipboardShouldFail) throw new Error(\"clipboard not available\");\n clipboardContent = content;\n },\n },\n}));\n\nconst { Sprinkle } = await import(\"../../index.js\");\n\nconst TestSchema = Type.Object({\n name: Type.String(),\n});\n\ndescribe(\"TxDialog (2.6)\", () => {\n beforeEach(() => {\n selectCalls = [];\n selectResponses = [];\n clipboardContent = \"\";\n clipboardShouldFail = false;\n });\n\n test(\"shows truncated CBOR by default\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog\");\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n // Just exit immediately\n selectResponses = [-1];\n\n const mockTx = {\n toCbor: () => \"a\".repeat(100),\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // Should show truncated CBOR (50 chars + ...)\n const cborLog = logs.find(l => l.includes(\"Transaction CBOR:\"));\n expect(cborLog).toBeDefined();\n expect(cborLog!.length).toBeLessThan(100);\n expect(cborLog).toContain(\"...\");\n });\n\n test(\"menu items for non-HotWallet include Expand, Copy, no Sign\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog2\");\n const origLog = console.log;\n console.log = () => {};\n\n selectResponses = [-1];\n\n const mockTx = {\n toCbor: () => \"deadbeef\",\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // Check the select call had Expand and Copy but not Sign\n const menuCall = selectCalls[0];\n expect(menuCall).toBeDefined();\n const choiceNames = menuCall.choices.map((c: any) => c.name);\n expect(choiceNames).toContain(\"Expand CBOR\");\n expect(choiceNames).toContain(\"Copy CBOR to clipboard\");\n expect(choiceNames).not.toContain(\"Sign and submit transaction\");\n });\n\n test(\"menu items for HotWallet include Sign\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog3\");\n const origLog = console.log;\n console.log = () => {};\n\n // Need to import HotWallet to use instanceof\n const { HotWallet } = await import(\"@blaze-cardano/sdk\");\n\n selectResponses = [-1];\n\n const mockTx = {\n toCbor: () => \"deadbeef\",\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n // Create a mock that passes instanceof HotWallet check\n // We need to use Object.create to set the prototype\n const hotWalletProto = HotWallet.prototype;\n const mockWallet = Object.create(hotWalletProto);\n mockWallet.getUsedAddresses = async () => [];\n\n const mockBlaze = {\n wallet: mockWallet,\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n const menuCall = selectCalls[0];\n expect(menuCall).toBeDefined();\n const choiceNames = menuCall.choices.map((c: any) => c.name);\n expect(choiceNames).toContain(\"Sign and submit transaction\");\n });\n\n test(\"copy CBOR to clipboard works\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog4\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n // Select \"Copy CBOR to clipboard\" (index 1), then Back (-1)\n selectResponses = [1, -1];\n\n const txCbor = \"deadbeefcafebabe\";\n const mockTx = {\n toCbor: () => txCbor,\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(clipboardContent).toBe(txCbor);\n expect(logs.some(l => l.includes(\"copied to clipboard\"))).toBe(true);\n });\n\n test(\"clipboard failure falls back to expanded view\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog5\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n clipboardShouldFail = true;\n\n // Select \"Copy CBOR to clipboard\" (index 1), \n // It will fail and call showDialog again with expanded=true\n // Then Back (-1) from the expanded menu, then Back from outer\n selectResponses = [1, -1, -1];\n\n const txCbor = \"a\".repeat(100);\n const mockTx = {\n toCbor: () => txCbor,\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(logs.some(l => l.includes(\"Failed to copy\"))).toBe(true);\n // After failure it should show the full CBOR without truncation\n expect(logs.some(l => l.includes(txCbor) && !l.includes(\"...\"))).toBe(true);\n });\n\n test(\"expand CBOR shows full content\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog6\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n // Select \"Expand CBOR\" (index 0), then Back (-1) from expanded, then Back from outer\n selectResponses = [0, -1, -1];\n\n const txCbor = \"b\".repeat(100);\n const mockTx = {\n toCbor: () => txCbor,\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // First call shows truncated, second shows full\n const truncatedLog = logs.find(l => l.includes(\"...\") && l.includes(\"Transaction CBOR:\"));\n const fullLog = logs.find(l => l.includes(txCbor) && !l.includes(\"...\"));\n expect(truncatedLog).toBeDefined();\n expect(fullLog).toBeDefined();\n });\n\n test(\"beforeSign hook is called before signing\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog7\");\n const origLog = console.log;\n const origWarn = console.warn;\n console.log = () => {};\n console.warn = () => {};\n\n const { HotWallet } = await import(\"@blaze-cardano/sdk\");\n\n let beforeSignCalled = false;\n\n // Select \"Sign and submit\" (index 2 - after Expand and Copy), then Back\n selectResponses = [2, -1];\n\n const mockTx = {\n toCbor: () => \"deadbeef\",\n body: () => ({\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n };\n\n const hotWalletProto = HotWallet.prototype;\n const mockWallet = Object.create(hotWalletProto);\n mockWallet.getUsedAddresses = async () => [];\n\n const mockBlaze = {\n wallet: mockWallet,\n signTransaction: async (tx: any) => tx,\n submitTransaction: async () => \"txhash123\",\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any, {\n beforeSign: async () => {\n beforeSignCalled = true;\n },\n });\n console.log = origLog;\n console.warn = origWarn;\n\n expect(beforeSignCalled).toBe(true);\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"tx-dialog.test.js","names":["_bunTest","require","_typebox","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","selectCalls","selectResponses","confirmResponses","inputResponses","mock","module","input","response","shift","password","select","opts","push","undefined","confirm","search","clipboardContent","clipboardShouldFail","writeSync","content","Error","Sprinkle","Promise","resolve","then","TestSchema","Type","name","String","createMockTx","cbor","toCbor","body","requiredSigners","certs","withdrawals","witnessSet","vkeys","setVkeys","setWitnessSet","describe","beforeEach","test","sprinkle","logs","origLog","console","log","args","join","mockTx","repeat","mockBlaze","wallet","getUsedAddresses","TxDialog","cborLog","find","l","includes","expect","toBeDefined","length","toBeLessThan","toContain","txLog","sigLog","menuCall","choiceNames","choices","map","c","not","HotWallet","hotWalletProto","prototype","mockWallet","create","txCbor","toBe","some","truncatedLog","fullLog","origWarn","warn","beforeSignCalled","signTransaction","tx","size","toCore","beforeSign","firstMenuChoices","secondMenuChoices","result","action","txId","toBeUndefined","submitTransaction","values","toString","origErr","error","errors"],"sources":["../../../../src/Sprinkle/__tests__/tx-dialog.test.ts"],"sourcesContent":["import { describe, test, expect, mock, beforeEach } from \"bun:test\";\nimport { Type } from \"@sinclair/typebox\";\n\n// Track calls and responses\nlet selectCalls: any[] = [];\nlet selectResponses: string[] = [];\nlet confirmResponses: boolean[] = [];\nlet inputResponses: string[] = [];\n\n// Mock @inquirer/prompts\nmock.module(\"@inquirer/prompts\", () => ({\n input: mock(async () => {\n const response = inputResponses.shift();\n return response ?? \"\";\n }),\n password: mock(async () => \"secret\"),\n select: mock(async (opts: any) => {\n selectCalls.push(opts);\n const response = selectResponses.shift();\n if (response === undefined) {\n return \"cancel\";\n }\n return response;\n }),\n confirm: mock(async () => {\n const response = confirmResponses.shift();\n return response ?? false;\n }),\n search: mock(async () => \"result\"),\n}));\n\n// Mock clipboardy\nlet clipboardContent = \"\";\nlet clipboardShouldFail = false;\nmock.module(\"clipboardy\", () => ({\n default: {\n writeSync: (content: string) => {\n if (clipboardShouldFail) throw new Error(\"clipboard not available\");\n clipboardContent = content;\n },\n },\n}));\n\nconst { Sprinkle } = await import(\"../../index.js\");\n\nconst TestSchema = Type.Object({\n name: Type.String(),\n});\n\n// Helper to create a mock transaction\nconst createMockTx = (cbor = \"deadbeef\") => ({\n toCbor: () => cbor,\n body: () => ({\n toCbor: () => cbor,\n requiredSigners: () => null,\n certs: () => null,\n withdrawals: () => null,\n }),\n witnessSet: () => ({\n vkeys: () => null,\n setVkeys: () => {},\n }),\n setWitnessSet: () => {},\n});\n\ndescribe(\"TxDialog\", () => {\n beforeEach(() => {\n selectCalls = [];\n selectResponses = [];\n confirmResponses = [];\n inputResponses = [];\n clipboardContent = \"\";\n clipboardShouldFail = false;\n });\n\n describe(\"Display\", () => {\n test(\"shows truncated CBOR by default\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog\");\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"cancel\"];\n\n const mockTx = createMockTx(\"a\".repeat(100));\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n const cborLog = logs.find((l) => l.includes(\"Transaction CBOR:\"));\n expect(cborLog).toBeDefined();\n expect(cborLog!.length).toBeLessThan(100);\n expect(cborLog).toContain(\"...\");\n });\n\n test(\"shows transaction hash\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-hash\");\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"cancel\"];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n const txLog = logs.find((l) => l.includes(\"Transaction:\"));\n expect(txLog).toBeDefined();\n });\n\n test(\"shows signature count\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-sigs\");\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"cancel\"];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n const sigLog = logs.find((l) => l.includes(\"Signatures:\"));\n expect(sigLog).toBeDefined();\n expect(sigLog).toContain(\"0\");\n });\n });\n\n describe(\"Menu options\", () => {\n test(\"non-HotWallet has Expand, Copy, Import, Submit, Cancel - no Sign\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog2\");\n const origLog = console.log;\n console.log = () => {};\n\n selectResponses = [\"cancel\"];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n const menuCall = selectCalls[0];\n expect(menuCall).toBeDefined();\n const choiceNames = menuCall.choices.map((c: any) => c.name);\n expect(choiceNames).toContain(\"Expand CBOR\");\n expect(choiceNames).toContain(\"Copy CBOR to clipboard\");\n expect(choiceNames).toContain(\"Import signatures from CBOR\");\n expect(choiceNames).toContain(\"Submit transaction\");\n expect(choiceNames).toContain(\"Cancel\");\n expect(choiceNames).not.toContain(\"Sign with this wallet\");\n });\n\n test(\"HotWallet has Sign option\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog3\");\n const origLog = console.log;\n console.log = () => {};\n\n const { HotWallet } = await import(\"@blaze-cardano/sdk\");\n\n selectResponses = [\"cancel\"];\n\n const mockTx = createMockTx();\n\n const hotWalletProto = HotWallet.prototype;\n const mockWallet = Object.create(hotWalletProto);\n mockWallet.getUsedAddresses = async () => [];\n\n const mockBlaze = {\n wallet: mockWallet,\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n const menuCall = selectCalls[0];\n expect(menuCall).toBeDefined();\n const choiceNames = menuCall.choices.map((c: any) => c.name);\n expect(choiceNames).toContain(\"Sign with this wallet\");\n });\n });\n\n describe(\"Copy CBOR\", () => {\n test(\"copies CBOR to clipboard\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog4\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"copy\", \"cancel\"];\n\n const txCbor = \"deadbeefcafebabe\";\n const mockTx = createMockTx(txCbor);\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(clipboardContent).toBe(txCbor);\n expect(logs.some((l) => l.includes(\"copied to clipboard\"))).toBe(true);\n });\n\n test(\"clipboard failure falls back to expanded view\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog5\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n clipboardShouldFail = true;\n\n selectResponses = [\"copy\", \"cancel\"];\n\n const txCbor = \"a\".repeat(100);\n const mockTx = createMockTx(txCbor);\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(logs.some((l) => l.includes(\"Failed to copy\"))).toBe(true);\n });\n });\n\n describe(\"Expand CBOR\", () => {\n test(\"shows full content when expanded\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog6\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"expand\", \"cancel\"];\n\n const txCbor = \"b\".repeat(100);\n const mockTx = createMockTx(txCbor);\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // First shows truncated, second shows full\n const truncatedLog = logs.find(\n (l) => l.includes(\"...\") && l.includes(\"Transaction CBOR:\"),\n );\n const fullLog = logs.find(\n (l) => l.includes(txCbor) && !l.includes(\"...\"),\n );\n expect(truncatedLog).toBeDefined();\n expect(fullLog).toBeDefined();\n });\n });\n\n describe(\"Sign\", () => {\n test(\"beforeSign hook is called before signing\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog7\");\n const origLog = console.log;\n const origWarn = console.warn;\n console.log = () => {};\n console.warn = () => {};\n\n const { HotWallet } = await import(\"@blaze-cardano/sdk\");\n\n let beforeSignCalled = false;\n\n selectResponses = [\"sign\", \"cancel\"];\n\n const mockTx = createMockTx();\n\n const hotWalletProto = HotWallet.prototype;\n const mockWallet = Object.create(hotWalletProto);\n mockWallet.getUsedAddresses = async () => [];\n\n const mockBlaze = {\n wallet: mockWallet,\n signTransaction: async (tx: any) => ({\n witnessSet: () => ({\n vkeys: () => ({\n size: () => 1,\n toCore: () => [[\"vkey123\", \"sig123\"]],\n }),\n }),\n }),\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any, {\n beforeSign: async () => {\n beforeSignCalled = true;\n },\n });\n console.log = origLog;\n console.warn = origWarn;\n\n expect(beforeSignCalled).toBe(true);\n });\n\n test(\"Sign option hidden after signing\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-signed\");\n const origLog = console.log;\n const origWarn = console.warn;\n console.log = () => {};\n console.warn = () => {};\n\n const { HotWallet } = await import(\"@blaze-cardano/sdk\");\n\n selectResponses = [\"sign\", \"cancel\"];\n\n const mockTx = createMockTx();\n\n const hotWalletProto = HotWallet.prototype;\n const mockWallet = Object.create(hotWalletProto);\n mockWallet.getUsedAddresses = async () => [];\n\n const mockBlaze = {\n wallet: mockWallet,\n signTransaction: async (tx: any) => ({\n witnessSet: () => ({\n vkeys: () => ({\n size: () => 1,\n toCore: () => [[\"vkey123\", \"sig123\"]],\n }),\n }),\n }),\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n console.warn = origWarn;\n\n // First menu should have Sign, second should not\n expect(selectCalls.length).toBe(2);\n const firstMenuChoices = selectCalls[0].choices.map((c: any) => c.name);\n const secondMenuChoices = selectCalls[1].choices.map((c: any) => c.name);\n expect(firstMenuChoices).toContain(\"Sign with this wallet\");\n expect(secondMenuChoices).not.toContain(\"Sign with this wallet\");\n });\n });\n\n describe(\"Return values\", () => {\n test(\"returns cancelled when user cancels\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-cancel\");\n const origLog = console.log;\n console.log = () => {};\n\n selectResponses = [\"cancel\"];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(result.action).toBe(\"cancelled\");\n expect(result.tx).toBeDefined();\n expect(result.txId).toBeUndefined();\n });\n\n test(\"returns signed when user signs then cancels\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-signed2\");\n const origLog = console.log;\n const origWarn = console.warn;\n console.log = () => {};\n console.warn = () => {};\n\n const { HotWallet } = await import(\"@blaze-cardano/sdk\");\n\n selectResponses = [\"sign\", \"cancel\"];\n\n const mockTx = createMockTx();\n\n const hotWalletProto = HotWallet.prototype;\n const mockWallet = Object.create(hotWalletProto);\n mockWallet.getUsedAddresses = async () => [];\n\n const mockBlaze = {\n wallet: mockWallet,\n signTransaction: async (tx: any) => ({\n witnessSet: () => ({\n vkeys: () => ({\n size: () => 1,\n toCore: () => [[\"vkey123\", \"sig123\"]],\n }),\n }),\n }),\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n console.warn = origWarn;\n\n expect(result.action).toBe(\"signed\");\n expect(result.tx).toBeDefined();\n });\n\n test(\"returns submitted with txId on successful submit\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-submit\");\n const origLog = console.log;\n console.log = () => {};\n\n selectResponses = [\"submit\"];\n confirmResponses = [true]; // Confirm submit with no signatures\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n submitTransaction: async () => \"txhash123456\",\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(result.action).toBe(\"submitted\");\n expect(result.txId).toBe(\"txhash123456\");\n expect(result.tx).toBeDefined();\n });\n });\n\n describe(\"Submit warnings\", () => {\n test(\"warns when submitting with no signatures\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-warn\");\n const origLog = console.log;\n console.log = () => {};\n\n // First try to submit, decline warning, then cancel\n selectResponses = [\"submit\", \"cancel\"];\n confirmResponses = [false];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // Should have returned to menu, then cancelled\n expect(result.action).toBe(\"cancelled\");\n expect(selectCalls.length).toBe(2);\n });\n });\n\n describe(\"Exit behavior\", () => {\n test(\"exits loop after successful submit\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-exit\");\n const origLog = console.log;\n console.log = () => {};\n\n selectResponses = [\"submit\"];\n confirmResponses = [true];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n submitTransaction: async () => \"txhash789\",\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // Should only have one menu call - no loop after submit\n expect(selectCalls.length).toBe(1);\n expect(result.action).toBe(\"submitted\");\n });\n });\n\n describe(\"Required signers display\", () => {\n test(\"shows required signers when present\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-req\");\n const logs: string[] = [];\n const origLog = console.log;\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"cancel\"];\n\n const mockTx = {\n toCbor: () => \"deadbeef\",\n body: () => ({\n toCbor: () => \"deadbeef\",\n requiredSigners: () => ({\n values: () => [\n { toString: () => \"abc123def456\" },\n { toString: () => \"789ghi012jkl\" },\n ],\n }),\n certs: () => null,\n withdrawals: () => null,\n }),\n witnessSet: () => ({\n vkeys: () => null,\n }),\n };\n\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n // Should show \"X of Y required\" format\n expect(logs.some((l) => l.includes(\"of\") && l.includes(\"required\"))).toBe(\n true,\n );\n // Should show required signers list\n expect(logs.some((l) => l.includes(\"Required signers:\"))).toBe(true);\n });\n });\n\n describe(\"Import signatures\", () => {\n test(\"continues on empty CBOR input\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-import1\");\n const origLog = console.log;\n const logs: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n\n selectResponses = [\"import\", \"cancel\"];\n inputResponses = [\"\"]; // Empty input\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n\n expect(logs.some((l) => l.includes(\"No CBOR provided\"))).toBe(true);\n expect(result.action).toBe(\"cancelled\");\n });\n\n test(\"handles invalid CBOR gracefully\", async () => {\n const sprinkle = new Sprinkle(TestSchema, \"/tmp/test-txdialog-import2\");\n const origLog = console.log;\n const origErr = console.error;\n const logs: string[] = [];\n const errors: string[] = [];\n console.log = (...args: any[]) => logs.push(args.join(\" \"));\n console.error = (...args: any[]) => errors.push(args.join(\" \"));\n\n selectResponses = [\"import\", \"cancel\"];\n inputResponses = [\"not-valid-cbor\"];\n\n const mockTx = createMockTx();\n const mockBlaze = {\n wallet: { getUsedAddresses: async () => [] },\n };\n\n const result = await sprinkle.TxDialog(mockBlaze as any, mockTx as any);\n console.log = origLog;\n console.error = origErr;\n\n expect(errors.some((l) => l.includes(\"Failed to import\"))).toBe(true);\n expect(result.action).toBe(\"cancelled\");\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -643,112 +643,359 @@ class Sprinkle {
|
|
|
643
643
|
saveSettings() {
|
|
644
644
|
this.saveProfile();
|
|
645
645
|
}
|
|
646
|
+
|
|
647
|
+
// --- TxDialog Helpers ---
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Get the payment key hash from a HotWallet's first address
|
|
651
|
+
*/
|
|
652
|
+
async getWalletPaymentKeyHash(wallet) {
|
|
653
|
+
try {
|
|
654
|
+
const addresses = await wallet.getUsedAddresses();
|
|
655
|
+
const address = addresses[0];
|
|
656
|
+
if (!address) return null;
|
|
657
|
+
const paymentCredential = address.asBase()?.getPaymentCredential();
|
|
658
|
+
return paymentCredential?.hash?.toString() ?? null;
|
|
659
|
+
} catch {
|
|
660
|
+
return null;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Count the number of vkey signatures in a transaction's witness set
|
|
666
|
+
*/
|
|
667
|
+
countSignatures(tx) {
|
|
668
|
+
const vkeys = tx.witnessSet().vkeys();
|
|
669
|
+
return vkeys ? vkeys.size() : 0;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Check if a specific public key has already signed the transaction
|
|
674
|
+
* Compares by vkey (public key bytes)
|
|
675
|
+
*/
|
|
676
|
+
hasVkeySigned(tx, vkeyHex) {
|
|
677
|
+
const vkeys = tx.witnessSet().vkeys();
|
|
678
|
+
if (!vkeys) return false;
|
|
679
|
+
const vkeyArray = vkeys.toCore();
|
|
680
|
+
return vkeyArray.some(([vkey]) => vkey === vkeyHex);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Get the list of required signer key hashes from the transaction body
|
|
685
|
+
*/
|
|
686
|
+
getRequiredSigners(tx) {
|
|
687
|
+
const requiredSigners = tx.body().requiredSigners();
|
|
688
|
+
if (!requiredSigners) return [];
|
|
689
|
+
return Array.from(requiredSigners.values()).map(s => s.toString());
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Compute the transaction body hash for display
|
|
694
|
+
*/
|
|
695
|
+
getTxBodyHash(tx) {
|
|
696
|
+
const bodyCbor = tx.body().toCbor();
|
|
697
|
+
return (0, _core.blake2b_256)(bodyCbor);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Format a hash for display: first 8 chars + ... + last 8 chars
|
|
702
|
+
*/
|
|
703
|
+
formatHash(hash) {
|
|
704
|
+
if (hash.length <= 20) return hash;
|
|
705
|
+
return `${hash.slice(0, 8)}...${hash.slice(-8)}`;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Merge signatures from source transaction into target transaction.
|
|
710
|
+
* Prevents duplicate signatures by comparing vkey (public key).
|
|
711
|
+
* Returns the count of newly added signatures.
|
|
712
|
+
*/
|
|
713
|
+
mergeSignatures(target, source) {
|
|
714
|
+
const targetWs = target.witnessSet();
|
|
715
|
+
const sourceWs = source.witnessSet();
|
|
716
|
+
const targetVkeys = targetWs.vkeys()?.toCore() ?? [];
|
|
717
|
+
const sourceVkeys = sourceWs.vkeys()?.toCore() ?? [];
|
|
718
|
+
|
|
719
|
+
// Find vkeys in source that aren't in target (by comparing public key)
|
|
720
|
+
const existingPubKeys = new Set(targetVkeys.map(([vkey]) => vkey));
|
|
721
|
+
const newVkeys = sourceVkeys.filter(([vkey]) => !existingPubKeys.has(vkey));
|
|
722
|
+
if (newVkeys.length === 0) {
|
|
723
|
+
return 0;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// Merge the new vkeys into target
|
|
727
|
+
targetWs.setVkeys(_core.CborSet.fromCore([...targetVkeys, ...newVkeys], _core.VkeyWitness.fromCore));
|
|
728
|
+
target.setWitnessSet(targetWs);
|
|
729
|
+
return newVkeys.length;
|
|
730
|
+
}
|
|
646
731
|
async TxDialog(blaze, tx, opts) {
|
|
647
|
-
|
|
732
|
+
let currentTx = tx;
|
|
648
733
|
let expanded = false;
|
|
649
|
-
|
|
734
|
+
let hasSignedThisSession = false;
|
|
735
|
+
|
|
736
|
+
// Check if wallet can sign (is HotWallet)
|
|
737
|
+
const isHotWallet = blaze.wallet instanceof _sdk.HotWallet;
|
|
738
|
+
|
|
739
|
+
// Get wallet's vkeys for detecting if already signed
|
|
740
|
+
let walletVkeys = [];
|
|
741
|
+
if (isHotWallet) {
|
|
742
|
+
try {
|
|
743
|
+
// Sign a dummy to get the wallet's public keys
|
|
744
|
+
// We'll use this to check if wallet has already signed
|
|
745
|
+
const wallet = blaze.wallet;
|
|
746
|
+
const addresses = await wallet.getUsedAddresses();
|
|
747
|
+
const address = addresses[0];
|
|
748
|
+
if (address) {
|
|
749
|
+
// We can't easily get vkeys without signing, so we'll track after first sign
|
|
750
|
+
}
|
|
751
|
+
} catch {
|
|
752
|
+
// Ignore errors in setup
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
while (true) {
|
|
756
|
+
// Display transaction status
|
|
757
|
+
const txHash = this.getTxBodyHash(currentTx);
|
|
758
|
+
const sigCount = this.countSignatures(currentTx);
|
|
759
|
+
const requiredSigners = this.getRequiredSigners(currentTx);
|
|
760
|
+
console.log("");
|
|
761
|
+
console.log(`Transaction: ${this.formatHash(txHash)}`);
|
|
762
|
+
if (requiredSigners.length > 0) {
|
|
763
|
+
console.log(`Signatures: ${sigCount} of ${requiredSigners.length} required`);
|
|
764
|
+
console.log("Required signers:");
|
|
765
|
+
for (const signer of requiredSigners) {
|
|
766
|
+
console.log(` - ${this.formatHash(signer)}`);
|
|
767
|
+
}
|
|
768
|
+
} else {
|
|
769
|
+
console.log(`Signatures: ${sigCount}`);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// Display CBOR
|
|
773
|
+
const txCbor = currentTx.toCbor();
|
|
650
774
|
if (expanded) {
|
|
651
775
|
console.log("Transaction CBOR:", txCbor);
|
|
652
776
|
} else {
|
|
653
777
|
console.log("Transaction CBOR:", `${String(txCbor).slice(0, 50)}...`);
|
|
654
778
|
}
|
|
655
|
-
|
|
779
|
+
|
|
780
|
+
// Build dynamic menu choices
|
|
781
|
+
const choices = [];
|
|
782
|
+
|
|
783
|
+
// "Sign with this wallet" - only if HotWallet and hasn't signed this session
|
|
784
|
+
if (isHotWallet && !hasSignedThisSession) {
|
|
785
|
+
choices.push({
|
|
786
|
+
name: "Sign with this wallet",
|
|
787
|
+
value: "sign"
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// CBOR options
|
|
656
792
|
if (!expanded) {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
expanded = true;
|
|
661
|
-
await showDialog();
|
|
662
|
-
}
|
|
793
|
+
choices.push({
|
|
794
|
+
name: "Expand CBOR",
|
|
795
|
+
value: "expand"
|
|
663
796
|
});
|
|
664
797
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
try {
|
|
669
|
-
const {
|
|
670
|
-
default: clipboard
|
|
671
|
-
} = await Promise.resolve().then(() => _interopRequireWildcard(require("clipboardy")));
|
|
672
|
-
clipboard.writeSync(String(txCbor));
|
|
673
|
-
console.log("Transaction CBOR copied to clipboard.");
|
|
674
|
-
} catch (e) {
|
|
675
|
-
console.log("Failed to copy to clipboard, expanding instead.");
|
|
676
|
-
expanded = true;
|
|
677
|
-
await showDialog();
|
|
678
|
-
}
|
|
679
|
-
}
|
|
798
|
+
choices.push({
|
|
799
|
+
name: "Copy CBOR to clipboard",
|
|
800
|
+
value: "copy"
|
|
680
801
|
});
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
802
|
+
choices.push({
|
|
803
|
+
name: "Import signatures from CBOR",
|
|
804
|
+
value: "import"
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// Submit and cancel
|
|
808
|
+
choices.push({
|
|
809
|
+
name: "Submit transaction",
|
|
810
|
+
value: "submit"
|
|
811
|
+
});
|
|
812
|
+
choices.push({
|
|
813
|
+
name: "Cancel",
|
|
814
|
+
value: "cancel"
|
|
815
|
+
});
|
|
816
|
+
const selection = await (0, _prompts.select)({
|
|
817
|
+
message: "Select an option:",
|
|
818
|
+
choices
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
// Handle selection
|
|
822
|
+
if (selection === "sign") {
|
|
823
|
+
if (opts?.beforeSign) {
|
|
824
|
+
await opts.beforeSign();
|
|
825
|
+
}
|
|
688
826
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
}
|
|
704
|
-
const certs = tx.body().certs();
|
|
705
|
-
const hasCertificates = certs && certs.size() > 0;
|
|
706
|
-
const withdrawals = tx.body().withdrawals();
|
|
707
|
-
const hasWithdrawals = withdrawals && withdrawals.size > 0;
|
|
708
|
-
if (hasCertificates || hasWithdrawals) {
|
|
709
|
-
needsStakeKey = true;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
827
|
+
// Detect if stake key signature is required
|
|
828
|
+
let needsStakeKey = false;
|
|
829
|
+
try {
|
|
830
|
+
const wallet = blaze.wallet;
|
|
831
|
+
const addresses = await wallet.getUsedAddresses();
|
|
832
|
+
const userAddress = addresses[0];
|
|
833
|
+
if (userAddress) {
|
|
834
|
+
const stakeCredential = userAddress.asBase()?.getStakeCredential();
|
|
835
|
+
const stakeKeyHash = stakeCredential?.hash?.toString();
|
|
836
|
+
if (stakeKeyHash) {
|
|
837
|
+
const reqSigners = currentTx.body().requiredSigners();
|
|
838
|
+
if (reqSigners) {
|
|
839
|
+
const signerArray = Array.from(reqSigners.values());
|
|
840
|
+
needsStakeKey = signerArray.some(signer => signer.toString() === stakeKeyHash);
|
|
712
841
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
842
|
+
const certs = currentTx.body().certs();
|
|
843
|
+
const hasCertificates = certs && certs.size() > 0;
|
|
844
|
+
const withdrawals = currentTx.body().withdrawals();
|
|
845
|
+
const hasWithdrawals = withdrawals && withdrawals.size > 0;
|
|
846
|
+
if (hasCertificates || hasWithdrawals) {
|
|
847
|
+
needsStakeKey = true;
|
|
717
848
|
}
|
|
718
|
-
} catch (error) {
|
|
719
|
-
console.warn("Could not determine stake key requirement, signing with payment key only.");
|
|
720
|
-
console.warn(`Error: ${error.message}`);
|
|
721
849
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
850
|
+
}
|
|
851
|
+
if (needsStakeKey) {
|
|
852
|
+
console.log("Transaction requires stake key signature.");
|
|
853
|
+
} else {
|
|
854
|
+
console.log("Transaction requires payment key signature only.");
|
|
855
|
+
}
|
|
856
|
+
} catch (error) {
|
|
857
|
+
console.warn("Could not determine stake key requirement, signing with payment key only.");
|
|
858
|
+
console.warn(`Error: ${error.message}`);
|
|
859
|
+
}
|
|
860
|
+
try {
|
|
861
|
+
if (needsStakeKey) {
|
|
862
|
+
const wallet = blaze.wallet;
|
|
863
|
+
const signed = await wallet.signTransaction(currentTx, true, true);
|
|
864
|
+
const ws = currentTx.witnessSet();
|
|
865
|
+
const existingVkeys = ws.vkeys()?.toCore() ?? [];
|
|
866
|
+
const signedKeys = signed.vkeys();
|
|
867
|
+
if (!signedKeys) {
|
|
868
|
+
throw new Error("signTransaction: no signed keys in wallet witness response");
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// Check for duplicates before adding
|
|
872
|
+
const newSignedKeys = signedKeys.toCore();
|
|
873
|
+
const existingPubKeys = new Set(existingVkeys.map(([vkey]) => vkey));
|
|
874
|
+
const uniqueNewKeys = newSignedKeys.filter(([vkey]) => !existingPubKeys.has(vkey));
|
|
875
|
+
if (uniqueNewKeys.length === 0) {
|
|
876
|
+
console.log("Wallet has already signed this transaction.");
|
|
877
|
+
} else {
|
|
878
|
+
ws.setVkeys(_core.CborSet.fromCore([...existingVkeys, ...uniqueNewKeys], _core.VkeyWitness.fromCore));
|
|
879
|
+
currentTx.setWitnessSet(ws);
|
|
880
|
+
console.log(`Added ${uniqueNewKeys.length} signature(s).`);
|
|
881
|
+
hasSignedThisSession = true;
|
|
882
|
+
}
|
|
883
|
+
} else {
|
|
884
|
+
const signedTx = await blaze.signTransaction(currentTx);
|
|
885
|
+
// Merge signatures from signed tx into current tx
|
|
886
|
+
const added = this.mergeSignatures(currentTx, signedTx);
|
|
887
|
+
if (added > 0) {
|
|
888
|
+
console.log(`Added ${added} signature(s).`);
|
|
889
|
+
hasSignedThisSession = true;
|
|
737
890
|
} else {
|
|
738
|
-
|
|
891
|
+
console.log("Wallet has already signed this transaction.");
|
|
739
892
|
}
|
|
740
|
-
const txId = await blaze.submitTransaction(signedTx);
|
|
741
|
-
console.log(`Transaction submitted: ${txId}`);
|
|
742
893
|
}
|
|
894
|
+
} catch (error) {
|
|
895
|
+
console.error(`Signing failed: ${error.message}`);
|
|
896
|
+
}
|
|
897
|
+
// Continue loop after signing
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
if (selection === "expand") {
|
|
901
|
+
expanded = true;
|
|
902
|
+
continue;
|
|
903
|
+
}
|
|
904
|
+
if (selection === "copy") {
|
|
905
|
+
try {
|
|
906
|
+
const {
|
|
907
|
+
default: clipboard
|
|
908
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require("clipboardy")));
|
|
909
|
+
clipboard.writeSync(String(currentTx.toCbor()));
|
|
910
|
+
console.log("Transaction CBOR copied to clipboard.");
|
|
911
|
+
} catch {
|
|
912
|
+
console.log("Failed to copy to clipboard, expanding instead.");
|
|
913
|
+
expanded = true;
|
|
914
|
+
}
|
|
915
|
+
continue;
|
|
916
|
+
}
|
|
917
|
+
if (selection === "import") {
|
|
918
|
+
const cborInput = await (0, _prompts.input)({
|
|
919
|
+
message: "Paste transaction CBOR (hex):"
|
|
743
920
|
});
|
|
921
|
+
if (!cborInput || cborInput.trim() === "") {
|
|
922
|
+
console.log("No CBOR provided.");
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
try {
|
|
926
|
+
const importedTx = _sdk.Core.Transaction.fromCbor((0, _core.TxCBOR)(cborInput.trim()));
|
|
927
|
+
|
|
928
|
+
// Validate body hash matches
|
|
929
|
+
const currentHash = this.getTxBodyHash(currentTx);
|
|
930
|
+
const importedHash = this.getTxBodyHash(importedTx);
|
|
931
|
+
if (currentHash !== importedHash) {
|
|
932
|
+
const proceed = await (0, _prompts.confirm)({
|
|
933
|
+
message: `Warning: Imported transaction has different body hash.\nCurrent: ${this.formatHash(currentHash)}\nImported: ${this.formatHash(importedHash)}\nProceed anyway?`,
|
|
934
|
+
default: false
|
|
935
|
+
});
|
|
936
|
+
if (!proceed) {
|
|
937
|
+
console.log("Import cancelled.");
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Merge signatures
|
|
943
|
+
const added = this.mergeSignatures(currentTx, importedTx);
|
|
944
|
+
const sourceVkeys = importedTx.witnessSet().vkeys();
|
|
945
|
+
const sourceCount = sourceVkeys ? sourceVkeys.size() : 0;
|
|
946
|
+
const skipped = sourceCount - added;
|
|
947
|
+
if (added > 0) {
|
|
948
|
+
console.log(`Added ${added} new signature(s).`);
|
|
949
|
+
}
|
|
950
|
+
if (skipped > 0) {
|
|
951
|
+
console.log(`Skipped ${skipped} duplicate signature(s).`);
|
|
952
|
+
}
|
|
953
|
+
if (added === 0 && skipped === 0) {
|
|
954
|
+
console.log("No signatures found in imported transaction.");
|
|
955
|
+
}
|
|
956
|
+
} catch (error) {
|
|
957
|
+
console.error(`Failed to import CBOR: ${error.message}`);
|
|
958
|
+
}
|
|
959
|
+
continue;
|
|
744
960
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
961
|
+
if (selection === "submit") {
|
|
962
|
+
const sigCount = this.countSignatures(currentTx);
|
|
963
|
+
if (sigCount === 0) {
|
|
964
|
+
const proceed = await (0, _prompts.confirm)({
|
|
965
|
+
message: "Warning: Transaction has no signatures. Submit anyway?",
|
|
966
|
+
default: false
|
|
967
|
+
});
|
|
968
|
+
if (!proceed) {
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
try {
|
|
973
|
+
const txId = await blaze.submitTransaction(currentTx);
|
|
974
|
+
console.log(`Transaction submitted: ${txId}`);
|
|
975
|
+
return {
|
|
976
|
+
action: "submitted",
|
|
977
|
+
txId,
|
|
978
|
+
tx: currentTx
|
|
979
|
+
};
|
|
980
|
+
} catch (error) {
|
|
981
|
+
console.error(`Submit failed: ${error.message}`);
|
|
982
|
+
// Continue loop to allow retry or other actions
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
if (selection === "cancel") {
|
|
987
|
+
if (hasSignedThisSession) {
|
|
988
|
+
return {
|
|
989
|
+
action: "signed",
|
|
990
|
+
tx: currentTx
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
return {
|
|
994
|
+
action: "cancelled",
|
|
995
|
+
tx: currentTx
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
}
|
|
752
999
|
}
|
|
753
1000
|
async EditStruct(type, current) {
|
|
754
1001
|
return this._editStruct(type, ["root"], current);
|