toss-expo-sdk 0.1.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/LICENSE +20 -0
- package/README.md +292 -0
- package/lib/module/ble.js +103 -0
- package/lib/module/ble.js.map +1 -0
- package/lib/module/client/TossClient.js +324 -0
- package/lib/module/client/TossClient.js.map +1 -0
- package/lib/module/client/index.js +4 -0
- package/lib/module/client/index.js.map +1 -0
- package/lib/module/contexts/WalletContext.js +99 -0
- package/lib/module/contexts/WalletContext.js.map +1 -0
- package/lib/module/discovery.js +434 -0
- package/lib/module/discovery.js.map +1 -0
- package/lib/module/errors.js +47 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/examples/offlinePaymentFlow.js +234 -0
- package/lib/module/examples/offlinePaymentFlow.js.map +1 -0
- package/lib/module/index.js +32 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/intent.js +223 -0
- package/lib/module/intent.js.map +1 -0
- package/lib/module/intentManager.js +145 -0
- package/lib/module/intentManager.js.map +1 -0
- package/lib/module/internal/arciumHelper.js +50 -0
- package/lib/module/internal/arciumHelper.js.map +1 -0
- package/lib/module/nfc.js +54 -0
- package/lib/module/nfc.js.map +1 -0
- package/lib/module/noise.js +14 -0
- package/lib/module/noise.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/qr.js +57 -0
- package/lib/module/qr.js.map +1 -0
- package/lib/module/reconciliation.js +329 -0
- package/lib/module/reconciliation.js.map +1 -0
- package/lib/module/services/authService.js +205 -0
- package/lib/module/services/authService.js.map +1 -0
- package/lib/module/storage/secureStorage.js +89 -0
- package/lib/module/storage/secureStorage.js.map +1 -0
- package/lib/module/storage.js +16 -0
- package/lib/module/storage.js.map +1 -0
- package/lib/module/sync.js +64 -0
- package/lib/module/sync.js.map +1 -0
- package/lib/module/types/tossUser.js +41 -0
- package/lib/module/types/tossUser.js.map +1 -0
- package/lib/module/utils/nonceUtils.js +38 -0
- package/lib/module/utils/nonceUtils.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/__tests__/index.test.d.ts +1 -0
- package/lib/typescript/src/__tests__/index.test.d.ts.map +1 -0
- package/lib/typescript/src/__tests__/reconciliation.test.d.ts +6 -0
- package/lib/typescript/src/__tests__/reconciliation.test.d.ts.map +1 -0
- package/lib/typescript/src/ble.d.ts +10 -0
- package/lib/typescript/src/ble.d.ts.map +1 -0
- package/lib/typescript/src/client/TossClient.d.ts +110 -0
- package/lib/typescript/src/client/TossClient.d.ts.map +1 -0
- package/lib/typescript/src/client/index.d.ts +3 -0
- package/lib/typescript/src/client/index.d.ts.map +1 -0
- package/lib/typescript/src/contexts/WalletContext.d.ts +20 -0
- package/lib/typescript/src/contexts/WalletContext.d.ts.map +1 -0
- package/lib/typescript/src/discovery.d.ts +188 -0
- package/lib/typescript/src/discovery.d.ts.map +1 -0
- package/lib/typescript/src/errors.d.ts +27 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/examples/offlinePaymentFlow.d.ts +48 -0
- package/lib/typescript/src/examples/offlinePaymentFlow.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/intent.d.ts +84 -0
- package/lib/typescript/src/intent.d.ts.map +1 -0
- package/lib/typescript/src/intentManager.d.ts +46 -0
- package/lib/typescript/src/intentManager.d.ts.map +1 -0
- package/lib/typescript/src/internal/arciumHelper.d.ts +19 -0
- package/lib/typescript/src/internal/arciumHelper.d.ts.map +1 -0
- package/lib/typescript/src/nfc.d.ts +7 -0
- package/lib/typescript/src/nfc.d.ts.map +1 -0
- package/lib/typescript/src/noise.d.ts +5 -0
- package/lib/typescript/src/noise.d.ts.map +1 -0
- package/lib/typescript/src/qr.d.ts +6 -0
- package/lib/typescript/src/qr.d.ts.map +1 -0
- package/lib/typescript/src/reconciliation.d.ts +65 -0
- package/lib/typescript/src/reconciliation.d.ts.map +1 -0
- package/lib/typescript/src/services/authService.d.ts +55 -0
- package/lib/typescript/src/services/authService.d.ts.map +1 -0
- package/lib/typescript/src/storage/secureStorage.d.ts +7 -0
- package/lib/typescript/src/storage/secureStorage.d.ts.map +1 -0
- package/lib/typescript/src/storage.d.ts +4 -0
- package/lib/typescript/src/storage.d.ts.map +1 -0
- package/lib/typescript/src/sync.d.ts +40 -0
- package/lib/typescript/src/sync.d.ts.map +1 -0
- package/lib/typescript/src/types/tossUser.d.ts +39 -0
- package/lib/typescript/src/types/tossUser.d.ts.map +1 -0
- package/lib/typescript/src/utils/nonceUtils.d.ts +8 -0
- package/lib/typescript/src/utils/nonceUtils.d.ts.map +1 -0
- package/package.json +176 -0
- package/src/__tests__/index.test.tsx +1 -0
- package/src/__tests__/reconciliation.test.tsx +361 -0
- package/src/ble.ts +138 -0
- package/src/client/TossClient.ts +435 -0
- package/src/client/index.ts +2 -0
- package/src/contexts/WalletContext.tsx +127 -0
- package/src/discovery.ts +542 -0
- package/src/errors.ts +51 -0
- package/src/examples/offlinePaymentFlow.ts +331 -0
- package/src/index.tsx +61 -0
- package/src/intent.ts +328 -0
- package/src/intentManager.ts +164 -0
- package/src/internal/arciumHelper.ts +58 -0
- package/src/nfc.ts +57 -0
- package/src/noise.ts +9 -0
- package/src/qr.tsx +65 -0
- package/src/reconciliation.ts +421 -0
- package/src/services/authService.ts +238 -0
- package/src/storage/secureStorage.ts +100 -0
- package/src/storage.ts +17 -0
- package/src/sync.ts +101 -0
- package/src/types/tossUser.ts +81 -0
- package/src/utils/nonceUtils.ts +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Transaction","bs58","verifyIntentSignature","intent","serialized","tx","from","Buffer","decode","verifySignatures","error","console","isIntentExpired","Date","now","expiry","updateIntentStatus","status","updatedAt","Math","floor","validateIntent","currentBlockhash","valid","blockhash","processIntentsForSync","intents","connection","getRecentBlockhash","Promise","all","map","validation","Error","message","filterExpiredIntents","expired","push"],"sourceRoot":"../../src","sources":["intentManager.ts"],"mappings":";;AAAA,SAASA,WAAW,QAAQ,iBAAiB;AAC7C,OAAOC,IAAI,MAAM,MAAM;AAGvB;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAACC,MAAoB,EAAW;EACnE,IAAI;IACF;IACA,IAAI,CAACA,MAAM,CAACC,UAAU,EAAE;MACtB,OAAO,KAAK;IACd;;IAEA;IACA,MAAMC,EAAE,GAAGL,WAAW,CAACM,IAAI,CAACC,MAAM,CAACD,IAAI,CAACL,IAAI,CAACO,MAAM,CAACL,MAAM,CAACC,UAAU,CAAC,CAAC,CAAC;;IAExE;IACA,OAAOC,EAAE,CAACI,gBAAgB,CAAC,CAAC;EAC9B,CAAC,CAAC,OAAOC,KAAK,EAAE;IACdC,OAAO,CAACD,KAAK,CAAC,mCAAmC,EAAEA,KAAK,CAAC;IACzD,OAAO,KAAK;EACd;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,eAAeA,CAACT,MAAoB,EAAW;EAC7D,OAAOU,IAAI,CAACC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAGX,MAAM,CAACY,MAAM;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAChCb,MAAoB,EACpBc,MAAoB,EACpBP,KAAc,EACA;EACd,OAAO;IACL,GAAGP,MAAM;IACTc,MAAM;IACNC,SAAS,EAAEC,IAAI,CAACC,KAAK,CAACP,IAAI,CAACC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;IACxC,IAAIJ,KAAK,IAAI;MAAEA;IAAM,CAAC;EACxB,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeW,cAAcA,CAClClB,MAAoB,EACpBmB,gBAAwB,EACqB;EAC7C;EACA,IAAIV,eAAe,CAACT,MAAM,CAAC,EAAE;IAC3B,OAAO;MACLoB,KAAK,EAAE,KAAK;MACZb,KAAK,EAAE;IACT,CAAC;EACH;;EAEA;EACA,IAAI,CAACR,qBAAqB,CAACC,MAAM,CAAC,EAAE;IAClC,OAAO;MACLoB,KAAK,EAAE,KAAK;MACZb,KAAK,EAAE;IACT,CAAC;EACH;;EAEA;EACA;EACA;EACA,IAAIP,MAAM,CAACqB,SAAS,KAAKF,gBAAgB,EAAE;IACzC,OAAO;MACLC,KAAK,EAAE,KAAK;MACZb,KAAK,EAAE;IACT,CAAC;EACH;;EAEA;EACA;EACA;EACA;;EAEA,OAAO;IAAEa,KAAK,EAAE;EAAK,CAAC;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeE,qBAAqBA,CACzCC,OAAuB,EACvBC,UAAe,EACU;EACzB,MAAML,gBAAgB,GAAG,CAAC,MAAMK,UAAU,CAACC,kBAAkB,CAAC,CAAC,EAAEJ,SAAS;EAE1E,OAAOK,OAAO,CAACC,GAAG,CAChBJ,OAAO,CAACK,GAAG,CAAC,MAAO5B,MAAM,IAAK;IAC5B;IACA,IAAIA,MAAM,CAACc,MAAM,KAAK,SAAS,EAAE,OAAOd,MAAM;IAE9C,MAAM6B,UAAU,GAAG,MAAMX,cAAc,CAAClB,MAAM,EAAEmB,gBAAgB,CAAC;IAEjE,IAAI,CAACU,UAAU,CAACT,KAAK,EAAE;MACrB,OAAOP,kBAAkB,CAACb,MAAM,EAAE,QAAQ,EAAE6B,UAAU,CAACtB,KAAK,CAAC;IAC/D;IAEA,IAAI;MACF;MACA;MACA;MACA;MACA;;MAEA,OAAOM,kBAAkB,CAACb,MAAM,EAAE,SAAS,CAAC;IAC9C,CAAC,CAAC,OAAOO,KAAK,EAAE;MACd,OAAOM,kBAAkB,CACvBb,MAAM,EACN,QAAQ,EACRO,KAAK,YAAYuB,KAAK,GAAGvB,KAAK,CAACwB,OAAO,GAAG,eAC3C,CAAC;IACH;EACF,CAAC,CACH,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAClCT,OAAuB,EACW;EAClC,MAAMH,KAAqB,GAAG,EAAE;EAChC,MAAMa,OAAuB,GAAG,EAAE;EAElC,KAAK,MAAMjC,MAAM,IAAIuB,OAAO,EAAE;IAC5B,IAAId,eAAe,CAACT,MAAM,CAAC,EAAE;MAC3BiC,OAAO,CAACC,IAAI,CAACrB,kBAAkB,CAACb,MAAM,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,MAAM;MACLoB,KAAK,CAACc,IAAI,CAAClC,MAAM,CAAC;IACpB;EACF;EAEA,OAAO,CAACoB,KAAK,EAAEa,OAAO,CAAC;AACzB","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// import {
|
|
4
|
+
// getArciumEnv,
|
|
5
|
+
// x25519,
|
|
6
|
+
// getMXEPublicKey,
|
|
7
|
+
// RescueCipher,
|
|
8
|
+
// } from "@arcium-hq/client";
|
|
9
|
+
import * as Arcium from '@arcium-hq/client';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Output from Arcium encryption (internal only)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Internal helper to encrypt a set of numeric values with Arcium.
|
|
17
|
+
* Does not leak anything about Arcium to the SDK consumer.
|
|
18
|
+
*
|
|
19
|
+
* @param mxeProgramId PublicKey of the MXE
|
|
20
|
+
* @param plaintextValues numeric values for encryption
|
|
21
|
+
* @param provider Solana provider (e.g., AnchorProvider)
|
|
22
|
+
*/
|
|
23
|
+
export async function encryptForArciumInternal(mxeProgramId, plaintextValues, provider) {
|
|
24
|
+
// Required by the Arcium client before encryption
|
|
25
|
+
Arcium.getArciumEnv();
|
|
26
|
+
|
|
27
|
+
// 1) Generate a random x25519 keypair
|
|
28
|
+
const privateKey = Arcium.x25519.utils.randomSecretKey();
|
|
29
|
+
const publicKey = Arcium.x25519.getPublicKey(privateKey);
|
|
30
|
+
|
|
31
|
+
// 2) Fetch the MXE's public encryption key using the provided provider
|
|
32
|
+
const mxePubKey = await Arcium.getMXEPublicKey(provider, mxeProgramId);
|
|
33
|
+
if (!mxePubKey) {
|
|
34
|
+
throw new Error('MXE public key not found for Arcium encryption');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 3) Derive DH shared secret
|
|
38
|
+
const sharedSecret = Arcium.x25519.getSharedSecret(privateKey, mxePubKey);
|
|
39
|
+
|
|
40
|
+
// 4) Build the cipher and encrypt the data
|
|
41
|
+
const cipher = new Arcium.RescueCipher(sharedSecret);
|
|
42
|
+
const nonce = crypto.getRandomValues(new Uint8Array(16));
|
|
43
|
+
const ciphertext = cipher.encrypt(plaintextValues, nonce);
|
|
44
|
+
return {
|
|
45
|
+
ciphertext,
|
|
46
|
+
publicKey,
|
|
47
|
+
nonce
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=arciumHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Arcium","encryptForArciumInternal","mxeProgramId","plaintextValues","provider","getArciumEnv","privateKey","x25519","utils","randomSecretKey","publicKey","getPublicKey","mxePubKey","getMXEPublicKey","Error","sharedSecret","getSharedSecret","cipher","RescueCipher","nonce","crypto","getRandomValues","Uint8Array","ciphertext","encrypt"],"sourceRoot":"../../../src","sources":["internal/arciumHelper.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,KAAKA,MAAM,MAAM,mBAAmB;;AAG3C;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeC,wBAAwBA,CAC5CC,YAAuB,EACvBC,eAAyB,EACzBC,QAAa,EACmB;EAChC;EACAJ,MAAM,CAACK,YAAY,CAAC,CAAC;;EAErB;EACA,MAAMC,UAAU,GAAGN,MAAM,CAACO,MAAM,CAACC,KAAK,CAACC,eAAe,CAAC,CAAC;EACxD,MAAMC,SAAS,GAAGV,MAAM,CAACO,MAAM,CAACI,YAAY,CAACL,UAAU,CAAC;;EAExD;EACA,MAAMM,SAAS,GAAG,MAAMZ,MAAM,CAACa,eAAe,CAACT,QAAQ,EAAEF,YAAY,CAAC;EAEtE,IAAI,CAACU,SAAS,EAAE;IACd,MAAM,IAAIE,KAAK,CAAC,gDAAgD,CAAC;EACnE;;EAEA;EACA,MAAMC,YAAY,GAAGf,MAAM,CAACO,MAAM,CAACS,eAAe,CAACV,UAAU,EAAEM,SAAS,CAAC;;EAEzE;EACA,MAAMK,MAAM,GAAG,IAAIjB,MAAM,CAACkB,YAAY,CAACH,YAAY,CAAC;EACpD,MAAMI,KAAK,GAAGC,MAAM,CAACC,eAAe,CAAC,IAAIC,UAAU,CAAC,EAAE,CAAC,CAAC;EACxD,MAAMC,UAAU,GAAGN,MAAM,CAACO,OAAO,CAACrB,eAAe,EAAEgB,KAAK,CAAC;EAEzD,OAAO;IACLI,UAAU;IACVb,SAAS;IACTS;EACF,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// src/nfc.ts
|
|
4
|
+
import NfcManager, { NfcTech, Ndef } from "react-native-nfc-manager";
|
|
5
|
+
// Start the manager
|
|
6
|
+
export function initNFC() {
|
|
7
|
+
return NfcManager.start();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Read NFC tag containing a TossUser
|
|
11
|
+
export async function readNFCUser() {
|
|
12
|
+
try {
|
|
13
|
+
await NfcManager.requestTechnology(NfcTech.Ndef);
|
|
14
|
+
const tag = await NfcManager.getTag();
|
|
15
|
+
await NfcManager.cancelTechnologyRequest();
|
|
16
|
+
if (!tag?.ndefMessage?.[0]?.payload) {
|
|
17
|
+
throw new Error('No NDEF message found');
|
|
18
|
+
}
|
|
19
|
+
const message = Ndef.uri.decodePayload(tag.ndefMessage[0].payload);
|
|
20
|
+
return JSON.parse(message);
|
|
21
|
+
} catch (ex) {
|
|
22
|
+
await NfcManager.cancelTechnologyRequest();
|
|
23
|
+
throw new Error(`Failed to read user from NFC: ${String(ex)}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function writeUserToNFC(user) {
|
|
27
|
+
try {
|
|
28
|
+
await NfcManager.requestTechnology(NfcTech.Ndef);
|
|
29
|
+
const jsonUser = JSON.stringify(user);
|
|
30
|
+
const bytes = Ndef.encodeMessage([Ndef.uriRecord(jsonUser)]);
|
|
31
|
+
await NfcManager.ndefHandler.writeNdefMessage(bytes);
|
|
32
|
+
await NfcManager.cancelTechnologyRequest();
|
|
33
|
+
return true;
|
|
34
|
+
} catch (ex) {
|
|
35
|
+
await NfcManager.cancelTechnologyRequest();
|
|
36
|
+
throw new Error(`Failed to write user to NFC: ${String(ex)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Write SolanaIntent to NFC tag
|
|
41
|
+
export async function writeIntentToNFC(intent) {
|
|
42
|
+
try {
|
|
43
|
+
await NfcManager.requestTechnology(NfcTech.Ndef);
|
|
44
|
+
const jsonIntent = JSON.stringify(intent);
|
|
45
|
+
const bytes = Ndef.encodeMessage([Ndef.uriRecord(jsonIntent)]);
|
|
46
|
+
await NfcManager.ndefHandler.writeNdefMessage(bytes);
|
|
47
|
+
await NfcManager.cancelTechnologyRequest();
|
|
48
|
+
return true;
|
|
49
|
+
} catch (ex) {
|
|
50
|
+
await NfcManager.cancelTechnologyRequest();
|
|
51
|
+
throw new Error(`Failed to write intent to NFC: ${String(ex)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=nfc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NfcManager","NfcTech","Ndef","initNFC","start","readNFCUser","requestTechnology","tag","getTag","cancelTechnologyRequest","ndefMessage","payload","Error","message","uri","decodePayload","JSON","parse","ex","String","writeUserToNFC","user","jsonUser","stringify","bytes","encodeMessage","uriRecord","ndefHandler","writeNdefMessage","writeIntentToNFC","intent","jsonIntent"],"sourceRoot":"../../src","sources":["nfc.ts"],"mappings":";;AAAA;AACA,OAAOA,UAAU,IAAIC,OAAO,EAAEC,IAAI,QAAQ,0BAA0B;AAIpE;AACA,OAAO,SAASC,OAAOA,CAAA,EAAG;EACxB,OAAOH,UAAU,CAACI,KAAK,CAAC,CAAC;AAC3B;;AAEA;AACA,OAAO,eAAeC,WAAWA,CAAA,EAAsB;EACrD,IAAI;IACF,MAAML,UAAU,CAACM,iBAAiB,CAACL,OAAO,CAACC,IAAI,CAAC;IAChD,MAAMK,GAAG,GAAG,MAAMP,UAAU,CAACQ,MAAM,CAAC,CAAC;IACrC,MAAMR,UAAU,CAACS,uBAAuB,CAAC,CAAC;IAE1C,IAAI,CAACF,GAAG,EAAEG,WAAW,GAAG,CAAC,CAAC,EAAEC,OAAO,EAAE;MACnC,MAAM,IAAIC,KAAK,CAAC,uBAAuB,CAAC;IAC1C;IAEA,MAAMC,OAAO,GAAGX,IAAI,CAACY,GAAG,CAACC,aAAa,CAACR,GAAG,CAACG,WAAW,CAAC,CAAC,CAAC,CAACC,OAAc,CAAC;IACzE,OAAOK,IAAI,CAACC,KAAK,CAACJ,OAAO,CAAC;EAC5B,CAAC,CAAC,OAAOK,EAAW,EAAE;IACpB,MAAMlB,UAAU,CAACS,uBAAuB,CAAC,CAAC;IAC1C,MAAM,IAAIG,KAAK,CAAC,iCAAiCO,MAAM,CAACD,EAAE,CAAC,EAAE,CAAC;EAChE;AACF;AAEA,OAAO,eAAeE,cAAcA,CAACC,IAAc,EAAoB;EACrE,IAAI;IACF,MAAMrB,UAAU,CAACM,iBAAiB,CAACL,OAAO,CAACC,IAAI,CAAC;IAChD,MAAMoB,QAAQ,GAAGN,IAAI,CAACO,SAAS,CAACF,IAAI,CAAC;IACrC,MAAMG,KAAK,GAAGtB,IAAI,CAACuB,aAAa,CAAC,CAACvB,IAAI,CAACwB,SAAS,CAACJ,QAAQ,CAAC,CAAC,CAAC;IAC5D,MAAMtB,UAAU,CAAC2B,WAAW,CAACC,gBAAgB,CAACJ,KAAK,CAAC;IACpD,MAAMxB,UAAU,CAACS,uBAAuB,CAAC,CAAC;IAC1C,OAAO,IAAI;EACb,CAAC,CAAC,OAAOS,EAAW,EAAE;IACpB,MAAMlB,UAAU,CAACS,uBAAuB,CAAC,CAAC;IAC1C,MAAM,IAAIG,KAAK,CAAC,gCAAgCO,MAAM,CAACD,EAAE,CAAC,EAAE,CAAC;EAC/D;AACF;;AAEA;AACA,OAAO,eAAeW,gBAAgBA,CAACC,MAAoB,EAAoB;EAC7E,IAAI;IACF,MAAM9B,UAAU,CAACM,iBAAiB,CAACL,OAAO,CAACC,IAAI,CAAC;IAChD,MAAM6B,UAAU,GAAGf,IAAI,CAACO,SAAS,CAACO,MAAM,CAAC;IACzC,MAAMN,KAAK,GAAGtB,IAAI,CAACuB,aAAa,CAAC,CAACvB,IAAI,CAACwB,SAAS,CAACK,UAAU,CAAC,CAAC,CAAC;IAC9D,MAAM/B,UAAU,CAAC2B,WAAW,CAACC,gBAAgB,CAACJ,KAAK,CAAC;IACpD,MAAMxB,UAAU,CAACS,uBAAuB,CAAC,CAAC;IAC1C,OAAO,IAAI;EACb,CAAC,CAAC,OAAOS,EAAW,EAAE;IACpB,MAAMlB,UAAU,CAACS,uBAAuB,CAAC,CAAC;IAC1C,MAAM,IAAIG,KAAK,CAAC,kCAAkCO,MAAM,CAACD,EAAE,CAAC,EAAE,CAAC;EACjE;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { noise } from "@chainsafe/libp2p-noise";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Initialize Noise secure session with a static key.
|
|
7
|
+
*/
|
|
8
|
+
export function initNoiseSession(staticKey) {
|
|
9
|
+
const ns = noise({
|
|
10
|
+
staticNoiseKey: staticKey
|
|
11
|
+
});
|
|
12
|
+
return ns;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=noise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["noise","initNoiseSession","staticKey","ns","staticNoiseKey"],"sourceRoot":"../../src","sources":["noise.ts"],"mappings":";;AAAA,SAASA,KAAK,QAAQ,yBAAyB;;AAE/C;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAACC,SAAqB,EAAE;EACtD,MAAMC,EAAE,GAAGH,KAAK,CAAC;IAAEI,cAAc,EAAEF;EAAU,CAAC,CAAC;EAC/C,OAAOC,EAAE;AACX","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
package/lib/module/qr.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { View, StyleSheet, Text } from 'react-native';
|
|
4
|
+
import { Camera, useCameraDevice, useCameraPermission, useCodeScanner } from 'react-native-vision-camera';
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
export function QRScanner({
|
|
7
|
+
onScan
|
|
8
|
+
}) {
|
|
9
|
+
const device = useCameraDevice('back');
|
|
10
|
+
const permission = useCameraPermission();
|
|
11
|
+
const codeScanner = useCodeScanner({
|
|
12
|
+
codeTypes: ['qr'],
|
|
13
|
+
// ✅ correct CodeType
|
|
14
|
+
onCodeScanned: codes => {
|
|
15
|
+
const code = codes[0];
|
|
16
|
+
if (!code?.value) return; // ✅ undefined-safe
|
|
17
|
+
|
|
18
|
+
onScan(code.value);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
if (!permission.hasPermission) {
|
|
22
|
+
return /*#__PURE__*/_jsx(View, {
|
|
23
|
+
style: styles.center,
|
|
24
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
25
|
+
children: "Camera permission not granted"
|
|
26
|
+
})
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (!device) {
|
|
30
|
+
return /*#__PURE__*/_jsx(View, {
|
|
31
|
+
style: styles.center,
|
|
32
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
33
|
+
children: "Camera not available"
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return /*#__PURE__*/_jsx(View, {
|
|
38
|
+
style: styles.container,
|
|
39
|
+
children: /*#__PURE__*/_jsx(Camera, {
|
|
40
|
+
style: StyleSheet.absoluteFill,
|
|
41
|
+
device: device,
|
|
42
|
+
isActive: true,
|
|
43
|
+
codeScanner: codeScanner
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const styles = StyleSheet.create({
|
|
48
|
+
container: {
|
|
49
|
+
flex: 1
|
|
50
|
+
},
|
|
51
|
+
center: {
|
|
52
|
+
flex: 1,
|
|
53
|
+
alignItems: 'center',
|
|
54
|
+
justifyContent: 'center'
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=qr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["View","StyleSheet","Text","Camera","useCameraDevice","useCameraPermission","useCodeScanner","jsx","_jsx","QRScanner","onScan","device","permission","codeScanner","codeTypes","onCodeScanned","codes","code","value","hasPermission","style","styles","center","children","container","absoluteFill","isActive","create","flex","alignItems","justifyContent"],"sourceRoot":"../../src","sources":["qr.tsx"],"mappings":";;AAAA,SAASA,IAAI,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AACrD,SACEC,MAAM,EACNC,eAAe,EACfC,mBAAmB,EACnBC,cAAc,QAET,4BAA4B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAMpC,OAAO,SAASC,SAASA,CAAC;EAAEC;AAAuB,CAAC,EAAE;EACpD,MAAMC,MAAM,GAAGP,eAAe,CAAC,MAAM,CAAC;EACtC,MAAMQ,UAAU,GAAGP,mBAAmB,CAAC,CAAC;EAExC,MAAMQ,WAAW,GAAGP,cAAc,CAAC;IACjCQ,SAAS,EAAE,CAAC,IAAI,CAAC;IAAE;IACnBC,aAAa,EAAGC,KAAa,IAAK;MAChC,MAAMC,IAAI,GAAGD,KAAK,CAAC,CAAC,CAAC;MACrB,IAAI,CAACC,IAAI,EAAEC,KAAK,EAAE,OAAO,CAAC;;MAE1BR,MAAM,CAACO,IAAI,CAACC,KAAK,CAAC;IACpB;EACF,CAAC,CAAC;EAEF,IAAI,CAACN,UAAU,CAACO,aAAa,EAAE;IAC7B,oBACEX,IAAA,CAACR,IAAI;MAACoB,KAAK,EAAEC,MAAM,CAACC,MAAO;MAAAC,QAAA,eACzBf,IAAA,CAACN,IAAI;QAAAqB,QAAA,EAAC;MAA6B,CAAM;IAAC,CACtC,CAAC;EAEX;EAEA,IAAI,CAACZ,MAAM,EAAE;IACX,oBACEH,IAAA,CAACR,IAAI;MAACoB,KAAK,EAAEC,MAAM,CAACC,MAAO;MAAAC,QAAA,eACzBf,IAAA,CAACN,IAAI;QAAAqB,QAAA,EAAC;MAAoB,CAAM;IAAC,CAC7B,CAAC;EAEX;EAEA,oBACEf,IAAA,CAACR,IAAI;IAACoB,KAAK,EAAEC,MAAM,CAACG,SAAU;IAAAD,QAAA,eAC5Bf,IAAA,CAACL,MAAM;MACLiB,KAAK,EAAEnB,UAAU,CAACwB,YAAa;MAC/Bd,MAAM,EAAEA,MAAO;MACfe,QAAQ;MACRb,WAAW,EAAEA;IAAY,CAC1B;EAAC,CACE,CAAC;AAEX;AAEA,MAAMQ,MAAM,GAAGpB,UAAU,CAAC0B,MAAM,CAAC;EAC/BH,SAAS,EAAE;IACTI,IAAI,EAAE;EACR,CAAC;EACDN,MAAM,EAAE;IACNM,IAAI,EAAE,CAAC;IACPC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE;EAClB;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Reconciliation and Settlement Module for TOSS
|
|
5
|
+
*
|
|
6
|
+
* Implements Section 9-10 of the TOSS Technical Paper:
|
|
7
|
+
* - Synchronisation and reconciliation with onchain state
|
|
8
|
+
* - Deterministic failure handling
|
|
9
|
+
* - Conflict resolution
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { PublicKey, Transaction, SystemProgram } from '@solana/web3.js';
|
|
13
|
+
import { isIntentExpired } from "./intent.js";
|
|
14
|
+
import { secureStoreIntent, getAllSecureIntents } from "./storage/secureStorage.js";
|
|
15
|
+
import { TossError, NetworkError } from "./errors.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Result of intent settlement attempt
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* State of a device's reconciliation with onchain
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Validates an intent can be settled with current onchain state
|
|
27
|
+
*/
|
|
28
|
+
export async function validateIntentOnchain(intent, connection) {
|
|
29
|
+
try {
|
|
30
|
+
// Check if intent has expired
|
|
31
|
+
if (isIntentExpired(intent)) {
|
|
32
|
+
return {
|
|
33
|
+
valid: false,
|
|
34
|
+
error: 'Intent has expired'
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Fetch sender account info
|
|
39
|
+
const senderPublicKey = new PublicKey(intent.from);
|
|
40
|
+
const senderAccountInfo = await connection.getAccountInfo(senderPublicKey);
|
|
41
|
+
if (!senderAccountInfo) {
|
|
42
|
+
return {
|
|
43
|
+
valid: false,
|
|
44
|
+
error: 'Sender account does not exist'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Validate sender has sufficient balance
|
|
49
|
+
if (senderAccountInfo.lamports < intent.amount) {
|
|
50
|
+
return {
|
|
51
|
+
valid: false,
|
|
52
|
+
error: `Insufficient balance: have ${senderAccountInfo.lamports}, need ${intent.amount}`
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Validate recipient exists (if not a system account)
|
|
57
|
+
const recipientPublicKey = new PublicKey(intent.to);
|
|
58
|
+
const recipientAccountInfo = await connection.getAccountInfo(recipientPublicKey);
|
|
59
|
+
if (!recipientAccountInfo && intent.amount > 0) {
|
|
60
|
+
// Recipient account doesn't exist - this is okay, will be created by transfer
|
|
61
|
+
// But we should verify it's a valid public key format (already done above)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Fetch recent transactions to check for double-spend
|
|
65
|
+
const signatures = await connection.getSignaturesForAddress(senderPublicKey, {
|
|
66
|
+
limit: 100
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Check if this nonce has been used recently
|
|
70
|
+
for (const sig of signatures) {
|
|
71
|
+
const tx = await connection.getParsedTransaction(sig.signature);
|
|
72
|
+
if (tx?.transaction.message) {
|
|
73
|
+
// Check if nonce matches and transaction was successful
|
|
74
|
+
const instructions = tx.transaction.message.instructions;
|
|
75
|
+
for (const instruction of instructions) {
|
|
76
|
+
// Look for SystemProgram transfers with same nonce
|
|
77
|
+
if ('parsed' in instruction && instruction.parsed?.type === 'transfer') {
|
|
78
|
+
const parsedIx = instruction.parsed;
|
|
79
|
+
if (parsedIx.info?.source === intent.from && parsedIx.info?.destination === intent.to) {
|
|
80
|
+
// Check if this is a duplicate
|
|
81
|
+
if (tx.slot && tx.blockTime) {
|
|
82
|
+
const timeDiff = Math.floor(Date.now() / 1000) - tx.blockTime;
|
|
83
|
+
// If transaction was confirmed within the nonce window, it's a potential conflict
|
|
84
|
+
if (timeDiff < 5 * 60) {
|
|
85
|
+
return {
|
|
86
|
+
valid: false,
|
|
87
|
+
error: `Potential double-spend detected: similar transaction already confirmed`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
valid: true
|
|
98
|
+
};
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return {
|
|
101
|
+
valid: false,
|
|
102
|
+
error: `Onchain validation failed: ${error instanceof Error ? error.message : String(error)}`
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Builds a Solana transaction from an intent
|
|
109
|
+
*/
|
|
110
|
+
export async function buildTransactionFromIntent(intent, connection, feePayer) {
|
|
111
|
+
try {
|
|
112
|
+
const senderPublicKey = new PublicKey(intent.from);
|
|
113
|
+
const recipientPublicKey = new PublicKey(intent.to);
|
|
114
|
+
const feePayerPubkey = feePayer || senderPublicKey;
|
|
115
|
+
|
|
116
|
+
// Get latest blockhash
|
|
117
|
+
const {
|
|
118
|
+
blockhash,
|
|
119
|
+
lastValidBlockHeight
|
|
120
|
+
} = await connection.getLatestBlockhash('confirmed');
|
|
121
|
+
|
|
122
|
+
// Create transfer instruction
|
|
123
|
+
const transferInstruction = SystemProgram.transfer({
|
|
124
|
+
fromPubkey: senderPublicKey,
|
|
125
|
+
toPubkey: recipientPublicKey,
|
|
126
|
+
lamports: intent.amount
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Create transaction
|
|
130
|
+
const transaction = new Transaction();
|
|
131
|
+
transaction.add(transferInstruction);
|
|
132
|
+
|
|
133
|
+
// If using nonce account, add nonce advance instruction
|
|
134
|
+
if (intent.nonceAccount && intent.nonceAuth) {
|
|
135
|
+
const nonceAccountPubkey = new PublicKey(intent.nonceAccount);
|
|
136
|
+
const nonceAuthPubkey = new PublicKey(intent.nonceAuth);
|
|
137
|
+
const nonceAdvanceInstruction = SystemProgram.nonceAdvance({
|
|
138
|
+
noncePubkey: nonceAccountPubkey,
|
|
139
|
+
authorizedPubkey: nonceAuthPubkey
|
|
140
|
+
});
|
|
141
|
+
transaction.add(nonceAdvanceInstruction);
|
|
142
|
+
}
|
|
143
|
+
transaction.feePayer = feePayerPubkey;
|
|
144
|
+
transaction.recentBlockhash = blockhash;
|
|
145
|
+
transaction.lastValidBlockHeight = lastValidBlockHeight;
|
|
146
|
+
return transaction;
|
|
147
|
+
} catch (error) {
|
|
148
|
+
throw new TossError(`Failed to build transaction from intent: ${error instanceof Error ? error.message : String(error)}`, 'TRANSACTION_BUILD_FAILED');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Submits a transaction to the network with confirmation
|
|
154
|
+
*/
|
|
155
|
+
export async function submitTransactionToChain(transaction, connection, maxRetries = 3) {
|
|
156
|
+
let lastError = null;
|
|
157
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
158
|
+
try {
|
|
159
|
+
// Serialize and send transaction
|
|
160
|
+
const rawTransaction = transaction.serialize();
|
|
161
|
+
const signature = await connection.sendRawTransaction(rawTransaction, {
|
|
162
|
+
skipPreflight: false,
|
|
163
|
+
preflightCommitment: 'confirmed'
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Wait for confirmation
|
|
167
|
+
const confirmation = await connection.confirmTransaction(signature, 'confirmed');
|
|
168
|
+
if (confirmation.value.err) {
|
|
169
|
+
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
|
|
170
|
+
}
|
|
171
|
+
return signature;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
lastError = error;
|
|
174
|
+
|
|
175
|
+
// Don't retry if it's a signature error (transaction already processed)
|
|
176
|
+
if (lastError.message?.includes('Signature verification failed')) {
|
|
177
|
+
throw lastError;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Exponential backoff
|
|
181
|
+
if (attempt < maxRetries) {
|
|
182
|
+
const delay = 1000 * Math.pow(2, attempt - 1);
|
|
183
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
throw new NetworkError(`Failed to submit transaction after ${maxRetries} attempts: ${lastError?.message}`, {
|
|
188
|
+
context: 'submitTransactionToChain',
|
|
189
|
+
cause: lastError
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Attempts to settle a single intent and returns the result
|
|
195
|
+
*/
|
|
196
|
+
export async function settleIntent(intent, connection, feePayer) {
|
|
197
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
198
|
+
try {
|
|
199
|
+
// Validate intent against onchain state
|
|
200
|
+
const validation = await validateIntentOnchain(intent, connection);
|
|
201
|
+
if (!validation.valid) {
|
|
202
|
+
return {
|
|
203
|
+
intentId: intent.id,
|
|
204
|
+
status: 'rejected',
|
|
205
|
+
error: validation.error,
|
|
206
|
+
timestamp
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Build transaction from intent
|
|
211
|
+
const transaction = await buildTransactionFromIntent(intent, connection, feePayer);
|
|
212
|
+
|
|
213
|
+
// Submit transaction to chain
|
|
214
|
+
const signature = await submitTransactionToChain(transaction, connection);
|
|
215
|
+
return {
|
|
216
|
+
intentId: intent.id,
|
|
217
|
+
status: 'success',
|
|
218
|
+
signature,
|
|
219
|
+
timestamp
|
|
220
|
+
};
|
|
221
|
+
} catch (error) {
|
|
222
|
+
return {
|
|
223
|
+
intentId: intent.id,
|
|
224
|
+
status: 'failed',
|
|
225
|
+
error: error instanceof Error ? error.message : String(error),
|
|
226
|
+
timestamp
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Core reconciliation: process all pending intents for settlement
|
|
233
|
+
*/
|
|
234
|
+
export async function reconcilePendingIntents(connection, feePayer) {
|
|
235
|
+
try {
|
|
236
|
+
// Fetch all pending intents from storage
|
|
237
|
+
const allIntents = await getAllSecureIntents();
|
|
238
|
+
const pendingIntents = allIntents.filter(i => i.status === 'pending');
|
|
239
|
+
if (pendingIntents.length === 0) {
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Sort by creation time to maintain ordering
|
|
244
|
+
pendingIntents.sort((a, b) => a.createdAt - b.createdAt);
|
|
245
|
+
|
|
246
|
+
// Settle each intent and collect results
|
|
247
|
+
const settlementResults = [];
|
|
248
|
+
for (const intent of pendingIntents) {
|
|
249
|
+
const result = await settleIntent(intent, connection, feePayer);
|
|
250
|
+
settlementResults.push(result);
|
|
251
|
+
|
|
252
|
+
// Update intent status based on settlement result
|
|
253
|
+
let newStatus;
|
|
254
|
+
let error;
|
|
255
|
+
switch (result.status) {
|
|
256
|
+
case 'success':
|
|
257
|
+
newStatus = 'settled';
|
|
258
|
+
break;
|
|
259
|
+
case 'rejected':
|
|
260
|
+
newStatus = 'failed';
|
|
261
|
+
error = result.error;
|
|
262
|
+
break;
|
|
263
|
+
case 'failed':
|
|
264
|
+
newStatus = 'failed';
|
|
265
|
+
error = result.error;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Update the intent in storage
|
|
270
|
+
const updatedIntent = {
|
|
271
|
+
...intent,
|
|
272
|
+
status: newStatus,
|
|
273
|
+
updatedAt: Math.floor(Date.now() / 1000),
|
|
274
|
+
error,
|
|
275
|
+
signatures: result.signature ? [result.signature] : undefined
|
|
276
|
+
};
|
|
277
|
+
await secureStoreIntent(updatedIntent);
|
|
278
|
+
}
|
|
279
|
+
return settlementResults;
|
|
280
|
+
} catch (error) {
|
|
281
|
+
throw new NetworkError(`Reconciliation failed: ${error instanceof Error ? error.message : String(error)}`, {
|
|
282
|
+
cause: error
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Detects conflicts between local intents and onchain state
|
|
289
|
+
*/
|
|
290
|
+
export async function detectConflicts(connection) {
|
|
291
|
+
const conflicts = [];
|
|
292
|
+
try {
|
|
293
|
+
const allIntents = await getAllSecureIntents();
|
|
294
|
+
for (const intent of allIntents) {
|
|
295
|
+
// Skip already settled or failed intents
|
|
296
|
+
if (intent.status !== 'pending') continue;
|
|
297
|
+
|
|
298
|
+
// Check for conflicts
|
|
299
|
+
const validation = await validateIntentOnchain(intent, connection);
|
|
300
|
+
if (!validation.valid) {
|
|
301
|
+
conflicts.push({
|
|
302
|
+
intentId: intent.id,
|
|
303
|
+
conflict: validation.error || 'Unknown conflict'
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return conflicts;
|
|
308
|
+
} catch (error) {
|
|
309
|
+
throw new NetworkError('Conflict detection failed', {
|
|
310
|
+
cause: error
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Gets reconciliation state summary
|
|
317
|
+
*/
|
|
318
|
+
export async function getReconciliationState(connection) {
|
|
319
|
+
const allIntents = await getAllSecureIntents();
|
|
320
|
+
const slot = await connection.getSlot('confirmed');
|
|
321
|
+
return {
|
|
322
|
+
lastSyncTime: Math.floor(Date.now() / 1000),
|
|
323
|
+
lastSyncSlot: slot,
|
|
324
|
+
processedIntents: allIntents.filter(i => i.status === 'settled').map(i => i.id),
|
|
325
|
+
failedIntents: allIntents.filter(i => i.status === 'failed').map(i => i.id),
|
|
326
|
+
conflictingIntents: allIntents.filter(i => isIntentExpired(i) && i.status === 'pending').map(i => i.id)
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=reconciliation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["PublicKey","Transaction","SystemProgram","isIntentExpired","secureStoreIntent","getAllSecureIntents","TossError","NetworkError","validateIntentOnchain","intent","connection","valid","error","senderPublicKey","from","senderAccountInfo","getAccountInfo","lamports","amount","recipientPublicKey","to","recipientAccountInfo","signatures","getSignaturesForAddress","limit","sig","tx","getParsedTransaction","signature","transaction","message","instructions","instruction","parsed","type","parsedIx","info","source","destination","slot","blockTime","timeDiff","Math","floor","Date","now","Error","String","buildTransactionFromIntent","feePayer","feePayerPubkey","blockhash","lastValidBlockHeight","getLatestBlockhash","transferInstruction","transfer","fromPubkey","toPubkey","add","nonceAccount","nonceAuth","nonceAccountPubkey","nonceAuthPubkey","nonceAdvanceInstruction","nonceAdvance","noncePubkey","authorizedPubkey","recentBlockhash","submitTransactionToChain","maxRetries","lastError","attempt","rawTransaction","serialize","sendRawTransaction","skipPreflight","preflightCommitment","confirmation","confirmTransaction","value","err","JSON","stringify","includes","delay","pow","Promise","resolve","setTimeout","context","cause","settleIntent","timestamp","validation","intentId","id","status","reconcilePendingIntents","allIntents","pendingIntents","filter","i","length","sort","a","b","createdAt","settlementResults","result","push","newStatus","updatedIntent","updatedAt","undefined","detectConflicts","conflicts","conflict","getReconciliationState","getSlot","lastSyncTime","lastSyncSlot","processedIntents","map","failedIntents","conflictingIntents"],"sourceRoot":"../../src","sources":["reconciliation.ts"],"mappings":"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","ignoreList":[]}
|